【问题标题】:How to access protect variable within class Laravel如何访问 Laravel 类中的保护变量
【发布时间】:2016-10-23 07:53:34
【问题描述】:

我不明白如何在同一个类中访问表名。

class Timesheets extends Model
{
    protected $table = "timesheets";

    public static function getAllTimesheets() {
        //return DB::table("timesheets")->get();
        return DB::table("timesheets")
            ->join('users', 'name', '=', 'users.name')
            ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
            ->get();
    }
}

如何将“时间表”替换为受保护的 Table 变量?

【问题讨论】:

    标签: php class laravel protected


    【解决方案1】:

    Manual for PhP visibility。受保护的变量可以在类本身和继承的类中访问,因此您正在尝试的是可能的。它由关键字$this 调用。但是,您的函数被声明为static,这会导致$this-> 出现问题。试试:

     return DB::table((new static)->getTable())->...
    

    或者只是通过删除 static 关键字使函数成为非静态函数。

    【讨论】:

    • 由于某种原因 $this 不起作用,我尝试了 $this->table 但它说 $this 未定义。
    • 那么也许@Max 是正确的,我不认为它扩展另一个类会对它产生影响,但也许它确实......
    • @TMartin 更新您的答案,而不是 $this->table (new static())
    【解决方案2】:

    您已将getAllTimesheets 定义为静态函数。

    但是,静态函数与类相关联,而不是与类的实例相关联。因此,getAllTimesheets 不提供 $this。

    要访问 $table 变量,请将 getAllTimesheets 定义为实例方法

    public function getAllTimesheets() { // Code // }
    

    有了这个,您可以访问函数中的 $this 变量,并且可以访问 $table variable$this->table

    【讨论】:

      【解决方案3】:

      你不能像那样访问 $table 。虽然你可以做类似的事情

      return DB::table((new static)->getTable())->...
      

      另一种解决方案是将getAllTimesheets 设为作用域

      public function scopeGetAllTimesheets() {
          // return DB::table($this->table)
          return DB::table($this->getTable())
              ->join('users', 'name', '=', 'users.name')
              ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
              ->get();
      }
      

      你可以这样称呼它

      $timeSheets = Timesheets::getAllTimesheets();
      

      我认为使用 getTable 更好,因为它为您提供了 $table 或 Laravel 使用模型构造表名的方式。

      【讨论】:

        【解决方案4】:

        直接回复(new static)->getTable()

        class Timesheets extends Model
        {
            protected $table = "timesheets";
        
            public static function getAllTimesheets() {
                return DB::table((new static)->getTable())
                    ->join('users', 'name', '=', 'users.name')
                    ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
                    ->get();
            }
        }
        

        了解详情的机会

        Eloquent 模型使用Magic Functions,它允许您通过静态函数调用检索新类实例的非静态方法; Illuminate/Database/Eloquent/Model::__callStatic().

        __callStatic() 在静态上下文中调用不可访问的方法时触发。

        查看code for Illuminate/Database/Eloquent/Model::__callStatic(),我们看到$instance = new static; 调用Late Static Bindings。这意味着您将获得的值将与新的类实例化相同。与@PeterPan666 commented 一样,这仅在当前类中根本不存在所请求的方法时才有效。查看code for Illuminate/Database/Eloquent/Model::__call(),我们看到此调用将发送到模型表的新查询Builder

        作为Álvaro Guimarães answered,您可以使用static::join() 启动对模型表的查询。

        class Timesheets extends Model
        {
            protected $table = "timesheets";
        
            public static function getAllTimesheets() {
                return static::join('users', 'name', '=', 'users.name')
                    ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
                    ->get();
            }
        }
        

        【讨论】:

        • 由于getTable确实存在于Model类中,PHP不会通过__callStatic。正如您所写的,“在静态上下文中调用不可访问的方法时会触发 __callStatic()。”但是 getTable 是可访问的,所以你会得到一个异常,说你不能像那样调用非静态方法。
        • @PeterPan666 你是对的。我误解了the code。我现在正在测试解决方案,并将相应地更新或删除我的答案。查看更多代码,我可以看到他们使用__callStatic() 实质上将呼叫转发到新的QueryBuilder。感谢您提出这个问题。
        • 我很高兴,但除了我指出的两个之外,我真的看不到其他解决方案......
        • @PeterPan666 我认为answer by Álvaro Guimarães 是一种有效的方法。根据 __call()__callStatic() 的编写方式,这似乎是 Laravel 的计划。
        • 是的,但首先的问题是“如何访问protected $table”。但是,是的,他的回答非常好。
        【解决方案5】:

        使用常规的静态语法:

        <?php
        
        class Timesheets extends Model
        {
            protected $table = "timesheets";
        
            public static function getAllTimesheets() {
                return static::join('users', 'name', '=', 'users.name')
                    ->select('timesheets.id', 'name', 'timesheets.time_start', 'timesheets.time_end', 'timesheets.time_desc')
                    ->get();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2023-01-13
          • 2014-05-14
          • 2017-01-12
          • 1970-01-01
          • 2019-11-21
          • 2016-02-19
          • 2013-07-23
          • 2011-03-29
          • 1970-01-01
          相关资源
          最近更新 更多