Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

PHP: Classloader per __autoload

Empfohlene Antworten

Veröffentlicht

Hi Leute,

ich bin grad ein bisschen am tüfteln mit netten php5 funktionalitäten :P

Wenn ich jetzt eine funktion definiere:


function __autoload($classname) {
require_once($classname . '.class.php');
}
[/PHP]

Das ganze funktioniert jetzt aber nur wenn ich alle Klassen im selben Verzeichnis liegen habe ...

Jemand ne idee wie man eine schnelle methode findet klassen automatisch zu laden? Ich könnte das ganze ja mit opendir() etc. machen aber das dürfte das script ja doch um einiges verlangsamen ... gibts da ne Möglichkeit oder sollte ich dann im Endeffekt doch lieber mit ganz normalen requires bzw. require_onces arbeiten?

mfg

Eth

Also, die Funktion __autoload() ist eigentlich dafür gedacht, dass eine benötigte Klasse nur bei Bedarf geladen wird. Wenn du sowieso bei deinem Webprojekt immer Zugriff auf alle deine Klassen haben musst, ist die Variante per require() besser.

Solltest du aber eine Sammlung von Klassen (in einzelnen Dateien in einem Ordner) haben, und du brauchst mal diese und mal jene Klasse, ist die Funktion __autoload() von Vorteil. Wenn du in deinem Script eine Instanz einer Klasse erzeugen willst, und diese Klasse ist noch nicht deklariert, wird die Funktion __autoload() aufgerufen. Als Parameter enthält sie den Klassennamen. Dann kann man per include() oder require() die entsprechende Datei laden. Danach wird PHP automatisch versuchen, die Instanz erneut zu erstellen.

Beispiel:


<?
function __autoload($classname) {
include($classname."class.php");
}

$link = new DB_Klasse;
?>[/PHP]

Hier wird zuerst die Datei "DB_Klasse.class.php" eingebunden und dann wird versucht eine Instanz von DB_Klasse zu erzeugen. Sollte in der eingebundenen Datei nicht die Klasse DB_Klasse vorhanden sein, wird natürlich ein Fehler erzeugt.

Ich hoffe mal, dass ich dir damit ein wenig helfen konnte.

// ssambdar

Das ganze funktioniert jetzt aber nur wenn ich alle Klassen im selben Verzeichnis liegen habe ...

ini_set("include_path", ".:/mein/absoluter/pfad/zu/den/klassen/und/ihren/subordnern:/noch/ein/include/pfad:/und/noch/einer");

Falls du es nicht zur Laufzeit definieren willst, so kannst du es natürlich auch fest in der php.ini aufschreiben.

Dann findet __autoload auch Klassen aus anderen Verzeichnissen. ;)

Hm ... also prinzipiell gesehen werden an sich schon alle klassen benötigt.

Wobei mich die ganzen requires allerdings ziemlich nerven *gg*

Ich schau mal wie ich das am sinnigsten löse ...

Danke für die Antworten :)

Hm ... also prinzipiell gesehen werden an sich schon alle klassen benötigt.

Also selbst wenn du wirklich alle Klassen brauchst, und die Abhängigkeiten verstreut sind, dann würde ich dir wirklich zu __autoload raten.

Ich sehe keinen besonderen Grund warum man ein statisches require dem dynamischeren __autoload vorziehen sollte.

Wenn man alle requires per Hand aufschreibt schleichen sich imo viel eher Fehler ein (z.B.) Reihenfolge als wenn du sie dynamisch lädst.

Jetzt stellt sich allerdings wieder die Frage wie ich meine dynamischen includes am sinnvollsten einbinde...

wenn ich require_once o. Ä. benutze, werden dann auch unterverzeichnisse des include_path durchsucht oder muss ich jedes verzeichnis separat spezifizieren? Nicht dass es ein Problem ist... :P

mfg

Eth

Hab mir da grad ma was nettes gebaut ^^:


<?php

class ClassLoader {

private static $pathInitialized = false;

public static function autoLoad($classname) {

if ( !self :: $pathInitialized ) {
self :: initializePath();
}

self :: loadClass($classname);
}

private static function initializePath() {
$currentIncludePath = ini_get('include_path');
$includePaths = explode(':',$currentIncludePath);

$libDir = realpath(realpath(dirname(__FILE__) . '/../'));

$dirTree = self :: buildDirTree($libDir);

foreach ( $includePaths as $includePath ) {
if ( !in_array($includePath,$dirTree) ) {
array_unshift($dirTree,$includePath);
}
}

$includePathComplete = implode(':',$dirTree);

ini_set('include_path',$includePathComplete);

self :: $pathInitialized = true;
}

private static function buildDirTree($dir) {
$dirList = array();

$dirHandle = opendir($dir);

while ( $currentDir = readdir($dirHandle) ) {
$fullCurrentDir = $dir . '/' . $currentDir;

if ( is_dir($fullCurrentDir) && $currentDir!='.' && $currentDir!='..' ) {
$dirList[] = $fullCurrentDir;
$dirContent = self :: buildDirTree($fullCurrentDir);
foreach ( $dirContent as $dirContentEntry ) {
$dirList[] = $dirContentEntry;
}
}
}

return $dirList;
}

private static function loadClass($classname) {
require_once($classname . '.class.php');
}

}

function __autoload($classname) {
ClassLoader :: autoLoad($classname);
}

?>

[/PHP]

So kann mans natürlich auch machen... :rolleyes:

Ich schreib lieber einmal meinen Path auf, anstelle ihn immer dynamisch generieren zu lassen, aber jedem das seine. :)

Naja muss ich mal schauen. Das Aufschreiben ist mit Sicherheit um einiges schneller als das Generieren bei jedem Aufruf. Allerdings muss ich dann ja den Pfad jedes Mal ändern. hmm.

Vielleicht sollte ich mir ja nen packetmanager basteln *gg*

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.