Ich nutze nahezu immer PSR-0 beziehungsweise PSR-4, was im Grunde bedeutet: Ein Namespace (oder Sub-Namespace) ist an ein beliebiges Verzeichnis gekoppelt, und die Klassen (oder Sub-Namespaces) darin folgen dann einem festen 1:1-Mapping von Sub-Namespaces/Klassennamen auf die Verzeichnisstruktur.
-
http://www.php-fig.org/psr/psr-0/
-
http://www.php-fig.org/psr/psr-4/
Du könntest also zum Beispiel eine Klasse Foo\Bar\Baz\Blub haben, die in ./classes/Baz/Blub.php liegt, und im Autoloader den Namespace-Teil Foo\Bar nach ./classes mappen.
Ich würde einen Autoloader heutzutage nicht mehr selbst schreiben, ich würde empfehlen, dazu Composer zu nutzen.
-
https://getcomposer.org/
Beispiel für eine Projektstruktur:
Code:
.
|-- src
| |-- AbstractCRC.php
| |-- CRC16CCITT.php
| |-- CRC16DNP.php
| |-- CRC16Modbus.php
| |-- CRC16.php
| |-- CRC16XModem.php
| |-- CRC1.php
| `-- CRCInterface.php
|-- composer.json
`-- test.php
In test.php soll nun ein Autoloader für die Klassen aus ./src genutzt werden können (die liegen alle in
namespace mermshaus\CRC;).
Dazu schreibst du in composer.json:
Code:
{
"autoload": {
"psr-4": {
"mermshaus\\CRC\\": "src"
}
}
}
Dann rufst du Composer im Projektverzeichnis auf:
Code:
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
Das erstellt ein ./vendor-Verzeichnis:
Code:
.
|-- src
| |-- AbstractCRC.php
| |-- CRC16CCITT.php
| |-- CRC16DNP.php
| |-- CRC16Modbus.php
| |-- CRC16.php
| |-- CRC16XModem.php
| |-- CRC1.php
| `-- CRCInterface.php
|-- composer.json
|-- test.php
`-- vendor
|-- autoload.php
`-- composer
|-- autoload_classmap.php
|-- autoload_namespaces.php
|-- autoload_psr4.php
|-- autoload_real.php
`-- ClassLoader.php
In test.php kann nun ./vendor/autoload.php eingebunden werden:
PHP:
require __DIR__ . '/vendor/autoload.php';
Fertig.
Wenn sich an der Namespace-/Verzeichnisstruktur etwas ändert, einfach wieder
$ composer update ausführen.
Composer unterstützt auch andere Ansätze für Autoloading:
-
https://getcomposer.org/doc/04-schema.md#autoload
Der enthaltene Classmap-Generator ist etwa richtig gut, falls du Classmaps, also hinterlegte 1:1-Zuordnungen beliebiger, exakter Pfade zu Klassennamen, nutzen willst.
Composer kann außerdem dazu natürlich noch externe Abhängigkeiten in das Projekt einbinden.
Veränderte composer.json-Datei:
Code:
{
"license": "MIT",
"autoload": {
"psr-4": {
"mermshaus\\CRC\\": "src"
}
},
"require": {
"kaloa/filesystem": "dev-master",
"kaloa/renderer": "dev-master",
"rkr/recursive-array-accessor": "2.0.*"
}
}
Code:
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing kaloa/filesystem (dev-master d780c0c)
Cloning d780c0cd7b12c43e7b318a2a08416c24849083a8
- Installing kaloa/renderer (dev-master d7dcbaa)
Cloning d7dcbaa40258a8675f44cc9e9ce8e83f0a8b2a4a
- Installing rkr/recursive-array-accessor (2.0.0)
Loading from cache
Writing lock file
Generating autoload files
Jetzt kann in test.php etwa das hier stehen:
PHP:
<?php
require __DIR__ . '/vendor/autoload.php';
$markdownRenderer = \Kaloa\Renderer\Factory::createRenderer(null, 'markdown');
echo $markdownRenderer->render('# Hallo Welt
[Ein Link](http://www.example.org/)');
// Ausgabe:
// <h1>Hallo Welt</h1>
//
// <p><a href="http://www.example.org/">Ein Link</a></p>
Man beachte, wie sich Composer um sämtliche Details gekümmert hat.
Dankenswerterweise ist Autoloading/Dependency-Management ein gelöstes Problem.
Auch Pakete, die nicht explizit mit Composer zusammenarbeiten, kannst du mit Composer reinziehen.
Code:
{
"repositories": [
{
"type": "package",
"package": {
"name": "geshi/geshi",
"version": "1.0.8",
"dist": {
"url": "https://github.com/GeSHi/geshi-1.0/archive/c5329d9b39a3e07f2745d1f1dbb3d389657c01e7.zip",
"type": "zip"
},
"autoload": {
"classmap": ["src/"]
}
}
}
],
"require": {
"geshi/geshi": "1.0.*"
}
}
Das würde etwa dieses GeSHi holen (per Zip-Archiv-Download) und autoloadbar machen:
-
https://github.com/GeSHi/geshi-1.0
Composer generiert dabei automatisch diese Classmap und integriert sie in den Autoloader:
PHP:
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'GeSHi' => $vendorDir . '/geshi/geshi/src/geshi.php',
);
(Ist jetzt nicht so spektakulär, weil GeSHi nur aus einer Klasse besteht.)
Jedenfalls: Composer ist ein sehr sehr empfehlenswertes Tool.
Edit: Eine Sache noch: Du kannst das, was Composer zusammengesteckt hat, dann einfach auf den Webserver laden. Du hast alle Daten und Sources vorliegen und das ist alles normaler PHP-Code. Es hat keinen Vorteil, die Composer-Software selbst auf dem Zielsystem nutzen zu können. Das ist etwa anders als bei PEAR, wo die Packages in der Regel global auf dem Zielsystem verfügbar sein müssen. Ein
„composed“ Projekt ist da vollkommen autark und liefert alles hübsch selbst mit.
Ach ja, das zentrale Repository für Composer-Pakete ist Packagist:
-
https://packagist.org/