不应静态调用非静态方法

时间:2014-07-17 18:53:16

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

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

  

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

我不明白为什么当我尝试运行user()关系方法时出现此错误,但所有其他方法(包括$ this-> party-> all(),$ this-&gt ; 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();
  }
}

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

我已经解决了这个问题。感谢@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的适当顺序。