Персональный сайт Александра Литовченко

номер32
Поиграть в преферанс в онлайне
2 мая 2008 05:43

Организация псевдомодулей в php проектах

С удивлением обнаружил, что многие php-кодеры в своих проектах используют либо файл all.php, в котором собраны все includes проекта, либо ставят в каждый скрипт «простыню» из includes, необходимых для работы данного скрипта. Между тем, для php5 есть более элегантный способ.

Теория

Способ заключается в перекрытии системного хука __autoload(). Прием вполне себе документированный, и, думаю, можно не беспокоиться что, например, в php6 он перестанет работать. Каждый раз, когда php встречает в коде ссылку на класс, он вызывает этот хук. Фичу эту zend добавил, по всей видимости, для возможности написания classloaders ala java, но использовать ее можно для организации ленивых инклюдов, псевдомодульности и псевдонеймспейсов.

Практика

Теперь немного практики. Допустим есть некий небольшой boot.php который вызывается отовсюду. В нем пишем что-то вроде:

function __autoload( $class_name )
{
    $s = '';
    $a =  explode( '_', $class_name );
    foreach( $a as &$folder )
    {
        if ( $s!='' ) $s .= '/';
        $s .= strtolower( $folder );
    }
    require_once( '/www/framework/'.$s.'.php' );
}

где '/www/framework/' путь ко всем php файлам этого проекта. И все. Больше в проекте нигде не нужно никаких include, require и прочей ереси.

Предположим разработчику нужна некая самописная библиотека работы со строками. Достаточно ее положить в /www/framework/core/strings.php и оформить примерно так:

class Core_Strings
{
    static function cutString( $s, $n=255 )
    {
        if ( strlen($s)>$n )
            $s = substr( $s, 0, $n).'...';
        return $s;
    }
    static function ...
    ...
}

Все. после этого можно вызывать из любого места проекта функцию Core_Strings::cutString() не задумываясь о том где реально находится эта функция и подключен ли этот include. Загружаться этот strings.php будет автоматически и только тогда, когда на странице будет использоваться хотя бы одна функция из него.

С классами — то же самое. Причем автоматическое подтягивание базовых классов также будет работать.

$grid = new Grid_DBGrid();

grid — название папки от корня кода проекта где лежит dbgrid.php, в котором описан:

class Grid_DBGrid extends Grid_AbstractGrid {...}

В этом случае автоматом подхватится также и /www/framework/grid/abstractgrid.php

Плюсы такого подхода

  • Инклюдится только то, что нужно
  • Инклюдится только тогда, когда нужно
  • Разработчику не нужно задумываться об инклюдах как таковых
  • Не нужен all.php, в котором собраны все инклюды проекта, и который загрузит и проинтерпретирует при каждом обращении к странице все мегабайты кода, которые для работы скрипта, вполне возможно, не нужны

Минусы

  • Работает только в >= php5.0
  • Необходима некоторая реорганизация уже накопленной базы кода

Комментарии

1 4 мая 2008 12:00, KOHb

Красиво. Везде :)

2 8 сентября 2008 11:51, REDucka

Прикольно и удобно

3 3 декабря 2011 09:22, ден

Очень хорошо, спасибо.

Добавить комментарий

только текст. HTML теги вырезаются:

Пожалуйста будьте вежливы при общении