CodeNinja
CodeNinja

Reputation: 847

$model->save() does not save object params Laravel 5.5

Just as background information, i'm relatively new with PHP and Laravel. I started making a simple application to get some feelings with PHP and Laravel. In the application i want to create a object with some params and save this object in the database.

For this i created a migration:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePlayersTable extends Migration
{
    public function up()
    {
        Schema::create('players', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
            $table->integer("var1")->default(0);
            $table->integer("var2")->default(0);
    }
    public function down()
    {
           Schema::dropIfExists('players');
    }
 }

I created a model (Player):

namespace App;

use Illuminate\Database\Eloquent\Model;
use DB;
use Log;

class Player extends Model
{
    private $var1;
    private $var2;

    public function __construct($number)
    {
        $this->var1 = $number;
        $this->var2 = $number;
    }
}

And a controller off course (PlayerController):

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Player;

class PlayerController extends Controller
{
    public function index()
    {
        $player = new Player(20);
//      dd($player);
        $player->save();
    }

If i uncomment the dd($player) i get a json object in my browser what shows the player with var1 = 20 and var2 = 20 what is correct. If i check the player in the database, var1 and 2 are 0.

If i add $player->var1 = 10; above the $player->save(); the value in the database is 10.

Why is the value of the vars, defined by generating the Player object not stored and it is if i change the var values after the object exists?

Upvotes: 1

Views: 652

Answers (1)

Clément Baconnier
Clément Baconnier

Reputation: 6108

On this part, you declare your own variable called $var1 and $var2. I guess when you dump your object you, indeed, see your values.

class Player extends Model
{
    private $var1;
    private $var2;

    public function __construct($number)
    {
        $this->var1 = $number;
        $this->var2 = $number;
    }
}

In Laravel, the values are stored in an array called $attributes.
When you call $player->var1 = 10; from the controller, the variable $var1 is private and you wont have access to it.
Instead, php will call the __set() magic method and store your value in the array $attributes. That's why it's working from the controller.

public function __set($key, $value)
{
    $this->setAttribute($key, $value);
}

To make it work, you can simply remove $var1 and $var2 declaration to force the class to use the magic method __set():

class Player extends Model
{
    public function __construct($number)
    {
        $this->var1 = $number;
        $this->var2 = $number;
    }
}

More about __set() in laravel source code
More about setAttribute() in laravel source code

Documentation about __set() in PHP

Upvotes: 1

Related Questions