ClassAutoLoader

Sender

Новичок
ClassAutoLoader

Написал класс для автозагрузки файлов, где лежит класс.

Он сам узнает в каком файле лежит класс (по массиву Class->File) и подгружает его при объявлении new ClassName(). Если не находит файл для класса, еще раз перестраивает массив Class->File


http://phpclub.ru/paste/1619

в данном примере в каталоге classes лежит класс classA в файле classa.php
если вы добавите в директорию classes любой файл с любым классом в любую поддиректорию, то в index.php достаточно написать:
$ClassName = new Classname() - а автозагрузчик файлов автоматически загрузит файл, отвечающий за этот файл


что вы об этом думаете?
php.net/manual/ru/language.oop5.autoload.php хочется здесь это дело опубликовать, чтобы не позорится сначала ваше мнение интересно ))
 

GemVit

Новичок
Мнение: Для начала не мешало бы задокументировать класс.
 

Vallar_ultra

Любитель выпить :)
GemVit

Там и без документирования всё прозрачно.

Sender

А чего тебе сказать об этом????? Лично я не понял в чём суть темы...
 

Sender

Новичок
GemVit
ну вроде бы да, класс там понятен, документировать потом можно

Vallar_ultra
избавление от необходимости выполнять include_once и require_once при создании new ClassName
 

Vallar_ultra

Любитель выпить :)
Sender

Эт я понял!
Вот чё ТЫ хочешь услышать по данному поводу? Этого я НЕ понял.
 

GemVit

Новичок
Sender, Vallar_ultra
Я не говорю что он не понятен или не прозрачен.
Я же не знаю что там потом будет. А комментарии к методам и свойствам считаю нужными.

Sender
А не думал добавить проверку на существование индекса
[$ClassName]
?
 

Shturm

Гигант мысли
А что за странные манипуляции с file_exists()?
Аж целых три раза:
PHP:
function Load( $ClassName )
    {
        if( !file_exists( $this->ClassList[$ClassName] ) )
    {
        $this->ClearCacheClassList();
        $this->GetClassList();
    }
    if( file_exists( $this->ClassList[$ClassName] ) )
    {
        include_once( $this->ClassList[$ClassName] );
        if( !class_exists( $ClassName ) )
        {
            $this->ClearCacheClassList();
            $this->GetClassList();
            if( file_exists( $this->ClassList[$ClassName] ) )
            {
                include_once( $this->ClassList[$ClassName] );
            }
        }
    }
}
тоесть проверяем, существует ли файл, соответствующий
имени класса из списка( валидация кеша, по сути ),
если нет - перезагружаем кеш. Окей. Проверяем файл снова.
Инклюдим.
Проверяем наличие определения класса.
Если его нет, то перегружаем кеш (зачем?)
и повторяем загрузку файла (совсем непонятно).

Алгоритм напрашивается на оптимизацию
 

itprog

Cruftsman
Shturm
ща на тебя нападут что файл может исчезнуть между проверками :)
 

Sender

Новичок
itprog
:) нет

GemVit
ага, надо бы, спасибо, поправил



Vallar_ultra
хотел услышать не велосипед ли, может зря старался и может это вообще это неправильный подход


Shturm
там такая ситуация, если первый if не сработал, то есть файл такой был, и данные взяты из кеша, то класс могли из этого файла вынести в другой файл, следовательно нам надо перегрузить кеш и еще раз заинклудить теперь уже правильный файл если он найден
 

Vallar_ultra

Любитель выпить :)
ИМХО. Я никогда не сталкивался с жесткой необходимостью такого решения.... Но почему-бы и нет :)
 

Sender

Новичок
нашел ошибку...

при обходе файлов, чтобы выяснить какие классы в файле есть, - они инклудятся. но если заинклудить файл в котором объявлен какой-то класс, файл которого не заинклудили то происходит ошибка...
 

zerkms

TDD infected
Команда форума
Sender
раздели логику кэширования и подгрузки на 2 класса
 

Sender

Новичок
zerkms
верно, спасибо




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

-~{}~ 19.01.07 08:16:

немного помучался, потому что у меня для классов под разные проекты один каталог. есть общий каталог классов, которые используются во всех проектов, а в подкаталоге лежат классы для определенного проекта. получилось так что в разных проектах используются класы с одинаковыми названиями, и при построении списка классов возникает неоднозначная ситуация когда неизвестно какой класс реально надо подключать из двух.
пока что решил так...
PHP:
					if( isset( $this->ClassList[$Class] ) )
					{
						die( "Autoload conflict: class '{$Class}' from file `{$File}` already load from file `{$this->ClassList[$Class]}`" );
					}
					$this->ClassList[$Class] = $File;
 

Wicked

Новичок
Sender
1) вопросик... почему код написан на пхп4? __autoload все равно сделали начиная с 5го :)

2) global $ClassAutoLoader; - глобалы не люблю. Мож синглтон получше будет?

3) я бы в SetCacheClassList() заюзал file_put_contents();

4) почему объект в конструкторе принимает только одну директорию?

5) имхо [m]include_once[/m]() + [m]get_declared_classes[/m]() не очень хороший вариант. Мне страшно предположить, что может произойти, если человек ошибется и заинклюдит какие-нибудь не те файлы :) Я бы заюзал [m]token_get_all[/m]().

6) применяй [m]strtolower[/m]() к именам классов. Имена классов - case insensitive.
 

Sender

Новичок
Wicked
вопросик... почему код написан на пхп4? __autoload все равно сделали начиная с 5го
речь об области действия переменных и интерфейсе?

2) global $ClassAutoLoader; - глобалы не люблю. Мож синглтон получше будет?
я в паттернах не силен... долго смотрел на пример синглтона в мануале, не пойму, как он поможет избавиться от global


3) я бы в SetCacheClassList() заюзал file_put_contents();
заюзал

4) почему объект в конструкторе принимает только одну директорию?
уже массив принимает, когда начал встраивать то доделал

5) имхо include_once() + get_declared_classes() не очень хороший вариант. Мне страшно предположить, что может произойти, если человек ошибется и заинклюдит какие-нибудь не те файлы Я бы заюзал token_get_all().
да мне тоже не нравится, я просто о token_get_all не знал, переделал через token_get_all, так гораздо правильнее, согласен

6) применяй strtolower() к именам классов. Имена классов - case insensitive
применил


вот что получилось
http://phpclub.ru/paste/1623
 

GemVit

Новичок
Sender
На сколько велика значимость Cache?
Может дать возможность отключить Cache, типа
$ClassAutoLoader->useCache(false);
?
 

Sender

Новичок
GemVit
категорически не стоит, отключишь кеш - при каждой загрузке будет строиться список файлов, то есть постоянно обход директории, загрузка файлов... это лишняя нагрузка
 
Сверху