2016-11-30 58 views
2

我有我的自定義類的問題位於:ZF2使用PHP5 VS PHP7

module/SomeModule/src/SomeModule/Model/someClass.php 

我得到一個數據庫適配器像這樣使用ServiceLocator(完全是in this Learning Zend Framework 2 tutorial):

public function getAdapter() 
{ 
    if (!$this->adapter) { 
    $sm = $this->getServiceLocator(); 
    $this->adapter = $sm->get('Zend\Db\Adapter\Adapter'); 
    } 
    return $this->adapter; 
} 

在PHP 5工作得很好,但在PHP 7中並沒有。看來這個類是在PHP 7不再ServiceLocatorAware並給出了此錯誤:

Fatal error: Uncaught Error: Using $this when not in object context in C:\Zend9\Apache24\htdocs\Project\module\Account\src\Account\Model\User.php:316 
Stack trace: 
#0 C:\Zend9\Apache24\htdocs\Project\module\Account\src\Account\Model\User.php(271): Account\Model\User::getAdapter() 
#1 C:\Zend9\Apache24\htdocs\Project\module\Account\src\Account\Controller\LoginController.php(40): Account\Model\User::userLogin('xxx', 'xxx') 
#2 C:\Zend9\ZendServer\data\libraries\Zend_Framework_2\2.4.9\library\Zend\Mvc\Controller\AbstractActionController.php(82): Account\Controller\LoginController->indexAction() 
#3 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent)) 
#4 C:\Zend9\ZendServer\data\libraries\Zend_Framework_2\2.4.9\library\Zend\EventManager\EventManager.php(444): call_user_func(Array, Object(Zend\Mvc\MvcEvent)) 
#5 C:\Zend9\ZendServer\data\libraries\Zend_Framework_2\2.4.9\library\Zend\EventManager\EventManager.php(205): Zend\EventManager\EventManager->trigg 
in C:\Zend9\Apache24\htdocs\Project\module\Account\src\Account\Model\User.php on line 316 

誰能告訴我,爲什麼有PHP 5和PHP 7,以及如何解決它之間的差異?

+0

什麼時候開始通過檢查錯誤日誌 – RiggsFolly

+0

你PHP7跳 – RiggsFolly

+0

PHP 5.6之前,使用了什麼版本的PHP5中,錯誤日誌顯示: \t使用$這個時候不是在對象上下文 – user3130983

回答

3

你或Zend Framework正在調用一個靜態成員$this(類似於使用靜態調用來調用非靜態成員)。

如果你沒有刪除你的一半錯誤信息,我可以告訴你究竟發生了什麼。

http://php.net/manual/en/language.oop5.basic.php

The pseudo-variable $this is available when a method is called from within an object context. $this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object). As of PHP 7.0.0 calling a non-static method statically from an incompatible context results in $this being undefined inside the method. Calling a non-static method statically from an incompatible context has been deprecated as of PHP 5.6.0. As of PHP 7.0.0 calling a non-static method statically has been generally deprecated (even if called from a compatible context). Before PHP 5.6.0 such calls already triggered a strict notice.

+0

我認爲你是正確的,我將整個錯誤消息添加到主題。 如何使用PHP 7做到這一點 - 只是聲明getAdapter函數是靜態的? 謝謝 – user3130983

+1

很好的答案。這個問題是一個很好的例子,說明爲什麼這個棄用是合法的,並且是PHP7的一個重大改進。 – Wilt

1

此問題可能是由於刪除了Zend Framework的更高版本中的ServiceLocatorAwareInterfaceServiceManagerAwareInterface而導致的。這也意味着默認情況下,ServiceLocator不再可用於ServiceLocatorAware類。

所以這條線從taht你指的是在你的問題教程:

The adapter can then be accessed in any ServiceLocatorAware classes.

也不再適用於新的Zend Framework的版本(PHP 7個版本)。


您也可以在the migration guide瞭解更多關於這種變化:

The following interfaces, traits, and classes were removed:

  • ...
  • Zend\ServiceManager\ServiceLocatorAwareInterface
  • Zend\ServiceManager\ServiceLocatorAwareTrait
  • Zend\ServiceManager\ServiceManagerAwareInterface

The ServiceLocatorAware and ServiceManagerAware interfaces and traits were too often abused under v2, and represent the antithesis of the purpose of the Service Manager component; dependencies should be directly injected, and the container should never be composed by objects.

您將需要重構自己的服務,可能做到這一點的最好的辦法就是你注入創建一個服務工廠的依賴關係(在你的例子中是Zend\Db\Adapter\Adapter類)。

+0

感謝您的回答,但是,代碼 - 即使框架版本也完全一樣 - 只有Zend服務器使用php5.6而Zend服務器使用php7。 – user3130983

1

您的評論後,我看到的問題是什麼。這個信息應該在問題中,也許你可以編輯你的問題並添加它。

你可以叫getAdapter靜態(User::getAdapter();),但$this不會執行此操作時可用...

你可以調用非靜態方法靜態在PHP但如果方法使用$this它會拋出一個錯誤因爲靜態調用方法時$this不可用。

檢查also this similar question with an answer瞭解更多信息:

You can do this, but your code will error if you use $this in the function called fun1()

關於爲什麼這與PHP 5.6工作,並不再我想指的是從@DanFromGermany誰很好地解釋了這個答案...

+0

服務管理器和服務定位器感知類可以使用$ this嗎?記住它是由全局自動載入設置實例化的嗎? – user3130983

+0

@ user3130983不知道你在說什麼。如果你想繼續使用這樣的代碼開始[聲明你的函數是靜態的](http://php.net/manual/en/language.oop5.static.php):'public static function getAdapter'。 – Wilt