1. Функция __autoload()
В php для автозагрузки классов можно использовать функцию __autoload().
1.1 Файлы лежат в одной директории
Создадим файл user.php:
<?php class User { public function __construct() { echo 'Created User'; } }
Допустим, что данный класс мы хотим использовать в файле autoload_func.php:
<?php <?php error_reporting(E_ALL); ini_set('display_errors', 1); function __autoload($class) { require_once strtolower($class) . '.php'; } new User();
При этом эти два файла расположены в одной директории.
При запуске скрипта autoload_func.php класс User будет загружен автоматически. Нам не пришлось в файле autoload_func.php писать вручную включение файла: require_once 'user.php';. Также, если мы в этом файле обратимся к друкому классу, к примеру new Company(), то благодаря __autoload() интерпретатор php постарается включить файл company.php, в котором должен располагаться класс Company.
1.2 Файлы лежат во вложенных директориях
<?php class Account { public function __construct(){ echo 'Account created.'; } }
Структура файлов выглядит так:
.
├── autoload_func.php
├── bank
│ └── account.php
└── user.php
Получается, что нужно php сообщить, что поиск файлов нужно осуществлять еще и в директории bank:
<?php error_reporting(E_ALL); ini_set('display_errors', 1); set_include_path('.'); set_include_path(get_include_path() . PATH_SEPARATOR . './bank' ); function __autoload($class) { //Перечисляем пути поиска классов относительно //текущего файла, где расположена эта ф-ция $path_arr = array( '.', 'bank' ); foreach ($path_arr as $path) { $file_path = $path.DIRECTORY_SEPARATOR.strtolower($class).'.php'; if (file_exists($file_path)) { include_once $file_path; } } } new User(); new Account();
В этом случае при попытке создать класс Account php приводит имя файла к нижнему регистру - account.php и проверяет его наличие сначала в текущей директории, затем в директории bank. Если файл существует, то он будет включен. Однако, это неверно, т.к. в папке bank может тоже быть файл с именем user.php, характеризующий пользователя банка. Из-за этого мы получим ошибку:
Fatal error: Cannot redeclare class User
Этой ошибки не возникнет, если в вашем проекте используются классы с уникальными названиями.
2. Функция spl_autoload_register()
Она предназначена для автозагрузки файлов используемых классов. Для примера 1.2. код с ее использованием выглядит так:
<?php error_reporting(E_ALL); ini_set('display_errors', 1); $path_arr = array( '.', 'bank' ); foreach ($path_arr as $path) { set_include_path(get_include_path(). PATH_SEPARATOR . $path); } spl_autoload_register(function($class) { include_once strtolower($class) . '.php'; }); new User(); new Account();
И снова, если имена классов не будут уникальны, возникнет ошибка: Fatal error: Cannot redeclare class ***.
Однако плюсом использования этой функции является отсутствие необходимости проверять наличие файла перед его загрузкой. Здесь мы просто посредством set_include_path() добавляем к include_path новые пути, а функция автозагрузки уже сама позаботится о включении нужных файлов.
Удобочитаемые имена загружаемых файлов
До сих пор мы обсуждали функции автозагрузки, которые поддерживали загрузку только таких файлов: bankuser.php, bankusercomment.php. Такие имена сложно читать, поэтому функцию автозагрузки нужно изменить, чтобы она стала работать с такими файлами: bank_user.php, bank_user_comment.php.
Чтобы это сделать, нужно придумать, как преобразовать строку имени класса "BankUserComment" в "bank_user_comment".
<?php error_reporting(E_ALL); ini_set('display_errors', 1); $path_arr = array( '.', 'bank' ); foreach ($path_arr as $path) { set_include_path(get_include_path(). PATH_SEPARATOR . $path); } spl_autoload_register(function($class) { include_once strtolower( ltrim( preg_replace('/[A-Z]/', '_$0', $class), '_' ) ) . '.php'; }); new User(); new Account(); new BankUser();
В этом случае вы можете файл называть bank_user_comment.php, а класс в нем так: BankUserComment.
Разумеется, если вас устраивает, что файлы будут называться так: BankUserComment.php, то в функции автозагрузки нужно просто удалить преобразование имени к нижнему регистру - strtolower().
Комментариев нет:
Отправить комментарий