Автоматическая загрузка объектов
Большинство разработчиков объектно-ориентированных приложений создают для каждого определения класса отдельный файл с кодом PHP. Одной из самых больших неприятностей в этом случае является необходимость писать в начале каждого скрипта длинный список подгружаемых файлов.
Если используется PHP 5, то делать это не обязательно. Вы можете определить функцию __autoload, которая автоматически вызывается в том случае, когда вы пытаетесь использовать класс, который не был определен ранее. Вызов этой функции - это последний шанс для интерпретатора загрузить класс прежде, чем он закончит выполнение скрипта с ошибкой.
Замечание: Исключения, вызванные в функции __autoload, не могут быть перехвачены в блоке catch и завершатся с неисправимой ошибкой.
Замечание: Автоматическая загрузка не доступна в случае использования PHP в командной строке в интерактивном режиме.
Замечание: Если имя класса используется, например, для вызова через call_user_func(), то оно может содержать некоторые опасные символы, такие как ../. Поэтому, рекомендуется не использовать данные от пользователей в таких функциях или же, как минимум, проверять значения в __autoload().
Пример #1 Пример автоматической загрузки
В этом примере функция пытается загрузить классы MyClass1 и MyClass2 из файлов MyClass1.php и MyClass2.php соответственно.
<?php
function __autoload($class_name) {
require_once $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
- Введение
- Основы
- Свойства
- Константы классов
- Автоматическая загрузка классов
- Конструкторы и деструкторы
- Область видимости
- Наследование
- Оператор разрешения области видимости (::)
- Ключевое слово "static"
- Абстрактные классы
- Интерфейсы объектов
- Трейты
- Anonymous classes
- Перегрузка
- Итераторы объектов
- Магические методы
- Ключевое слово "final"
- Клонирование объектов
- Сравнение объектов
- Контроль типа
- Позднее статическое связывание
- Объекты и ссылки
- Сериализация объектов
- Журнал изменений ООП
Коментарии
Because static classes have no constructor I use this to initialize such classes.
The function init will (if available) be called when you first use the class.
The class must not be included before, otherwise the init-function wont be called as autoloading is not used.
<?php
function __autoload($class_name)
{
require_once(CLASSES_PATH.$class_name.'.cls.php');
if(method_exists($class_name,'init'))
call_user_func(array($class_name,'init'));
return true;
}
?>
I use it for example to establish the mysql-connection on demand.
It is also possilbe do add a destructor by adding this lines to the function:
<?php
if(method_exists($class_name,'destruct'))
register_shutdown_function(array($class_name,'destruct'));
?>
You should not have to use require_once inside the autoloader, as if the class is not found it wouldn't be trying to look for it by using the autoloader.
Just use require(), which will be better on performance as well as it does not have to check if it is unique.
It's worth to mention, if your operating system is case-sensitive you need to name your file with same case as in source code eg. MyClass.php instead of myclass.php
This is my autoloader for my PSR-4 clases. I prefer to use composer's autoloader, but this works for legacy projects that can't use composer.
<?php
/**
* Simple autoloader, so we don't need Composer just for this.
*/
class Autoloader
{
public static function register()
{
spl_autoload_register(function ($class) {
$file = str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
if (file_exists($file)) {
require $file;
return true;
}
return false;
});
}
}
Autoloader::register();
Autoloading plain functions is not supported by PHP at the time of writing. There is however a simple way to trick the autoloader to do this. The only thing that is needed is that the autoloader finds the searched class (or any other autoloadable piece of code) from the files it goes through and the whole file will be included to the runtime.
Let's say you have a namespaced file for functions you wish to autoload. Simply adding a class of the same name to that file with a single constant property is enough to trigger the autoloader to seek for the file. Autoloading can then be triggered by accessing the constant property.
The constant could be replaced by any static property or method or by default constructor. However, I personally find a constant named 'load' elegant and informative. After all this is a workaround. Another thing to keep in mind is that this introduces an unnecessary class to the runtime. The benefit of this is that there is no need to manually include or require files containing functions by path which in turn makes code maintaining easier. Such behaviour makes it easier to alter the project structure since manual includes need not to be fixed. Only the autoloader needs to be able to locate the moved files which can be automated.
A code file containing functions.
/Some/Namespace/Functions.php
<?php
namespace Some\Namespace;
class Functions { const load = 1; }
function a () {
}
function b () {
}
?>
Triggering autoloading of the file containing functions.
main.php
<?php
\Some\Namespace\Functions::load;
a ();
b ();
?>