Странности PHP при include'e файлов с унаследованными классами

Turist

Новичок
Странности PHP при include'e файлов с унаследованными классами

Проблема скорее теоретическая, т.к. при нормальном использование include (а точнее include_once) не возникает, но всё же...
Есть два скрипта:
Скрипт 1 bibl.inc:
Код:
<?php
if (isset($GLOBALS['loaded'])) {
    return;
}
$GLOBALS['loaded']=true;

class MyClass {
}

class MyClass2 extends MyClass {
}
?>
Скрипт 2 go.php:
Код:
<?php
include('bibl.inc');
include('bibl.inc');
?>
Если я правильно понимаю ошибок при исполнение появится не должно, но:
Код:
>php ./go.php
Fatal error: Cannot redeclare class myclass2 in /var/www/test1/classtest/bibl.inc on line 11
Собственно основной интерес вызывает даже не попытка передекларировать MyClass2, хотя, по идеи, этого не должно произойти, т.к. при втором вложении bibl.inc глобальная переменная loaded=true и мы покинем bibl.inc в строке 3.
Странно то, что если уж ошибка возникает, то почему она возникает не при декларации MyClass?
Т.е. почему PHP всё таки парсит bibl.inc второй раз и если уж парсит,то почему пытается переобъявить только наследуемые классы?

Возможно я где-то что-то упустил в документации или в теории, укажите пожалуйста что и где?
(Коллеги, ещё раз повторяю, я знаю о существовании include_once! Вопрос более теоретический чем практический)

-~{}~ 08.06.06 19:03:

Чуть не забыл - PHP 5.1.4 хотя и на 4.3.2 та же история
 

DiTHER

bang bang
Так.

php-4.4.2 - все ок.
php-5.1.4 - редекларация второго класса.

как в cgi, так и в виде модуля apache.

Возможно, баг. Ищи в багах php.net.
 

Gorynych

Посетитель PHP-Клуба
очень неприятный эффект, между прочим. Дело даже не в инклюде, а в том, что в PHP 5 привыкаешь использовать __autoload и попытка повторного подключения возможна.

я правда предпочитаю не глобальные переменные, а определять константы:
Код:
if ( defined('__MyClass') ) {
    return;
} else {
    define('__MyClass', 1);
}
причем проблема (видимо) именно в наследовании, потому что вариант:
Код:
<?php
if ( defined('__MyClass') ) {
    var_dump(__MyClass);
    return;
} else {
    define('__MyClass', 1);
}

class MyClass {
}

class MyClass2 {
}
?>
отробатывает так, как и ожидается.
 

Turist

Новичок
Да я и писал, проблема именно в наследовании.
Пока на bugs.php.net ничего не нашёл.
Чуть позже проверю не исправили ли в CVS версии.
 

_vampiro_

Новичок
Классы в ПХП5 - типы данных, и она их грузит не зависимо от наличия return; вроде так. Файл-то она весь читает, но не весь выполняет. если у вас до ретурна создаётся объект класса, описанного "ниже" ретурна - то все будет нормально работать. Это не баг - это фича!
 

Gorynych

Посетитель PHP-Клуба
_vampiro_ в принципе верно, вот только что делать с попыткой повторной загрузки?

Дело в том, что у меня подгрузка большинства классов строится через автозагрузку и (забавный факт!) - иногда наблюдалась попытка повторнго подключения при конструкции require_once. В какой-то момент появилось ощущение, что проверка "единственности" включения основывается на точном совпадении того имени файла (с путем) которое передается в require_once. Т.е. если путь к одному и тому же указан по разному, интерпритатор пытается его подключить повторно.

Но точно повторить ситуацию приводившую к такой ошибке сейчас не могу.
 

_vampiro_

Новичок
[m]class_exists[/m] ?

-~{}~ 09.06.06 17:34:

по поводу инклуд_уанс

c:/1/1.php:
PHP:
<?php echo '1';

c:/1/2.php
PHP:
<?php
include_once './1.php';
include_once '\/../1/1.php';
?>
на экране "11" что не есть гуд. Ищите косяк в преобразовании путей.
 

Gorynych

Посетитель PHP-Клуба
_vampiro_ мил человек, так если я правильно понимаю, вот этот зверь - http://www.php.net/manual/en/language.oop5.autoload.php и должен срабатывать при попытке обращения к классу, который еще не определен, т.е. отнюдь не exists.

и вот тут-то вся эта грабля очень не кстати. Угу, кстати, что-то такое с путями, что у тебя в примере, и было.
 
Сверху