autoload: hoe doet php dat?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Marc Cools

Marc Cools

09/12/2008 23:18:00
Quote Anchor link
Stel je hebt de volgende code:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$appl
= new Application();
$appl->user = new User();
?>

Bij de creatie van Application-object treed de autoload in werking. Het laat het bestand met de php code in het geheugen zodat die kan uitgevoerd worden.
Is de werking van dat autoloaden zoiets als requere_once? Dus dat de code op die exacte plaats ingesloten wordt. Of is het toch nog anders?
Dit is dus een zeer technische vraag. Immers bij het laden van het User object is dit in de __set functie van de instantie van het Application object.

Dus wie kan mij eens exact uitleggen wat het autoloaden exact inhoud.

Thanks :)
Gewijzigd op 01/01/1970 01:00:00 door Marc Cools
 
PHP hulp

PHP hulp

22/11/2024 02:37:04
 
Rens nvt

Rens nvt

09/12/2008 23:59:00
Quote Anchor link
@Marc: autoloading is niets... PHP laadt geen classe in op het moment dat ze niet bestaan... De manual zegt het volgende: " Many developers writing object-oriented applications create one PHP source file per-class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).

In PHP 5, this is no longer necessary. You may define an __autoload function which is automatically called in case you are trying to use a class/interface which hasn't been defined yet. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error. "

Oftewel, je krijgt de KANS om ZELF een functie te schrijven, die wordt aangeroepen als je een instance aanmaakt van een class die nog niet gedefinieerd is.

Stel, je hebt 3 mappen waarin je class files hebt staan, en je hebt een nette stijl waarin je al je documenten de volgende naam geeft: <class>.class.php (bijvoorbeeld).
Je kunt dan het volgende doen:

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
<?php
function __autoload($name)
{

  $dirs = array('classes', 'classes2', 'classes3');
  foreach ($dirs as $dir)
  {

    if (is_file($dir . '/' $name . '.class.php'))
    {

      require_once($dir . '/' . $name . '.class.php');
      return;
    }
  }
}


$user = new User();
?>


Als je nu een bestand 'classes3/User.class.php' hebt, die de class User definieert, zal alles gewoon werken.

Let op, dit is ter illustratie. Je bepaald dus helemaal zelf wat er gedaan wordt binnen je autoload.
 
Arian Stolwijk

Arian Stolwijk

10/12/2008 00:27:00
Quote Anchor link
Het is handig dat je dan je classes op de manier zoals bij het Zend Framework / PEAR structureert. Dus bijvoorbeeld:
Db_Table_Row hoort bij Db/Table/Row.php.

met dit kan je dan makkelijk je bestanden includen.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php

function __autoload($class){
    include_once str_replace('_','/',$class).'.php';
}


?>
 
Marc Cools

Marc Cools

10/12/2008 13:38:00
Quote Anchor link
@Rens

Ik was blijkbaar niet duidelijk genoeg.
Ik heb zo 'n autoload functie die de class van de juiste plaats ophaalt.

Maar waar staat die code in de 'sequentie' van de codes.
Bij include staat het daar waar include staat.

Kijkt de php parser eerst naar welke classes er gebruikt worden en via de autoload inlude het deze voor de hoofdcode start? Zet het in een appart geheugenblok en niet sequentieel tussen de andere php code. En wat met
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
<?php $obj = new $request ?>
of met
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
<?php if( TIME_CLASS::WorkingDay() ) {doSomething();} ?>
waarbij TIME_CLASS dan pas eerst (via __autoload) geladen wordt.

Dus waar staat *fysiek* die included code voor de classes?

@Arian

Zeer handige tip!
Geen ini gedoe.
 
Rens nvt

Rens nvt

10/12/2008 13:48:00
Quote Anchor link
@Marc: Het lijkt mij dat PHP niet opeens de parse volgorde aangepast heeft... Dus ik ga er vanuit dat de include gedaan wordt op het moment dat de class geinitieerd moet worden, en dat er niet eerst gekeken wordt welke extra classes er aangeroepen moeten worden. Dit zou namelijk 2 keer parsen betekenen... (je weet pas na het parsen welke classes nodig zijn).

