2010-09-24 29 views
7

Tôi đang sử dụng php 5.2.6. Tôi có một mô hình chiến lược, và các chiến lược có một phương pháp tĩnh. Trong lớp thực sự thực hiện một trong các chiến lược, nó nhận được tên của lớp chiến lược để khởi tạo. Tuy nhiên, tôi muốn gọi một trong các phương pháp tĩnh trước khi khởi tạo, như sau:Không thể gọi phương thức tĩnh từ lớp là tên biến?

$strNameOfStrategyClass::staticMethod(); 

nhưng nó cung cấp T_PAAMAYIM_NEKUDOTAYIM.

$> cat test.php 

<? 

interface strategyInterface { 
     public function execute(); 
     public function getLog(); 
     public static function getFormatString(); 
} 


class strategyA implements strategyInterface { 
     public function execute() {} 
     public function getLog() {} 
     public static function getFormatString() {} 
} 

class strategyB implements strategyInterface { 
     public function execute() {} 
     public function getLog() {} 
     public static function getFormatString() {} 
} 

class implementation { 
     public function __construct(strategyInterface $strategy) { 
       $strFormat = $strategy::getFormatString(); 
     } 
} 

$objImplementation = & new implementation("strategyB") ; 

$> php test.php 

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in /var/www/test.php on line 24 

$> php -v 

PHP 5.2.6-1+lenny9 with Suhosin-Patch 0.9.6.2 (cli) (built: Aug 4 2010 03:25:57) 

Điều này có hoạt động trong 5.3 không?

Trả lời

11

Có. cú pháp đã được giới thiệu trong 5,3

Để workaround cho < = 5.2, bạn có thể sử dụng call_user_func:

call_user_func(array($className, $funcName), $arg1, $arg2, $arg3); 

hoặc call_user_func_array:

call_user_func_array(array($className, $funcName), array($arg1, $arg2, $arg3)); 

Nhưng lưu ý khác, những gì bạn đang cố gắng để không thực sự hợp lý ...

Tại sao có chức năng tĩnh? Constructor của bạn trong implementation đang mong đợi một đối tượng anyway (đó là những gì strategyInterface $strategy đang tìm kiếm). Việc chuyển một chuỗi sẽ không hoạt động vì chuỗi không triển khai giao diện. Vì vậy, những gì tôi sẽ làm gì, là làm cho giao diện không tĩnh, và sau đó làm điều gì đó như:

$strategy = new StrategyB(); 
$implementation = new Implementation($strategy); 

Sau đó, trong constructor:

$strFormat = $strategy->getFormatString(); 

Hoặc, nếu bạn thực sự vẫn muốn rằng phương pháp để được tĩnh bạn có thể làm:

$strFormat = call_user_func(array(get_class($strategy), 'getFormatString')); 

Oh, và = & new synax là deprecated (và không làm những gì bạn nghĩ nó anyway).

+1

1 cho làm thế nào để Xử lý vấn đề loại gợi ý –

+0

Có một fart não ngày hôm nay: PI không muốn truyền một đối tượng instantiated đến lớp thực hiện, vì tôi muốn khởi tạo nó xuống dòng, sau khi lớp thực hiện đã tạo ra một số dữ liệu mà tầng egy cần. Tôi sẽ nghĩ rằng tôi sẽ cần 'call_user_func_array()' anyway - cảm ơn cho mã tuyệt vời! – user151841

+0

Lưu ý rằng loại tác phẩm này chỉ trong 5.3. Bạn có thể làm "$ foo :: staticMethod()" nhưng bạn không thể làm "$ this-> foo = new Whatever(); $ this-> foo :: staticMethod()". –

0

Loại gián tiếp sẽ cung cấp cho bạn một số vấn đề:

Đối số 1 truyền cho thực hiện :: __ construct() phải thực hiện giao diện strategyInterface, chuỗi cho trước

+0

Hm, não rắm sáng nay. Tại sao php của tôi không cho tôi lỗi đó? – user151841

+0

@ user151841 - Bởi vì bất ngờ T_PAAMAYIM_NEKUDOTAYIM được phát hiện tại thời gian biên dịch, vì vậy bạn đã nhận được lỗi đó ... Tôi đã sửa lỗi đó bằng call_user_func() trước khi cố gắng chạy mã và nhận lỗi thứ hai, đây là lỗi thời gian chạy. –

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