2009-12-07 109 views
10

我處於需要使用另一個類的實例中的參數實例化類的情況。 這裏是原型:PHP:如何使用另一個類中的參數實例化一個類

//test.php 

class test 
{ 
    function __construct($a, $b, $c) 
    { 
     echo $a . '<br />'; 
     echo $b . '<br />'; 
     echo $c . '<br />'; 
    } 
} 

現在,我需要實例上面用下面類的CLS功能類:

class myclass 
{ 
function cls($file_name, $args = array()) 
{ 
    include $file_name . ".php"; 

    if (isset($args)) 
    { 
     // this is where the problem might be, i need to pass as many arguments as test class has. 
     $class_instance = new $file_name($args); 
    } 
    else 
    { 
     $class_instance = new $file_name(); 
    } 

    return $class_instance; 
} 
} 

現在,當我試圖同時傳遞參數來創建測試類的一個實例它:

$myclass = new myclass; 
$test = $myclass->cls('test', array('a1', 'b2', 'c3')); 

它給出錯誤: 缺少參數1和2;只有第一個參數被傳遞。

這工作得很好,如果我實例化一個沒有它的構造函數參數的類。

對於有經驗的PHP開發人員來說,上面應該不是什麼大問題。請幫忙。

感謝

+0

與您的問題無關,但$ args將始終爲'isset',因爲您在函數定義中將array()分配給它。你可能對'empty'或'$ args = null'感興趣。 – Tordek

+0

對不起,這也與你的問題無關,但你所做的並不酷。你的問題的答案是:讓你的構造函數接受一個數組,獲得一些類屬性,然後處理該數組並將其映射到類屬性。但是,再一次,你正在做一些不太酷的事情。 – DarthVader

+0

測試類和其他開發人員將使用自己的方式使用自己的方式和沒有它,所以我不想限制他們只傳遞參數作爲數組構造函數。 – Sarfraz

回答

28

你需要思考http://php.net/manual/en/class.reflectionclass.php

if(count($args) == 0) 
    $obj = new $className; 
else { 
    $r = new ReflectionClass($className); 
    $obj = $r->newInstanceArgs($args); 
} 
+0

我非常喜歡stereofrog的知識,因爲大多數人甚至不知道反射類,我自己也不知道我們可以使用反射類來傳遞參數。它解決了我的問題,我無法找到解決方案很多天。即使是最有經驗的開發人員也無法爲我的問題提供令人滿意的答案,這非常重要,每個人都應該看看這個問題的場景。無論如何,我很高興找到解決這個非常重要的問題。謝謝stereofrog :) – Sarfraz

+1

我正在尋找一個非反射基礎解決方案,但看起來像我不得不訴諸這一點。該死。 – yclian

4

您可以:

1)修改測試類接受一個數組,其中包含你要傳遞的數據。

//test.php 

class test 
{ 
     function __construct($a) 
     { 
       echo $a[0] . '<br />'; 
       echo $a[1] . '<br />'; 
       echo $a[2] . '<br />'; 
     } 
} 

2)發起使用用戶方法代替的構造和使用call_user_func_array()函數調用它。

//test.php 

class test 
{ 
     function __construct() 
     { 

     } 

     public function init($a, $b, $c){ 
       echo $a . '<br />'; 
       echo $b . '<br />'; 
       echo $c . '<br />'; 
     } 

} 

在主類:

class myclass 
{ 
function cls($file_name, $args = array()) 
{ 
     include $file_name . ".php"; 

     if (isset($args)) 
     { 
       // this is where the problem might be, i need to pass as many arguments as test class has. 
       $class_instance = new $file_name($args); 
       call_user_func_array(array($class_instance,'init'), $args); 
     } 
     else 
     { 
       $class_instance = new $file_name(); 
     } 

     return $class_instance; 
} 
} 

http://www.php.net/manual/en/function.call-user-func-array.php

最後,您可以留下您的構造PARAMS空白和使用func_get_args()

//test.php 

class test 
{ 
     function __construct() 
     { 
       $a = func_get_args(); 
       echo $a[0] . '<br />'; 
       echo $a[1] . '<br />'; 
       echo $a[2] . '<br />'; 
     } 
} 

http://sg.php.net/manual/en/function.func-get-args.php

1

你可以使用call_user_func_array()我相信。

,或者你可以離開構造函數的參數列表,然後在構造函數中使用此

$args = func_get_args(); 
+0

這個答案的第一部分有助於調用構造函數;第二部分可以幫助這個類使接口更好(只是傳遞參數而不是將它們包裝在數組中)。 – Tordek

1
class textProperty 
{ 
    public $start; 
    public $end; 
    function textProperty($start, $end) 
    { 
     $this->start = $start; 
     $this->end = $end; 
    } 

} 

$對象=新textProperty($開始,$結束);

不工作?

0

我發現最簡單的方法:

if ($depCount === 0) { 
      $instance = new $clazz(); 
     } elseif ($depCount === 1) { 
      $instance = new $clazz($depInstances[0]); 
     } elseif ($depCount === 2) { 
      $instance = new $clazz($depInstances[0], $depInstances[1]); 
     } elseif ($depCount === 3) { 
      $instance = new $clazz($depInstances[0], $depInstances[1], $depInstances[2]); 
     } 

對不起有點生,但你應該瞭解的想法。

相關問題