Standard PSR-4
Celem ujednolicenia nazewnictwa stosowanego w bibliotekach wprowadzono standard PSR-4 (PSR oznacza PHP Standards Recommendation).
Standard PSR-4 określa zalecaną strukturę kodu, którą musi stosować aplikacja lub biblioteka, aby zagwarantować poprawne działanie autoloadera. Podstawowym wymaganiem jest definicja przestrzeni nazw zgodnie ze schematem:
\<Vendor Name>\( <Namespace> )*\<Class Name>
- Obszary nazw mogą mieć tyle poziomów zagnieżdżenia, ile potrzeba, ale Nazwa dostawcy (Vendor Name) powinna być przestrzenią nazw najwyższego poziomu.
- Przestrzenie nazw powinny być odwzorowane na strukturę katalogów. Każdy ukośnik w definicji przestrzeni nazw (
\
) jest w procesie ładowania plików konwertowany na stałą systemowąDIRECTORY_SEPARATOR
specyficzną dla systemu operacyjnego. - Uzyskana w powyższy sposób nazwa jest uzupełniana rozszerzeniem .php aby uzyskać nazwę pliku w którym zdefiniowano klasę..
Na przykład dla klasy Dostawca\Biblioteka\Klasa
należy stworzyć następującą strukturę katalogów:
/Dostawca
/Biblioteka
Klasa.php
Ten sposób przekładania przestrzeni nazw na nazwę pliku został wprowadzony w standardzoe PSR-0. nazw plików Co jednak zrobić, jeśli chcemy na rzykład aby w katalogu /Dostawca/Biblioteka pojawił się podkatalog src, a w nim dopiero moduły? To właśnie definiuje standard PSR-4. Wprowadza on powiązania prefiksu ścieżki z nazwą (przestrzenią nazw).
Na przykład tak (fragment pliku composer.json):
"autoload": {
"psr-4": {
"Application\\": "module/Application/src/"
}
},
Teraz autoloader będzie wiedział, że definicję klasy \Application\Module znajdzie w pliku module/Application/src/Module.php.
Przykład autoloadera dla projektu Zend Framework (bez mapy klas tworzonej przez Composera)
<?php
// "Standard" autoloader function.
function standardAutoloadFunc($className)
{
// Replace the namespace prefix with base directory.
$prefix = '\\Zend\\Mvc';
$baseDir = '/path/to/zendframework/zend-mvc/src/';
if (substr($className, 0, strlen($prefix)) == $prefix) {
$className = substr($className, strlen($prefix)+1);
$className = $baseDir . $className;
}
// Replace namespace separators in class name with directory separators.
$className = str_replace('\\', DIRECTORY_SEPARATOR, $className);
// Add the .php extension.
$fileName = $className . ".php";
// Check if file exists and is readable.
if (is_readable($fileName)) {
// Include the file.
require $fileName;
}
}
// Register the autoloader function.
spl_autoload_register("standardAutoloadFunc");
Ten autoloader sprawdza po kolei podkatalogi w poszukiwaniu miejsca położenia modułu. Jest to oczywiście rozwiązanie wolniejsze niż niż autoloader z mapą klas. Jednak w trakcie opracowywania nowego kodu dla aplikacji może to być wygodniejsze.