За последние 24 часа нас посетил 20631 программист и 1107 роботов. Сейчас ищут 353 программиста ...

Определение имени загруженного класса

Тема в разделе "Прочие вопросы по PHP", создана пользователем AterCattus, 17 июл 2008.

  1. AterCattus

    AterCattus Активный пользователь

    С нами с:
    6 фев 2008
    Сообщения:
    80
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Спрашиваю не помощи, а совета. Решение проблемы найдено, но вдруг есть лучше.

    Сразу уточняю, что разговор о PHP5.

    Есть некоторый файл, в котором описан класс:
    PHP:
    1. <?php
    2.     class my {}
    3. ?>
    Ну понятно, что все лишнее я вырезал ;-)

    Так вот, есть функция загружающая такие классы из файлов:
    PHP:
    1. <?php function &load_class() {
    2. $args = func_get_args();
    3. ...
    4. // неким образом получаю из $args значение $class_path
    5. ...
    6. require( $class_path . 'class.php' ); ?>
    Все хорошо, но мне-то нужно как-то узнать имя загруженного класса. Для создания экземпляра:
    PHP:
    1. <?php return &new $CLASSNAME(); ?>
    И вся соль в получении этого самого $CLASSNAME.

    Первой мыслью был такой вариант:
    PHP:
    1. <?php
    2.     $CLASSNAME = 'my';
    3.     class my {
    4.     }
    5.  
    6. ...
    7. unset( $CLASSNAME );
    8. require( $class_path . 'class.php' );?>
    Но мне мягко говоря не понравилось.

    Написал текущий вариант:
    PHP:
    1. <?php class my {} ?>
    2. ...
    3. <?php
    4. $snapshot = get_declared_classes();
    5. require( $class_path . 'class.php' );
    6. $snapshot = array_diff( get_declared_classes(), $snapshot ); ?>
    Вроде бы как раз то, что мне хотелось (в одном файле описывается только один класс, ну а даже если их несколько, инстанцируется только первый описанный).

    Однако, если ли способ лучше?

    Заранее спасибо за любые дельные советы.
     
  2. Anonymous

    Anonymous Guest

    ммм, а почему б не грузить все это дело spl_* функциями, и из них же и записывать, кого подключили, ибо там classname известен?
     
  3. AterCattus

    AterCattus Активный пользователь

    С нами с:
    6 фев 2008
    Сообщения:
    80
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Ну, насколько я понимаю, речь идет об *__autoload. Но там же необходимо знать имя класса что как раз в моем случае и неизвестно. У меня есть только путь к файлу скрипта, где описан класс.

    Имя файла скрипта не совпадает с именем класса (пусть даже на уровне case-sensitive). Также не известно, где этот файл находится (вычисляется на основе некоторого алгоритма).
     
  4. Anonymous

    Anonymous Guest

    Вообще, если задача стоит именно так, то она стоит неправильно. :)
    А вообще, я бы tokenizer-ом выдергивал класс из файла, и получал бы имя.
     
  5. AterCattus

    AterCattus Активный пользователь

    С нами с:
    6 фев 2008
    Сообщения:
    80
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    А не будет ли парсинг много медленее предложенного второго варианта? Просто многие классы будут разрабатываться фиг знает кем и совершенно не ясно заранее, что там будет в файле.
     
  6. Anonymous

    Anonymous Guest

    Тем более, можно и синтаксис сразу проверить. ;)
    Дык перед инклюдом PHP все равно синтаксис проверяет, и парсит файл. ;) Полученные результаты просто надо кешировать.
     
  7. Anonymous

    Anonymous Guest

    А вообще ты что, хочешь плагины сделать, что ли?
     
  8. AterCattus

    AterCattus Активный пользователь

    С нами с:
    6 фев 2008
    Сообщения:
    80
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    >Дык перед инклюдом PHP все равно синтаксис проверяет, и парсит файл.
    Вот. А свой парсер еще и сам предварительно будет парсить - получается двойная работа. Понятно, что для разбора хватит лексического и синтаксического анализатора, даже семантика уже не важна. Но оно того стоит? Сильно в этом сомневаюсь.

    Мой вариант с get_declared_classes() у меня работает около 5мс. Скорость меня устраивает, но вот количество загруженных классов под 200, а это немаленький расход памяти.

    Варианты с __autoload мне не подходят хотя бы по той причине, что хочется в пути к файлам указывать их логическое и функциональное назначение. Например /user/db.filter/class.php или /user/db/filter/class.php. А сам класс называется DBFilter или CDBFilter. Можно конечно сделать так: /user/db_filter/class.php, но это уже как-то искусственно и, имхо, не так наглядно.

    >А вообще ты что, хочешь плагины сделать, что ли?
    Нет, модули для CMF. Но суть конечно близка.