spl_autoload_register() functie

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Donald Boers

Donald Boers

08/07/2018 15:39:35
Quote Anchor link
Ik heb het volgende in mijn auto_loader functie staan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php

function auto_loader($file)
{

    $file = APP_PATH . '/includes/classes/' . str_replace('_', '/', $file) . '.php';
    if (file_exists($file)) {
        require_once $file;
    }
}

    
spl_autoload_register('auto_loader');
?>

Ik wil echter ook een aantal globale variabelen toevoegen i.e.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$root_path
  = $_SERVER['DOCUMENT_ROOT'];
$style_path = $root_path . '/css';
?>

Kan ik deze gewoon zo op deze manier na de if() statement gebruiken of vraagt dit om een bepaalde benadering. En zijn ze wanneer ik ze aan de auto_loader file toevoeg beschikbaar in al mijn classes?

Alvast bedankt
Gewijzigd op 08/07/2018 15:56:47 door - Ariën -
 
PHP hulp

PHP hulp

17/08/2018 01:55:24
 
Thomas van den Heuvel

Thomas van den Heuvel

08/07/2018 17:09:37
Quote Anchor link
Ik denk dat je hier teveel zaken wilt combineren. Zaken die eigenlijk op verschillende plekken thuishoren en die je dus allereerst zult moeten splitsen, daarna kun je deze ook weer handig combineren.

Ten eerste, ik geloof dat het de moeite loont om bij voorkeur spl_autoload() als autoload-implementatie te gebruiken. Wat deze functie doet is alle include paths op volgorde van declaratie aflopen (hoe we hier nog slimmer gebruik van kunnen maken volgt verderop) en zoekt hierin naar lowercase bestandsnamen (die gelijk zijn aan de classname) met (standaard) de extensies .inc of .php.

Het (hard) coden van je paden in de autoloader is dus niet nodig (en ook niet echt verstandig), zolang je zorgt dat het root-pad naar je classes in je include path lijst zit worden deze bestanden gevonden.

Wat je achtereenvolgens moet doen wordt in de eerste user contributed note beschreven. Heel vaak staan er best handige ideeën tussen dus ik zou ook altijd deze even doornemen als je daar de tijd voor hebt.

Dan heb je het over paden die je altijd en overal beschikbaar wilt hebben.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$root_path  = $_SERVER['DOCUMENT_ROOT'];

Ik zou gewoon rechtstreeks van $_SERVER['DOCUMENT_ROOT'] gebruik maken, en niet van een alias, tenzij "$root_path" hier van af kan wijken.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$style_path = $root_path . '/css';

Dit lijkt mij niet kloppen, want CSS-bestanden worden nooit via het interne pad (DOCUMENT_ROOT) aangesproken?

Anyhow, als je overal dit soort paden tot je beschikking wilt hebben, definieer deze gewoon als constanten, mogelijk afhankelijk van $_SERVER['SERVER_NAME'], dit om je website portabel te houden.

En dan nog een truuk met include paden. Stel je hebt een standaard zwik functionaliteit aan classes die je bijvoorbeeld allemaal onder een pad MY_LIBRARY_PATH hebt staan. En stel dat je wel eens af wilt wijken van de standaard werking van deze classes, maar daarbij wil je geen aanpassingen verrichten in je "core" classes. Je zou dan een tweede pad MY_APPLICATION_PATH kunnen instellen. Dit zorgt er dan voor dat de class eerst gevonden wordt in MY_APPLICATION_PATH als hier een mod voor is, nog voordat geprobeerd wordt de standaard implementatie te laden uit de library. Zo heb je dus meteen op een makkelijke manier "class overrides".

Daarnaast lijkt het mij verstandig om een switch-statement op grond van $_SERVER['SERVER_NAME'] te maken, vooral als je verschillende servers gebruikt voor deze website (wat eigenlijk altijd het geval zou zijn - minimaal 1 aparte ontwikkelomgeving en 1 aparte productieomgeving). De paden die je in de cases definieert (d.m.v. constanten) mogen best uitgeschreven zijn, deze liggen namelijk per server vast tenzij je fysiek met andere bestanden gaat schuiven.

Een voorbeeld. De volgende zaken zouden in aparte bestanden/onderdelen ondergebracht moeten worden.

#1 definiëren van server-specifieke constanten:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
switch ($_SERVER['SERVER_NAME']) {
    case 'development.local':
        // wellicht ook handig, de locatie van je config-bestand, wat een Config object creeert
        // dit is mogelijk ook het enige bestand dat je dient te require-n, omdat je anders
        // in allerlei kip-ei situaties terecht komt
        define('MY_CONFIG_FILE', 'D:/local/machine/path/to/config/config.php');
        // applicatiepad met afwijkende "core" bestanden
        define('MY_APPLICATION_PATH', 'D:/local/machine/path/to/application');
        // pad van je class library
        define('MY_LIBRARY_PATH', 'D:/local/machine/path/to/library');
    break;

    case 'production.server.com':
        define('MY_CONFIG_FILE', '/home/user/domains/production.server.com/config/config.php');
        define('MY_APPLICATION_PATH', '/home/user/domains/production.server.com/application');
        define('MY_LIBRARY_PATH', '/home/user/domains/production.server.com/library');
    break;

    default:
        die('unknown host');
}
?>


#2
Het instellen van het include path. Hier is volgorde belangrijk, allereerst applicatiepad (voor overrides), dan het library pad (voor je core classes), en dan de rest als voorheen (middels get_include_path()):
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
set_include_path(MY_APPLICATION_PATH.PATH_SEPARATOR.MY_LIBRARY_PATH.PATH_SEPARATOR.get_include_path());
?>


#3
Een minimale autoloader met gebruikmaking van spl_autoload():
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
function my_autoloader($class) {
    spl_autoload(strtr($class, '_', DIRECTORY_SEPARATOR));
}

spl_autoload_register('my_autoloader');
?>

Of rechtstreeks als anonieme functie (PHP >=5.3.0)
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
spl_autoload_register(function ($class) {
    spl_autoload(strtr($class, '_', DIRECTORY_SEPARATOR));
});

?>

En dat is alles! Bovenal lijkt het mij verstandig je autoloader zo simpel en lichtgewicht mogelijk te houden.
Gewijzigd op 08/07/2018 17:48:02 door Thomas van den Heuvel
 
Donald Boers

Donald Boers

11/07/2018 12:30:57
Quote Anchor link
@ Thomas

Hallo Thomas. Hartelijk bedankt voor je zeer gedetailleerde uitleg. Erg verhelderend en zeer zeker de moeite van het overdenken waard. Ik ga me hier zeker in verdiepen.
Quote:
Dit lijkt mij niet kloppen, want CSS-bestanden worden nooit via het interne pad (DOCUMENT_ROOT) aangesproken?

Anyhow, als je overal dit soort paden tot je beschikking wilt hebben, definieer deze gewoon als constanten, mogelijk afhankelijk van $_SERVER['SERVER_NAME'], dit om je website portabel te houden.

Dat van de css folder was meer om een voorbeeld te geven, ik had waarschijnlijk beter de afbeeldingen folder als voorbeeld kunnen gebruiken omdat deze in de CMS nogal vaak wordt aangeroepen.

Voor nu heb ik inderdaad maar voor het gebruik van constanten gekozen. Nogmaals hartelijk bedankt.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.