Mag ik vragen waarom dit nodig is om te weten? Gewoon achtergrondkennis? Of denk je tegen een probleem aan te lopen?
 
Marc Cools

Marc Cools

10/12/2008 14:41:00
Quote Anchor link
@Rens

Ik wil dat autoloaden goed begrijpen.
Include is simpel: zet hier code uit dat bestand neer. Hier dus. De volgorde van uitvoering is gekend.

stel de volgende code:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
//file time_class.php
class TIME_CLASS{
    public function WorkingDay(){
        return true;
    }
}


//file index.php
if( TIME_CLASS::WorkingDay() ) {
    doSomething();
}

?>

Bij het verwerken *zou* het kunnen zijn dat hij de regel met de if leest, interpreteerd en vaststeld dat hij via __autoload eerst de class code moet includen. We krijgen dan:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
//verwerkte index.php
class TIME_CLASS{
    public function WorkingDay(){
        return true;
    }
}

if( TIME_CLASS::WorkingDay() ) {
    doSomething();
}

?>
Niets aan de hand dus.
Maar als die if nu in een functie zit of in een andere class staat. Hoe zit het dan met de scoop van die 'included' class?

Het is dus zoals ik al stelde een *technische* vraag.

Vergelijk het met de werking van de stack en de heap waar variabelen in worden opgeslagen. Hoe maakt php verschil tussen een locale $a en een niet locale $a? Als je een functie gebruikt dan wordt als het ware een lijn getrokken in de stack en daar volgen dan de locale variabelen. Uw functie kan niet voorbij die lijn gaan. Wil je dat wel dan moet je 'global' gebruiken om een referentie naar de variabele aan de andere kant van de lijn te krijgen. Als de functie gedaan is dan word de stack 'gewist' tot aan de lijn.
Dus zo werkt technisch de scoop van variabelen. En is dat ook de reden waarom niet locale variabelen niet beschikbaar zijn, vanwege die 'lijn' dus. Andere talen kunnen dat anders behandelen en is de scoop dus ook anders. Zoals buiten de functie gedeclareerd is binnen de functie wel bruikbaar.

Maar mischien moet ik mij dit allemaal niet afvragen en gewoon aannemen dat het werkt.
...Toch maar niet, ik weet het gewoon graag zodat ik het ten volle begrijp.

;)
 
--

--

10/12/2008 16:39:00
Quote Anchor link
..
Gewijzigd op 01/01/1970 01:00:00 door --
 
Marc Cools

Marc Cools

10/12/2008 18:00:00
Quote Anchor link
@Evert,

Het stukje onderaan had niets met klassen te maken maar gewoon hoe de stack werkt als je bijvoorbeeld een simpele variabele wel of niet in een functie declareert.

Op je reactie over het laden van de klassen met autoload:

<b>*Waar* staat de code van Class1 *nadat* het geladen is?</b>

Op regel 4 ?
Voor regel 12?
In de heap?
Nog een andere locatie?

Waar, waar, waar, waar staat het?
 
Jelmer -

Jelmer -

11/12/2008 17:04:00
Quote Anchor link
Doet het er echt toe? Classes & functies zijn in PHP nu nog altijd globaal. Wanneer je een class binnen een functie definieert, bestaat hij ook daarbuiten. Hetzelfde geldt voor functies en constanten. Alleen variabelen zijn niet automatisch (of ik zou eerder zeggen "per definitie") globaal.

Wanneer je __autoload (of de functie die jij als callback hebt opgegeven) aanroept include deze dat bestand. Alle "globale" variabelen binnen dat bestand, welken dus niet binnen een functie stonden maar ook geen superglobals zijn, staan nu in de scope van de autoload-functie. Dat lijkt mij de enige logische plek waar je ze kan verwachten.
Gewijzigd op 01/01/1970 01:00:00 door Jelmer -
 



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.