Home » Php » Defining and initialize a class property in PHP Laravel controller

Defining and initialize a class property in PHP Laravel controller

Posted by: admin February 25, 2020 Leave a comment

Questions:

I try defined property for some controller and i get error :

Symfony \ Component \ Debug \ Exception \ FatalErrorException (E_UNKNOWN)

Constant expression contains invalid operations

This my controller code :

namespace App\Http\Controllers…;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Customer;
use App\City;
use Illuminate\Database\Eloquent\Builder;
use Carbon\Carbon;

use Illuminate\Support\Facades\Auth;

class CatalogController extends Controller
{
    protected $user = Auth::user();

    function user() {
       $user = optional(Auth::user())->load(['city']);
       return $user;
    }
}

In php.net I read this:

Class member variables may be initialized, but this initialization must be a constant value–that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.

I assume that this rule is not executed in my code. Am I right?

How to&Answers:

Retrieving the user in a controller method is fine because it is only executed once for the request. There is no need to advantage to storing it as instance property because a new instance of the controllers is made for every request.

You could use the following code:

public function index()
{
    $user = Auth::user()->with('city')->get();
    $articles = $this->getArticlesForUser($user);

    return view('home', [
        'user' => $user
    ]);
}

public function getArticlesForUser(User $user){
  // Do something with $user
  return [];
}

public function delete()
{
    $user = Auth::user();
    $user->delete();

    return view('home');
}

If the goal is to have calculate the values once and use them at various places a singleton can be used:

<?php

class Settings {
    private $accessToken = '';
    private $items = [];

    private static $instance = null;

    protected function __construct(){}

    public static function getInstance(){
        if(static::$instance == null){
            static::$instance = static::buildInstance();
        }

        return static::$instance;
    }

    private static function buildInstance(){
        $instance = new Settings();
        $instance->accessToken = md5(rand(1,1000));
        $instance->items = [1,2,3];

        return $instance;
    }

    public function getToken(){
        return $this->accessToken;
    }
}

$settings = Settings::getInstance();
// Both return the same token because the instance is the same
var_dump($settings->getToken());
var_dump(Settings::getInstance()->getToken());

Answer:

You should assign your properties in constructor like this

protected $user;

public function __construct()
    {
        $this->user = Auth::user();
    }

or through setters

Edit

However in your case it’s not a good idea please see https://laravel.com/docs/5.3/upgrade#5.3-session-in-constructors