我的自定义类存在问题:
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 :(得分: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更高版本中的ServiceLocatorAwareInterface
和ServiceManagerAwareInterface
这一事实。这也意味着默认情况下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)
在您发表评论后,我看到了问题所在。这些信息应该在问题中,也许您可以编辑您的问题并添加它。
您可以静态调用%.2f
(getAdapter
),但执行此操作时将无法使用User::getAdapter();
...
您可以在PHP中静态调用非静态方法,但如果方法使用$this
则会引发错误,因为静态调用方法时$this
不可用。
检查also this similar question with an answer以获取更多信息:
您可以执行此操作,但如果您在名为
的函数中使用$ this,则代码会出错$this
关于为何使用PHP 5.6而不再使用它我想参考@DanFromGermany的答案,他很好地解释了这个......