2016-11-30 57 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