2010-01-21 56 views
51

Xin vui lòng ai đó có kinh nghiệm trong PHP giúp đỡ với những điều sau đây. Một nơi nào đó trong mã của tôi, tôi có một cuộc gọi đến một phương pháp tĩnh công cộng bên trong một tổ chức phi instantiated lớp:Gọi phương thức tĩnh động trong PHP?

$result = myClassName::myFunctionName(); 

Tuy nhiên, tôi muốn có nhiều lớp học như thế và xác định tên lớp đúng khi đang bay theo ngôn ngữ của người dùng. Nói cách khác, tôi có:

$language = 'EN'; 

... và tôi cần phải làm một cái gì đó như:

$result = myClassName_EN::myFunctionName(); 

Tôi biết tôi có thể vượt qua các ngôn ngữ như một tham số cho hàm và đối phó với nó bên trong chỉ là một lớp phổ biến nhưng vì nhiều lý do, tôi thích một giải pháp khác.

Điều này có ý nghĩa gì không, bất kỳ ai? Cảm ơn.

+1

Để trả lời 3 dòng cuối cùng của bạn, không có ý nghĩa gì nhiều, trừ khi bạn có lý do cụ thể tại sao bạn không thể triển khai "ngôn ngữ truyền như tham số" cách –

+3

Vâng, tôi có một lý do cụ thể ... Liên quan đến việc quản lý bản dịch theo cách sane hơn cho nhiều thứ khác nhau xảy ra bên trong các lớp đó. Nó phức tạp :) – Tom

Trả lời

96

Sử dụng call_user_func chức năng:

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

Ví dụ:

call_user_func('myClassName_' . $language . '::myFunctionName'); 
+24

Kết hợp với 'is_callable' và' method_exists', điều này cũng sẽ là khuyến nghị của tôi. Để truyền các tham số nhìn vào 'call_user_func_array' http://php.net/is_callable http://php.net/method_exists http://php.net/call_user_func_array –

+1

+1, tôi đồng ý với nikc :-) –

+0

Loại tác phẩm này và có vẻ như là giải pháp sạch nhất. Cảm ơn – Tom

3

mặc dù tôi nghĩ rằng cách bạn đối phó là một ý tưởng rất xấu, tôi nghĩ rằng tôi có thể có một giải pháp

$className = 'myClassName_'.$language; 
$result = $className::myFunctionName(); 

tôi nghĩ rằng đây là những gì bạn muốn

+0

haha ​​snap! bạn đánh bại tôi bằng 45s –

+0

Bạn có thể cho tôi biết tại sao đó là một ý tưởng tồi? – Tom

+0

bạn có thể sử dụng ngôn ngữ làm tham số, thay vào đó bạn chọn xác định một lớp mới cho tham số đó. Giả sử bạn muốn hỗ trợ 200 ngôn ngữ khác nhau, bạn sẽ ngồi và viết 200 lớp khác nhau. Ngoài ra, nó sẽ làm cho mã của bạn cực kỳ khó đọc và dễ hiểu. – marvin

12

tôi nghĩ bạn có thể làm:

$classname = 'myClassName_' . $language; 
$result = $classname::myFunctionName(); 

này được gọi là Variable Functions

+4

Quá xấu này chỉ hoạt động trong> = 5.3.0 :( –

+0

Đối với tôi Và theo băng ghế của tôi, đây cũng là giải pháp nhanh nhất: 100.000 lần lặp mất 0,28 giây với cuộc gọi trực tiếp, 0,32 với giải pháp này và 0,47 với call_user_func – fred727

1

Theo như tôi có thể hiểu câu hỏi của bạn, bạn cần phải nhận được tên lớp mà có thể được thực hiện bằng get_class chức năng . Mặt khác, các Reflection class có thể giúp bạn ở đây đó là tuyệt vời khi nói đến phương pháp, đối số, vv trong OOP cách.

13

Tôi sẽ đóng gói việc tạo lớp bạn cần trong một nhà máy.

Bằng cách này bạn sẽ có một điểm vào duy nhất khi bạn cần thay đổi tên cơ sở hoặc các quy tắc để ánh xạ ngôn ngữ cho đúng lớp.

class YourClassFactory { 

     private $_language; 
     private $_basename = 'yourclass'; 

     public YourClassFactory($language) { 
      $this->_language = $language; 
     } 

     public function getYourClass() { 
      return $this->_basename . '_' . $this->_language; 
     }  
    } 

và sau đó, khi bạn phải sử dụng nó:

$yourClass = $yourClassFactoryInstance->getYourClass(); 
$yourClass::myFunctionName(); 
0

Những giải pháp như:

$yourClass::myFunctionName(); 

sẽ không hoạt động. PHP sẽ tạo ra lỗi phân tích cú pháp.

Thật không may, cách duy nhất là sử dụng rất chậmcall_user_func().

+3

Chỉ trong <5.3.0 thì điều này không được phép. 5.3.0 nó được cho phép –

+0

http://uk3.php.net/manual/en/language.variables.variable.php và http://uk3.php.net/manual/en/functions.variable-functions. php :) – tftd

6

Như temuri nói, lỗi phân tích cú pháp được tạo ra, khi cố gắng '$ className :: functionName':

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM ...

Trong trường hợp của tôi (phương pháp tĩnh với 2 đối số), giải pháp tốt nhất là sử dụng call_user_func_array với 2 mảng (theo đề nghị của nikc.org):

$result = call_user_func_array(array($className, $methodName), array($ard1, $arg2)); 

BR

-1

tôi biết đó là một chủ đề cũ, nhưng kể từ PHP 5.3.0 bạn nên sử dụng forward_static_call

$result = forward_static_call(array('myClassName_EN', 'myFunctionName')); 

Sử dụng biến ngôn ngữ $ của bạn, nó có thể trông giống như:

$result = forward_static_call(array('myClassName_' . $language, 'myFunctionName')); 
+0

Sẽ không hoạt động. Gọi một hàm do người dùng định nghĩa hoặc phương thức được đưa ra bởi tham số hàm, với các đối số sau đây. Hàm này phải được gọi trong ngữ cảnh phương thức, nó không thể được sử dụng bên ngoài một lớp ... như đã đề cập trong http://php.net/manual/en/function.forward-static-call.php –

1

Bạn có thể dễ dàng làm điều tiếp theo:

<?php 

class B { 

    public static $t = 5; 

    public static function t($h) { 
     return "Works!" . $h; 
    } 
} 

$g = 't'; 
$class = 'B'; 

echo $class::$g('yes'); //Works! Yes 

Và nó sẽ hoạt động tốt, thử nghiệm trên PHP 5.2> =

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