ZF2 使用 PHP5 与 PHP7
ZF2 using PHP5 vs PHP7
我的自定义 class 位于:
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 中它不工作。似乎 class 不再是 PHP 中的 ServiceLocatorAware
7。并给出此错误:
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.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.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.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 有这个区别,如何解决?
这个问题可能是由于Zend Framework 更高版本中的ServiceLocatorAwareInterface
和ServiceManagerAwareInterface
被删除造成的。这也意味着默认情况下 ServiceLocator
在 ServiceLocatorAware
class 中不再可用。
因此,您在问题中所指的教程中的这一行:
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
class)。
您或 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.
在您发表评论后,我明白了问题所在。这些信息应该在问题中,也许你可以编辑你的问题并添加它。
您可以静态调用 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 的回答,他很好地解释了这一点...
我的自定义 class 位于:
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 中它不工作。似乎 class 不再是 PHP 中的 ServiceLocatorAware
7。并给出此错误:
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.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.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.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 有这个区别,如何解决?
这个问题可能是由于Zend Framework 更高版本中的ServiceLocatorAwareInterface
和ServiceManagerAwareInterface
被删除造成的。这也意味着默认情况下 ServiceLocator
在 ServiceLocatorAware
class 中不再可用。
因此,您在问题中所指的教程中的这一行:
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
class)。
您或 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.
在您发表评论后,我明白了问题所在。这些信息应该在问题中,也许你可以编辑你的问题并添加它。
您可以静态调用 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 的回答,他很好地解释了这一点...