При написании сложных систем на php, количество подключаемых файлов возрастает неимоверно. Подключать в лоб, все необходимые файлы, быстро надоедает. Да и такой способ сказывается на быстродействии скрипта. Ведь не для всех операций нужны все скрипты.

На помощь приходит встроенный в php механизм автозагрузки классов при их вызове.

Раньше мы делали так:



<?php 
include 'db.php';
$db = new db();

Если класс не будет загружен то мы получим фатальную ошибку. Пойдем другим путем. Положим, что все наши классы лежать в папке classes/ и названия классов соответствуют названиям файлов с префиксом class.

Регистрируем автозагрузчик функцией spl_autoload_register



<?php 
spl_autoload_register(function ($class_name) {
	$file = 'classes/class..'.strtolower($class_name) . '.php';
	if ( file_exists($file) )
		require_once ($file);
});

теперь вы сразу же можете использовать new db(), если файл class.db.php с соответствующим классом лежит в папке classes



$db = new db(); // подклчится class.db.php
$tpl = new tpl();// подклчится class.tpl.php
$router = new router();// подклчится class.router.php

При использовании совместно с техникой синглетонов, вы получаете отличный инструмент автоматизации процесса разработки.

Отличие spl_autoload_register от обычной spl_autoload или просто объявления функции __autoload в том, что Вы можете объявлять несколько загрузчиков, каждый из которых может искать файлы в разных папках. К примеру модули в папке modules/ и т.п. 

Оставлять комментарии могут только зарегистрированные пользователи

Комментарии  

User
# User 28.03.2013 20:58
ИМХО,

1. spl_autoload_register - не чувствительна к рЕгИсТрУ...

2. проверка file_exists - излищняя...




spl_autoload_register(
function( $class_name ) {
include '/classes/'.$class_name.'.php';
}
);
Leroy
# Leroy 28.03.2013 21:15
1)файлы на сервере ЧуВсТвИтЕлЬНы к регистру,
<?php
$a = new Gogogo();
а файл gogogo.php, неприятный и трудноуловимый баг

2)если такого файла не существует то можно запустить проверку в другой папке, это управляемая загрузка. нет в папке classes, посмотрим в папке modules, я так делаю очень удобно.
User
# User 29.03.2013 14:17
Дорогой, Leroy!

Что означает Ваше "запустить проверку в другой папке" ?

Может проще, приступая к реализации проекта, обдумать его полную структуру ?

То есть, ГДЕ и ЧТО будет находится (лежать).

И тогда не надо будет "по ходу" заниматься так называемой "лепниной"... )

Спасибо за участие.
Leroy
# Leroy 29.03.2013 14:37
Ну мне удобно держать классы md_article и db в разных папках. Классы модуля вызываются роутером автоматически, тут все в порядке. Он знает про них все, где они лежат и когда вызываются. Но я долго приходил к структуре, что из одного модуля нужны методы, которые есть в другом, к примеру хотим использовать систему тегов из новостей в модуле галерее. Тогда просто вызывая класс md_article я не забочусь о его загрузке, spl_autoload_register проверит есть ли данный класс в соответствующей папке, если нет то посмотрит в модулях. Я просто его использую.
emme-ay
# emme-ay 03.11.2013 14:45
"Ну мне удобно держать классы md_article и db в разных папках."


set_include_path( get_include_path().PATH_SEPARATOR.'folder1'.PATH_SEPARATOR.'folder2'.PATH_SEPARATOR.'folder3' );
spl_autoload_register( function( $class ) { include $class.'.php'; } );
Leroy
# Leroy 03.11.2013 15:17
Спасибо! Подозревал, что такое можно сделать. Хотя менять каждый раз системные переменные может не всегда хорошая идея
green-zip
# green-zip 05.11.2013 15:12
Извините, не "отверблюжил" код... )))


set_include_path( get_include_path()
. PATH_SEPARATOR . 'folder1'
. PATH_SEPARATOR . 'folder2'
. PATH_SEPARATOR . 'folder3');
spl_autoload_register( function( $class ) {
include $class . '.php';
});


Но Ваш вариант, с проверкой "if ( file_exists($file) )" мне нравится больше...
green-zip
# green-zip 05.11.2013 15:14
p.s.

Валера, проверьте, плз,

форма комментариев на статьи

часто "съедает" пробелы между словами... спс
Leroy
# Leroy 29.03.2013 14:40
еще file_exists позволит при отсутсвии файла произвести какие-нибудь действия: запись в лог, вывод своего нормального исключения, а не тупо выбрасывать fatal error, не понимая что же произошло.

Как-то так