@Zezst
программист PHP

Include class наследование, в чем проблема?

Помогите понять, код который работал вдруг перестал работать.
есть два файла
index.php
<?php
include __DIR__.'/class_a.php';

$a = new b;
class b extends a {}
exit;

и class_a.php
<?php

class a {}


До недавнего времени никаких проблем с такой конструкцией небыло. Код работал.
Но буквално на днях начал выдавать ошибку:
Fatal error: Class 'b' not found

при этом если изменить немного файл index.php
<?php
include __DIR__.'/class_a.php';

class b extends a {}
$a = new b;
exit;

то все опять работает. Если class b extends a {} вынести в другой файл то снова все работает.
Снова меняем index.php
<?php

$a = new b;
class b extends a {}
class a {}
exit;

Опять ошибка. class not found.

<?php

$a = new b;
class a {}
class b extends a {}
exit;

И опять все работает.
Помогите понять почему так?
Код который успешно работал вдруг начал говорить что так не желает работать.
Где можно прочитать про подобное поведение?
  • Вопрос задан
  • 261 просмотр
Пригласить эксперта
Ответы на вопрос 3
Melkij
@Melkij
PostgreSQL DBA
Потому что сначала сущность объявляйте, а потом используйте. Не наоборот.
И вообще PSR-1, #2.3
https://github.com/php-fig/fig-standards/blob/mast...
A file SHOULD declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it SHOULD execute logic with side effects, but SHOULD NOT do both.
Ответ написан
@SergeyZelensky-Rostov
Вы пытаетесь создать экземпляр класса до его объявления

<?php
   class a {}
   class b extends a {}
   $a = new b;
   exit;
Ответ написан
Ваш пример кода становится рабочим и запускается благодаря OPCache.
Если очень упростить, то OPCache между компиляцией кода и запуском добавляет этап из оптимизации и кэширования на основе разделяемой памяти, после чего уже расширенный класс (с учетом наследования) может быть получен от туда. В PHP < 5.3 для этого использовалась установка с говорящим названием: opcache.inherited_hack

cache-optimization-steps.png
Кэш обновляется и обнуляется, в зависимости от настроек инвалидации и выделенного размера под хранения.
При этом каждый раз вы с таким кодом рискуете терять расширенный класс из кэша, тогда вам снова придется вручную добиваться его возврата через изменение файлов (триггер). Поэтому лучше так не делать, а последовать советам из других ответов, заодно учтя заветы PSR.

О работе и внутреннем устройстве OPCache смотрите статью: PHP's OPCache extension review
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы