【问题标题】:Defining and initialize a class property in PHP Laravel controller在 PHP Laravel 控制器中定义和初始化一个类属性
【发布时间】:2020-05-31 13:30:55
【问题描述】:

我尝试为某些控制器定义属性,但出现错误:

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

常量表达式包含无效操作

这是我的控制器代码:

命名空间 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;
    }
}

在 php.net 我读到这个:

类成员变量可以被初始化,但这个初始化必须是一个常量值——也就是说,它必须能够在编译时被计算,并且不能依赖运行时信息才能被计算。

我假设这个规则没有在我的代码中执行。我对吗?

【问题讨论】:

    标签: php laravel oop laravel-5.8


    【解决方案1】:

    你应该像这样在构造函数中分配你的属性

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

    或通过setters...

    编辑

    但是,在您的情况下,这不是一个好主意,请参阅https://laravel.com/docs/5.3/upgrade#5.3-session-in-constructors

    【讨论】:

    • 感谢您的回答。这不适合我的情况。我试了一下,它返回null。也许是因为我没有创建新实例。当我使用该方法并在需要的地方调用它时。
    【解决方案2】:

    在控制器方法中检索用户很好,因为它只为请求执行一次。没有必要将其存储为实例属性,因为每次请求都会创建一个新的控制器实例。

    您可以使用以下代码:

    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');
    }
    

    如果目标是计算一次值并在不同的地方使用它们,则可以使用单例:

    <?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());
    

    【讨论】:

    • 谢谢。在这个控制器中还有一些方法,需要一个用户。因此我想封装初始化。
    • 那么你可以传递用户对象吗?检索用户进行 http 调用很好。查看更新的示例。 @Pingo
    • 我需要来自 http 的用户模型,并且我需要在这个控制器中对其进行多次操作。我知道如何从 http 检索用户。我的问题是,如何使这个模型成为类属性。最好是“pretected static $user”。代码中不再多次描述初始化。或者我需要找出我不能这样做。以及为什么。
    • 我不确定你想要达到什么目的?为什么绕过用户不是一种选择?您的控制器不应有 20 多个对用户的引用,应将其移至服务层。 @Pingo
    • 这个问题比较笼统。我想了解当数据不是静态的,而是在启动时计算时,我如何启动变量。
    猜你喜欢
    • 1970-01-01
    • 2020-01-24
    • 2018-12-02
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2016-06-17
    相关资源
    最近更新 更多