Ik heb diverse child classes in diverse files
Ook heb ik diverse parrent classes ook in diverse files
Als ik nu dus bv een file require, met een class die gebruik maat van een parrent class, maar die file met die parrent class is nog nog niet toegevoegd middels een require, dan krijg ik gelijk toch al een error.
Ik vind dit vreemd omdat ik van die child class nog helemaal geen instantie van heb aangemaakt.
Wie kan mij dit gedrag een beetje uitleggen opdat ik dit kan begrijpen waarom ik dus toch die error krijg ondanks dat er geen instantie van de child class is aangemaakt nog.
Ok, dus er word een soort van voorcontrole gedaan?
Vind ik wel jammer, want ik krijg zo dus een fout terwijl als ik op een later moment de parrent class nog wel require, voordat ik dus wel een instantie aanmaak van de child class het dus goed zou kunnen werken.
Eigenlik zou ik dus een fout verwachten als ik de child class ga instantieren, en als de parrent clas dan niet gevonden zou worden.
Nu moet ik dus zorgen dat alle parrent classes dus echt eerst geladen worden voordat ik een class require die een parrent class extend.
Ik raad je aan eens naar een [php]spl_register_autoloader[/php] te kijken, of naar de magic __autoload() functie in PHP. Hiermee kun je een functie opzetten die, mocht de klasse nog niet gerequired zijn, de klasse alsnog required.
Ik werk volledig ook met namespaces, en hiermee is het mij niet gelukt een goed werkende autoload functie te kunnen opzetten.
Ik heb dus uiteindelijk maar besloten om alles wat ik nodig heb gewoon echt via require in te laden.
Ik gebruik ook geen require_once omdat ik exact weet waar ik wat nodig heb, en dan ook de juiste classes require die nodig zijn.
Ik werk ook volledig met namespaces, en dan lukt het perfect. Zorg dat je namespaces en de locatie van de klasse zich houden aan de PSR-0 standaards en je kunt het mooi gebruiken, je krijgt er zelfs een functie die perfect werkt.
mmm ok, misschien dat ik er dan toch nog eens en keer in moet verdiepen.
Want een autoloader is nog steeds wel gewenst. omdat ik dan niet zelf via reqiures alle files moet inserten.
[size=xsmall]Toevoeging op 25/03/2012 23:51:19:[/size]
Ik ben alleen bang dat het gebruik van usings dan wel teniet word gedaan, en dat ik dus altijd de volledige namespace moet gebruiken als ik een class wil instansieren.
Dus als ik bv dit gebruik in een totaal andere namespace:
use WebFrameWork\DomainLayer\UiTemplates\BaseTemplates\BasePage;
$basePage = new BasePage();
Hoe gebruik ik dit dan middels een autoloader?
Volgens mij was dit ook waar ik destijds tegen aanliep, en het maar had opgegeven toen :-)
Die worden gewoon meegegeven:
<?php
class ClassLoader
{
public static function register()
{
spl_autoload_register(array(__CLASS__, 'loadClass'));
}
// 1 van onze autoloaders
public static function loadClass( $className )
{
echo $className; // even voor debuggen
}
}
ClassLoader::register();
use WebFrameWork\DomainLayer\UiTemplates\BaseTemplates\BasePage;
$basePage = new BasePage();
// ClassLoader::loadClass() echo:
// "WebFrameWork\DomainLayer\UiTemplates\BaseTemplates\BasePage"
?>
De namespaces worden dus gewoon meegegeven. Als je hier vervolgens de PSR-0 functie aankoppelt heb je eigenlijk al je eigen simpele classloader:
<?php
class ClassLoader
{
// register method
public static function loadClass( $className )
{
$path = self::getFilePath($className);
if( file_exists($path) )
require_once $path;
else
throw new LogicException(sprintf('Class %s does not exists in %s', $classame, $path));
}
public static function getFilePath( $className )
{
$className = ltrim($className, '\\');
$fileName = '';
$namespace = '';
if ($lastNsPos = strripos($className, '\\')) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
return $fileName;
}
}
use WebFrameWork\DomainLayer\UiTemplates\BaseTemplates\BasePage;
$basePage = new BasePage();
// ClassLoader::loadClass() require_once:
// %path%/WebFrameWork/DomainLayer/UiTemplates/BaseTemplates/BasePage.php
?>
De classloaders van Symfony en die van mij zijn dan nog uitgebouwd met registered namespaces, prefixes en basepaths.
Ik zal dit dan vanavond gelijk even verder proberen, want ik kanteer wel ook die PSR-0 opbouw.
bedankt.
[size=xsmall]Toevoeging op 26/03/2012 21:46:58:[/size]
Tsjonge wat heb ik en spijt deze vraag niet eerder gesteld te hebben.
Ik heb het nu inderdaad werkend.
Je hoeft zelfs niet eens require_once te gebruiken, maar je kan gewoon require gebruiken
spl_autoload_register lijkt zelf al te herkennen of een class al is gedistantieerd en doet dan niet alsnog de file inserten.
Ik gebruik nu deze class voor mijn autoload functionaliteit, met grote dank aan Wouter.
<?php
namespace WebFrameWork
{
defined("SCRIPT_EXEC_PERM") or die ("HTTP/1.0 401 Unauthorized");
class AutoLoader
{
/**
* @var string
*/
private $_basePath;
/**
* @param $basePath
*/
public function __construct($basePath)
{
$this->_basePath = $basePath;