2016-11-30 3 views
2

У меня есть проблема с моим пользовательским классом, расположенную в:ZF2 с использованием PHP5 против 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 это не так. Кажется, что класс больше не 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 и как решить ее?

+0

ли вы начать с проверки журналов ошибок – RiggsFolly

+0

Какую версию PHP5 ты использовал до PHP7 скачка – RiggsFolly

+0

PHP 5.6, журнал ошибок показывает: \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 статикой? Thanks – user3130983

+1

Хороший ответ. Этот вопрос является хорошим примером того, почему устаревание является законным и значительно улучшено в PHP7. – Wilt

1

Эта проблема, вероятно, вызвана тем, что были удалены ServiceLocatorAwareInterface и ServiceManagerAwareInterface в более поздних версиях Zend Framework. Это также означает, что 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 Не уверен, что вы пытаетесь сказать. Если вы хотите продолжить использовать такой запуск кода [с объявлением своих функций static] (http://php.net/manual/en/language.oop5.static.php): 'public static function getAdapter'. – Wilt