2009-12-07 44 views
10

Tôi đang ở trong một tình huống mà tôi cần để khởi tạo một lớp với các đối số từ bên trong một thể hiện của một lớp khác. Đây là nguyên mẫu:PHP: Làm thế nào để khởi tạo một lớp với các đối số từ bên trong một lớp khác

//test.php 

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

Bây giờ, tôi cần phải nhanh chóng trên lớp sử dụng dưới đây cls lớp của chức năng:

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; 
} 
} 

Bây giờ khi tôi cố gắng để tạo ra một thể hiện của lớp thử nghiệm trong khi đi tranh cãi cho nó:

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

Lỗi: Thiếu đối số 1 và 2; chỉ đối số đầu tiên được thông qua.

Điều này làm việc tốt nếu tôi khởi tạo một lớp không có đối số trong hàm hàm tạo của nó.

Đối với các nhà phát triển PHP có kinh nghiệm, ở trên không phải là vấn đề lớn. Hãy giúp tôi.

Cảm ơn

+0

Không liên quan đến câu hỏi của bạn, nhưng $ args sẽ luôn là 'isset' vì bạn gán mảng() vào trong định nghĩa hàm. Bạn có thể quan tâm đến 'empty', hoặc' $ args = null'. – Tordek

+0

Tôi xin lỗi, điều này cũng không liên quan đến câu hỏi của bạn, nhưng những gì bạn đang làm không phải là mát mẻ. câu trả lời cho câu hỏi của bạn là: để constructor của bạn lấy một mảng, có một số thuộc tính lớp, sau đó xử lý mảng và ánh xạ nó tới các thuộc tính lớp. Nhưng một lần nữa, bạn đang làm một cái gì đó mà không mát mẻ. – DarthVader

+0

lớp kiểm tra và khác sẽ được thực hiện bởi các nhà phát triển khác bằng cách sử dụng cách riêng của họ với các đối số và không có nó, vì vậy tôi không muốn hạn chế họ chỉ chuyển đối số thành mảng cho các nhà xây dựng. – Sarfraz

Trả lời

28

bạn cần Reflection 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

Tôi thực sự cảm hứng với kiến ​​thức rằng stereofrog có bởi vì hầu hết mọi người thậm chí không biết về lớp phản chiếu và bản thân tôi không biết rằng chúng ta có thể sử dụng lớp phản chiếu để truyền các đối số theo cách đó. nó giải quyết vấn đề của tôi tôi đã không thể tìm ra giải pháp cho nhiều ngày. Ngay cả những nhà phát triển có kinh nghiệm nhất cũng không thể đưa ra câu trả lời thỏa đáng cho câu hỏi của tôi, điều này rất quan trọng và mọi người ở đây nên xem xét kịch bản đó của câu hỏi. Dù sao tôi rất vui khi tìm ra giải pháp cho câu hỏi rất quan trọng này. Cảm ơn stereofrog :) – Sarfraz

+1

Tôi đã tìm kiếm một giải pháp cơ bản không phản chiếu, nhưng có vẻ như tôi đã phải nghỉ mát đến điều này. Darn. – yclian

4

Bạn có thể:

1) Sửa đổi lớp thử nghiệm để chấp nhận một mảng, trong đó có chứa các dữ liệu mà bạn muốn vượt qua.

//test.php 

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

2) bắt đầu sử dụng phương pháp người dùng thay vì hàm tạo và gọi hàm sử dụng hàm 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 />'; 
     } 

} 

Trong lớp học chính của bạn:

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

Cuối cùng, bạn có thể để lại constructor của bạn params trống và sử dụng 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

Bạn có thể sử dụng call_user_func_array() Tôi tin.

hoặc bạn có thể để lại các đối số danh sách các nhà xây dựng, và sau đó bên trong constructor sử dụng này

$args = func_get_args(); 
+0

Phần đầu tiên của câu trả lời này giúp bằng cách gọi hàm tạo; phần thứ hai có thể giúp trong lớp này để làm cho giao diện đẹp hơn (chỉ cần vượt qua các đối số thay vì gói chúng trong một mảng). – Tordek

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

} 

$ object = textProperty mới ($ bắt đầu, $ end);

không hoạt động?

0

Cách đơn giản nhất tôi đã tìm thấy:

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]); 
     } 

Xin lỗi một chút thô, nhưng bạn nên hiểu được ý tưởng.

Các vấn đề liên quan