ZF2使用PHP5与PHP7

时间:2016-11-30 21:38:18

标签: php zend-framework2 adapter zend-framework3 zf3

我的自定义类存在问题:

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之间存在这种差异以及如何解决它?

3 个答案:

答案 0 :(得分:3)

您或Zend Framework使用$this调用静态成员(类似于使用静态调用调用非静态成员)。

如果您没有删除一半的错误消息,我可以告诉您这究竟发生了什么。

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

  

调用方法时,伪变量$this可用   在对象上下文中。 $ this是对调用对象的引用   (通常是方法所属的对象,但可能是另一个   object,如果从a的上下文静态调用该方法   次要对象)。 从PHP 7.0.0开始调用非静态方法   静态地从不兼容的上下文导致$ this   在方法中未定义。静态调用非静态方法   从PHP 5.6.0开始,不兼容的上下文已被弃用。如   PHP 7.0.0静态调用非静态方法一般   不推荐使用(即使从兼容的上下文调用)。在PHP之前   5.6.0这样的电话已经触发了严格的通知。

答案 1 :(得分:1)

此问题可能是由于删除了Zend Framework更高版本中的ServiceLocatorAwareInterfaceServiceManagerAwareInterface这一事实。这也意味着默认情况下ServiceLocator类中不再提供ServiceLocatorAware

所以你在问题中指的是教训中的这一行:

  

然后可以在任何ServiceLocatorAware类中访问适配器。

不再适用于较新的Zend Framework版本(PHP 7版本)。

您还可以在the migration guide中了解有关此更改的更多信息:

  

删除了以下接口,特征和类:

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

ServiceLocatorAware和ServiceManagerAware接口和特性在v2下经常被滥用,并且代表了Service Manager组件目的的对立面;应该直接注入依赖项,并且容器永远不应该由对象组成。

您需要重构您的服务,可能最好的方法是创建一个注入依赖项的服务工厂(在您的示例中为Zend\Db\Adapter\Adapter类)。

答案 2 :(得分:1)

在您发表评论后,我看到了问题所在。这些信息应该在问题中,也许您可​​以编辑您的问题并添加它。

您可以静态调用%.2fgetAdapter),但执行此操作时将无法使用User::getAdapter(); ...

您可以在PHP中静态调用非静态方法,但如果方法使用$this则会引发错误,因为静态调用方法时$this不可用。

检查also this similar question with an answer以获取更多信息:

  

您可以执行此操作,但如果您在名为$this

的函数中使用$ this,则代码会出错

关于为何使用PHP 5.6而不再使用它我想参考@DanFromGermany的答案,他很好地解释了这个......