2009-04-23 15 views
8

Jak przekazać dowolną liczbę argumentów do konstruktora klasy za pomocą funkcji Object() zdefiniowanej poniżej?Przekazywanie argumentów konstruktorowi klasy

<?php 

/* 
./index.php 
*/ 

function Object($object) 
{ 
    static $instance = array(); 

    if (is_file('./' . $object . '.php') === true) 
    { 
     $class = basename($object); 

     if (array_key_exists($class, $instance) === false) 
     { 
      if (class_exists($class, false) === false) 
      { 
       require('./' . $object . '.php'); 
      } 

      /* 
      How can I pass custom arguments, using the 
      func_get_args() function to the class constructor? 

      $instance[$class] = new $class(func_get_arg(1), func_get_arg(2), ...); 
      */ 

      $instance[$class] = new $class(); 
     } 

     return $instance[$class]; 
    } 

    return false; 
} 

/* 
How do I make this work? 
*/ 

Object('libraries/DB', 'DATABASE', 'USERNAME', 'PASSWORD')->Query(/* Some Query */); 

/* 
./libraries/DB.php 
*/ 

class DB 
{ 
    public function __construct($database, $username, $password, $host = 'localhost', $port = 3306) 
    { 
     // do stuff here 
    } 
} 

?> 

Odpowiedz

14
$klass = new ReflectionClass($classname); 
$thing = $klass->newInstanceArgs($args); 

Chociaż potrzeba użycia refleksji sugeruje, że komplikujesz coś w swoim projekcie. Dlaczego chcesz napisać tę funkcję w pierwszej kolejności?

+0

Przyznaję, że ta funkcja może wydawać się nieco nonsensem, ale używam jej do małych rzeczy, gdzie framework może być zbyt rozdęty. A ponieważ działa jako "autoloader", konstruktor obiektów i kontener singletonowy, doskonale spełnia swoją funkcję. –

+0

BTW, że klasa Reflection jest naprawdę przydatna, czy jest jakiś kurs na temat nowych funkcji PHP 5.3? Sprawdziłem podręcznik PHP, ale czy to ja, czy brakuje w nim dokumentacji? –

+0

To nie ty: Dokumentacja jest dość skąpa. Będziesz musiał zrobić z http://www.php.net/oop5.reflection. Od około 5,1 (czy jest to 5,0?), Więc nie jest to nowa funkcja 5.3 – troelskn

3

Zamiast klasy przyjmującej oddzielne parametry, musiałbym zająć tablicę.

class DB 
{ 
    public function __construct(array $params) 
    { 
     // do stuff here 
    } 
} 

W ten sposób możesz przekazać bezpośredni wynik func_get_args do swojego konstruktora. Jedynym problemem jest teraz możliwość ustalenia klucza/wartości tablicy.

Jeśli ktoś ma jakieś pomysły, będę również zachwycony wiedzieć :)

+0

Mam ten sam pomysł, ale byłem ciekawy, czy coś takiego jak opisałem można zrobić. –

0

nie próbowałem tego, ale call_user_func_array brzmi jak chcesz.

$thing = call_user_func_array(array($classname, '__construct'), $args); 

Zajrzyj pod numer PHP Documentation.

+0

Nie działa. = \ call_user_func_array (tablica (nowa $ classname(), '__construct'), $ args); To działa, ale wtedy wywołanie konstruktora dwa razy. –

+0

Wypróbuj bez nowej $ classname(). – staticsan

+0

Błąd krytyczny: test metody niestatycznej :: __ construct() nie może być wywołany statycznie –

0

Alternatywą dla metody odbicia, byłaby ocena kodu.

eval('$instance = new className('.implode(', ', $args).');'); 
+0

Eval jest prawie zawsze złym pomysłem – Nitroware

Powiązane problemy