У меня проблема с моим пользовательским классом, расположенным в:
module/SomeModule/src/SomeModule/Model/someClass.php
Я получаю адаптер базы данных, как это с помощью ServiceLocator
(точно так же, как в этом Изучение Zend Framework 2 руководство):
public function getAdapter()
{
if (!$this->adapter) {
$sm = $this->getServiceLocator();
$this->adapter = $sm->get('Zend\Db\Adapter\Adapter');
}
return $this->adapter;
}
В PHP 5 это работает просто отлично, но в PHP 7 это не так. Кажется, что класс больше не ServiceLocatorAware
в PHP 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\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 и как ее устранить?
Вы или Zend Framework вызываете статического члена с $this
(похоже на вызов нестатического члена с использованием статического вызова).
Если вы не удалили половину своего сообщения об ошибке, я мог бы сказать вам, где именно это происходит.
От http://php.net/manual/en/language.oop5.basic.php
Псевдо-переменная
$this
доступно, когда метод вызывается из
в контексте объекта. $ это ссылка на вызывающий объект
(обычно объект, которому принадлежит метод, но, возможно, другой
объект, если метод вызывается статически из контекста
вторичный объект). Начиная с PHP 7.0.0, вызывая нестатический метод
статически из несовместимого контекста приводит к тому, что $ это
не определено внутри метода. Вызов нестатического метода статически
из несовместимого контекста устарел, начиная с PHP 5.6.0. Как
PHP 7.0.0 статический вызов нестатического метода
не рекомендуется (даже если вызывается из совместимого контекста). До PHP
5.6.0 такие звонки уже вызвали строгое уведомление.
Эта проблема, вероятно, вызвана тем, что ServiceLocatorAwareInterface
и ServiceManagerAwareInterface
в более поздних версиях Zend Framework были удалены. Это также означает, что ServiceLocator
больше не доступен в ServiceLocatorAware
классы по умолчанию.
Итак, эта строка из учебника, на которую вы ссылаетесь в своем вопросе:
Затем к адаптеру можно получить доступ в любых классах ServiceLocatorAware.
больше не применяется к более новым версиям Zend Framework (версии PHP 7).
Вы также можете прочитать больше об этом изменении в руководство по миграции:
Следующие интерфейсы, черты и классы были удалены:
- …
- Zend \ ServiceManager \ ServiceLocatorAwareInterface
- Zend \ ServiceManager \ ServiceLocatorAwareTrait
- Zend \ ServiceManager \ ServiceManagerAwareInterface
Интерфейсы и признаки ServiceLocatorAware и ServiceManagerAware слишком часто злоупотребляли в v2 и представляют собой противоположность цели компонента Service Manager; зависимости должны вводиться напрямую, а контейнер никогда не должен состоять из объектов.
Вам нужно будет реорганизовать свой сервис, и, вероятно, лучший способ сделать это — создать фабрику сервисов, в которую вы вводите свои зависимости (в вашем примере Zend\Db\Adapter\Adapter
учебный класс).
После вашего комментария я вижу, в чем проблема. Эта информация должна была быть в вопросе, возможно, вы могли бы отредактировать свой вопрос и добавить его.
Ты можешь позвонить getAdapter
статически (User::getAdapter();
) но $this
не будет доступен, когда вы сделаете это …
Вы можете вызывать нестатический метод статически в PHP, но он вызовет ошибку, если метод использует $this
поскольку $this
недоступен при статическом вызове метода.
Проверьте также этот похожий вопрос с ответом для дополнительной информации:
Вы можете сделать это, но ваш код выдаст ошибку, если вы используете $ this в функции с именем
fun1()
О том, почему это работает с PHP 5.6, и больше нет, я бы хотел сослаться на ответ @DanFromGermany, который хорошо это объясняет …