Подтвердить что ты не робот

Прерывистая ошибка абстрактного класса PHP

Я немного борюсь с этим и не могу понять, может быть, у кого-то есть или может быть более серьезная проблема с Slim, PHP, Apache и т.д. После работы всего несколько часов, моя Slim install начнет давать это на всех маршрутах:

Неустранимая ошибка: класс Slim\Collection содержит 1 абстрактный метод и поэтому должен быть объявлен абстрактным или реализовать оставшиеся методы (IteratorAggregate:: getIterator) в F:\Projects\example\server\vendor\slim\slim\Slim\Collection.php в строке 21

Поразительно, что этот вопрос пропадает, если я перезапущу Apache. (В течение нескольких часов).

Я нашел это, когда у кого-то была аналогичная проблема два года назад, и тот, кто помогал им, без помощи вообще: https://community.apachefriends.org/viewtopic.php?p=250966&sid=96ef58aaeb7fe142a7dcdfd506a8683f

Я пробовал сделать чистую очистку и установить каталог каталога поставщиков. Это не исправляет. Я могу ясно видеть, что getIterator реализован как ожидалось в файле в сообщении об ошибке.

PHP версии 7.0.12, Windows 7, x86 PHP Build

Это произошло снова через несколько часов с другим, но похожим сообщением об ошибке:

Неустранимая ошибка: класс Pimple\Container содержит 1 абстрактный метод и поэтому должен быть объявлен абстрактным или реализовать оставшиеся методы (ArrayAccess:: sqlserver) в F:\Projects\example\server\vendor\pimple\pimple\src\Pimple\Container.php в строке 34

У этого вопроса есть аналогичная проблема и "решает" его, перезагружая PHP, но это явно не является реальным решением, и у меня нет поддержки opcache: PHP 7, Symfony 3: Fatal error 1 абстрактный метод и поэтому должен быть объявлен абстрактным или реализовать оставшиеся методы

Любые догадки? Помните: это сообщение в файлах, которые я не писал, и уходит на перезапуск Apache. Есть ли кэширование с PHP 7, которое могло бы вызвать это?

Редактировать 3/10/17:

Да, я открыл билет с Slim. Я также видел это в не-тонком файле (Pimple), поэтому я не думаю, что это тонкая проблема. https://github.com/slimphp/Slim/issues/2160

Как я уже сказал, мой opcache отключен. Я подтвердил, что это верно как в файле php.ini, так и в phpinfo().

4b9b3361

Ответ 1

Я думаю, что вы столкнулись с этой ошибкой opcache. Это не совсем та же ситуация, но, вероятно, связано.

После вызова функции opcache_reset() мы сталкиваемся с некоторыми странными ошибками. Это происходит случайно на серверах (10 из 400 серверов)

Некоторая буква a заменена другими, класс, кажется, уже объявлен. и т.д.

Пример ошибок, вызванных после opcache_reset():

  • PHP Неустранимая ошибка: класс XXX содержит 1 абстрактный метод и поэтому должен быть объявлен абстрактным или реализовать оставшиеся методы (YYY:: funczzz) в /dir/dir/x.php в строке 20

Билет закрыт, потому что у разработчиков недостаточно информации для его воспроизведения. Если вы можете придумать самый маленький воспроизводимый случай, я рекомендую сообщить об этом. Создайте очень маленькое Slim-приложение, а затем используйте JMeter или другой инструмент, чтобы сделать много запросов. Опубликуйте свои выводы.

Между тем единственным обходным решением может быть отключить opcache в php.ini:

opcache.enable=0

Конечно, это резко ухудшит производительность. Пока он не будет исправлен, вам придется выбирать между производительностью или периодическим перезапуском Apache.

Если отключение кеша не работает, единственной причиной, о которой я мог думать, является проблема с прерывистой задачей с компилятором кода операции. Кэшированная или не скомпилированная версия должна иметь ошибку. Открытие воспроизводимого билета с помощью PHP-разработчиков или отладка исходного кода PHP будет единственным способом продвижения, если это причина.

Ответ 2

Если вы разрабатываете Windows, я бы рекомендовал вам НЕ использовать XAMPP или WAMPP и попробовать настоящий сервер разработки с использованием Linux на виртуальной машине.

Попробуйте установить Vagrant и Virtualbox, затем перейдите на сайт puphpet.com, который может создать вам конфигурацию виртуальной машины. Разархивируйте загрузку, cd в папку, введите vagrant вверх. Затем просто укажите свой хост на виртуальной машине. Ставлю, если у вас есть реальная среда разработки, эта ошибка исчезнет. Другой вариант - Docker, но у него немного кривая обучения.

Проблема заключается не в вашем коде (или в коде поставщика), а в вашей платформе.

Ответ 3

У меня была такая же проблема с использованием CodeIgniter и PHP 7.1.x.

Я обновился до PHP 7.2, и проблема больше не возникла.

Ответ 4

Я столкнулся с этим точным поведением и не был точно ошибкой opcache, даже если это было вызвано opcache.

Проблема заключалась в том, что у нас было несколько классов с тем же базовым именем, например

Request\GenericProtocol\Dispatcher     abstract
Request\Protocol1\Dispatcher
Request\Protocol2\Dispatcher

Теперь по умолчанию в нашей установке opcache использовала "оптимизацию", которая использовала только имя_базы как кэш-ключ. В результате всякий раз, когда script происходило создание экземпляра Protocol2 Dispatcher в чистом кеше, он тонко саботировал все последующие вызовы с помощью протокола 1. Из-за шаблонов использования это маскируется как любая другая ошибка.

В итоге мы просто активировали соответствующую опцию:

opcache.use_cwd boolean

Если включено, OPcache добавляет текущий рабочий каталог к ​​ script, тем самым устраняя возможные столкновения между файлами с тем же базовым именем. Отключение этой директивы повышает производительность, , но может нарушать существующие приложения.

Условием нарушения является следующее: у вас есть как минимум два класса с одинаковым базовым именем.

Нашей следующей итерации действительно планируется переименовать много классов

 Request\Protocol1\Dispatcher   ==> Request\Protocol1\Protocol1Dispatcher

чтобы иметь возможность повторно отключить use_cwd и сжать несколько процентов производительности (PTB и PHB считают, что это того стоит), но я знаю, что это может быть невозможно с каждой инфраструктурой.