【问题标题】:Non-Static Method should not be called Statically不应静态调用非静态方法
【发布时间】:2014-09-08 18:51:23
【问题描述】:

我正在使用存储库模式并尝试建立模型之间的关系。当我尝试运行试图使用 user() 方法(与 Party 模型建立关系)的 store() 方法(在控制器中)时,我收到以下错误消息:

不应静态调用非静态方法 Party::user(),假设 $this 来自不兼容的上下文

我不明白为什么当我尝试运行 user() 关系方法时出现此错误,但所有其他方法(包括 $this->party->all()、$this->party- >create($data)),工作得很好。

以下是相关代码:

// PartiesController.php
public function __construct(Party $party){
  $this->party = $party
}

public function store(){
  $data = Input::all();
  $user = Sentry::getUser(); 
  $this->party->user()->create($data);
}

// Party.php
class Party extends Eloquent{
  public function user(){
    return $this->belongsTo('User');
  }
}

// User.php
use Cartalyst\Sentry\Users\Eloquent\User as SentryUserModel;

class User extends SentryUserModel implements UserInterface, RemindableInterface {
  public function party(){
    return $this->hasMany('Party');
  }
}

// PartyRepository.php
namespace repositories\Party;

interface PartyRepository{
  public function all();

  public function findByID($id);

  public function create($input);

  public function user();
}

// EloquentPartyRepository.php
namespace repositories\Party;
use Party;

class EloquentPartyRepository implements PartyRepository{
  public function all(){
    return Party::all();
  }

  public function create($input){
    return Party::create($input);
  }

  public function user(){
    return Party::user();
  }
}

【问题讨论】:

    标签: php laravel-4 repository-pattern static-methods non-static


    【解决方案1】:

    我已经解决了这个问题。感谢@watcher 和@deczo 的反馈。两者都非常有帮助并且与此错误消息相关。

    最后,我只需要更改一行。我在store() 函数中的方法调用序列乱序。这是相关代码。

    // PartiesController.php
    public function store(){
      $data = Input::all();
      $user = Sentry::getUser(); 
      $user->party()->create($data);
    }
    

    就我而言,要消除非静态错误并将User 模型正确插入Party 模型,我只需要进行上述更改。

    我参考了http://laravel.com/docs/eloquent/#inserting-related-models 以获得适当的顺序。

    【讨论】:

      【解决方案2】:

      问题是因为您在静态上下文中调用非静态方法。你可能习惯于看到 Laravel 做很多这样的方式(例如User::find() 等)。但实际上,这些不是静态调用(一个类实例实际上是在幕后解析的,并且在该实例上调用了find() 方法)。

      在您的情况下,它只是一个普通的静态方法调用。 PHP 将允许这样做,除了在您引用$this 的方法中,PHP 不知道如何处理它。根据定义,静态方法调用不知道类的任何实例。

      我的建议是将 Model 类的实例注入到存储库的构造函数中,如下所示:

      //Class: EloquentPartyRepository
      public function __construct(Party $party) 
      {
          $this->party = $party;
      }
      
      public function user($partyId) 
      {
          return $this->party->find($partyId)->user();
      }
      

      你发送给构造函数的Party实例不应该是来自数据库的记录,只是Party的一个空实例(即new Party()),尽管我相信如果你只是将它添加到构造函数中, IoC 应该能够利用依赖注入并为您提供实例。

      这里有一个等效的实现,它添加了一个byId 方法:

      //Class: EloquentPartyRepository
      public function __construct(Party $party) 
      {
          $this->party = $party;
      }
      
      public function byId($partyId)
      {
          return $this->party->find($partyId);
      }
      
      public function user($partyId) 
      {
          if($party = $this->byId($partyId)) {
              return $party->user();
          }
      
          return null;
      }
      

      【讨论】:

      • 其实all()是模型上的静态方法(OP使用的都是静态的:allcreate)。 Eloquent 上的大部分调用都传递给 Model 后面的 Eloquent\Builder 类,你说得对,它首先被实例化。
      • @deczo 你是对的!我忘记了,谢谢指出。我将更改我的示例以改用find
      • @watcher,控制器中的代码呢。当我按照规定修改 EloquentPartyRepository 时,我收到错误“调用非对象上的成员函数 user()”。
      • 您的控制器需要将存储库注入其中,您正在注入模型本身(这是存储库模式的基本点,您不希望任何东西直接依赖于您的模型类)。您还需要一些方法来确定要在 what 上查找用户的一方(阅读 - 您如何确定要加载的一方的 ID?)
      • 明白。查找partyId 是一个问题,因为当时正在创建记录。我正在尝试在创建 Party 时使用该关系将 user_id 插入模型中
      猜你喜欢
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      • 2012-08-16
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多