Hey iedereen,

Ik heb een methode 'load' in de class 'Library' die een object kan openen uit de library en terugstuurt:
<?php
$db = $library->load('database');
?>

Dat doet ie (erg versimpeld, zonder controle, enz) als volgt:
<?php
class Library {
    public function load ($name) {
        include_once($name.'.php');
        $object = new $name();
        return $object;
    }
}
?>

Alleen nu wil ik een object aanmaken waarvan de constructor parameters moet krijgen. Dus zo:
<?php
// object opvragen
$db = $library->load('database', array('localhost', 'mydatabase'));

// De load()-functie in de Library-class
public function load($name, $params = array()) {
    include_once($name.'.php');
    // Wat moet er hier komen??
    // Zoiets werkt niet:
    $object = new call_user_func_array($name, $params);
    // En zoiets ook niet:
    $object = call_user_func_array('new '.$name, $params);
    // Dit werkt wel, maar dan kan je maar één argument doorgeven (een array dus)
    $object = new $name($params);
    return $object;
}
?>

Moet ik dan echt de constructors herschrijven zodat ze de argumenten als een array kunnen ontvangen?
Een andere oplossing is om zoiets te doen:
<?php
$code = '$object = new $name(' . implode(', ', $params) . ');';
eval ($code);
?>

alleen is dit denk ik niet de ideale oplossing. Het lijkt mij iig erg omslachtig. Weet iemand hier een oplossing voor??

Alvast bedankt!
Daan

Edit:
Ik zie dat ik hem per ongeluk heb aangemaakt bij 'design'. Dat moet natuurlijk 'OOP' zijn..

Mod edit:
Verplaatst...
Wat jij wil is iig mogelijk met reflection ( http://nl.php.net/language.oop5.reflection ) hoe en wat precies weet ik ook niet uit mijn hoofd.

Overigens denk ik dat je dit beter anders kan aanpakken, wat je library eigenlijk is, is een registry. Registry is een bekend design pattern, wat vaak net iets anders wordt geïmplementeerd, hier op phphulp zijn genoeg voorbeelden te vinden. Je methode load is eigenlijk een combinatie van de registry en een autoload functie.

edit:
In het geval van reflection denk ik dat je ReflectionClass::newInstanceArgs() nodig hebt.
werkt dit niet:

$oObject = call_user_func_array(array('naam van de controller', '__construct'), $aParams);

Overigens lijkt Reflection mij mooier, maar is dit miss makkelijker
Volgens mij is reflection zelfs de enige manier waarop het kan.

Overigens is dit volgens mij niet het registery pattern, maar nijgt het meer naar het dependency injection pattern. Ik vind het er wel elegant uitzien eigenlijk :)
Ik was vanavond even weg, ik ga aan de slag met jullie commentaar!

Edit:
Reflection is precies wat ik zoek! Bedankt, had er nog nooit van gehoord.
Ik heb ff opgezocht wat dat met die patterns inhoud, en volgens mij is het meer een registry pattern. Van het Dependency injection pattern snap ik eigenlijk niet zoveel na de uitleg op wikipedia..

Maargoed, het werkt nu.
Voor de geïnteresseerden, dit heb ik nu:

<?php
// De load()-functie in de Library-class
public function load($name, $params = array()) {
    include_once($name.'.php');
    $class = new ReflectionClass($name);
    $object = $class->newInstanceArgs($params);
    return $object;
}
?>


Werkt perfect! Nogmaals bedankt!

Reageren