2010-01-21 14 views
51

Ktoś może doświadczyć w PHP pomocy z następującymi. Gdzieś w moim kodu, mam wezwanie do publicznej metody statycznej wewnątrz non-instancja klasy:Dynamiczne wywołanie metody statycznej w PHP?

$result = myClassName::myFunctionName(); 

Jednak chciałbym mieć wiele takich klas i określić prawidłową nazwę klasy na bieżąco zgodnie z język użytkownika. Innymi słowy, mam:

$language = 'EN'; 

... i muszę zrobić coś takiego:

$result = myClassName_EN::myFunctionName(); 

Wiem, że mógłbym przejść języka jako parametr do funkcji i radzić sobie z nim wewnątrz tylko jedna wspólna klasa, ale z różnych powodów wolałbym inne rozwiązanie.

Czy to ma jakiś sens, ktoś? Dzięki.

+1

Aby odpowiedzieć na ostatnie 3 wiersze, nie ma to większego sensu, chyba że masz konkretny powód, dla którego nie możesz wdrożyć "pass language as parameter" way –

+3

Tak, mam konkretny powód ... Odnosi się do zarządzania tłumaczeniami w bardziej logiczny sposób na różne rzeczy, które dzieją się wewnątrz tych klas. To skomplikowane :) – Tom

Odpowiedz

96

Korzystanie z call_user_func funkcję:

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

przykład:

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

W połączeniu z 'is_callable' i' method_exists' byłoby to również moje zalecenie. Aby przekazać paramy spójrz na 'call_user_func_array' http://php.net/is_callable http://php.net/method_exists http://php.net/call_user_func_array –

+1

+1, zgadzam się z nikc :-) –

+0

Ten rodzaj prac i wydaje się być najczystszym rozwiązaniem. Dzięki – Tom

3

chociaż myślę, że tak, jak sobie to bardzo zły pomysł, myślę, że może mieć rozwiązanie

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

myślę, że to jest to, co chcesz

+0

haha ​​snap! pokonałeś mnie przez 45s –

+0

Proszę, możesz mi powiedzieć, dlaczego to taki zły pomysł? – Tom

+0

możesz użyć języka jako parametru, zamiast tego zdecydujesz się zdefiniować dla niego nową klasę. Powiedzmy, że chcesz wspierać 200 różnych języków, czy usiądziesz i napiszesz 200 różnych klas. Ponadto sprawi, że twój kod będzie niezwykle trudny do odczytania i zrozumienia. – marvin

12

myślę można zrobić:

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

To się nazywa Variable Functions

+4

To źle, to działa tylko w> = 5.3.0 :( –

+0

Dla mnie To jest najlepsze rozwiązanie, a według mojej tabeli jest to również najszybsze: 100 000 iteracji zajęło 0,28 z bezpośrednim połączeniem, 0,32 z tym rozwiązaniem i 0,47 z call_user_func – fred727

1

O ile mogę zrozumieć pytanie, trzeba uzyskać nazwę klasy, które mogą być wykonywane przy użyciu get_class funkcji . Z drugiej strony, Reflection class może ci w tym pomóc, jeśli chodzi o metody, argumenty itp. W stylu OOP.

13

Chciałbym hermetyzować tworzenie klasy, której potrzebujesz w fabryce.

W ten sposób będziesz mieć pojedynczy punkt wejścia, gdy będziesz musiał zmienić swoją nazwę bazową lub reguły mapowania języka na właściwą klasę.

class YourClassFactory { 

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

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

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

a potem, kiedy trzeba go użyć:

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

Solutions jak:

$yourClass::myFunctionName(); 

nie będzie działać. PHP wygeneruje błąd analizy.

Niestety, jedynym sposobem jest użycie bardzo powolnegocall_user_func().

+3

Tylko w <5.3.0 jest to niedozwolone. 5.3.0 jest dozwolony –

+0

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

6

Jak powiedział Temuri, parse error jest produkowany, gdy próbuje '$ className :: functionName':

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM ...

W moim przypadku (statyczne metody z 2 argumentami), najlepszym rozwiązaniem jest użycie call_user_func_array z 2 tablicami (jak sugeruje nikc.org):

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

BR

-1

wiem, że to stary wątek, ale jak z 5.3.0 PHP należy używać forward_static_call

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

Korzystanie zmienną języka $, może to wyglądać tak:

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

Nie działa. Wywołuje zdefiniowaną przez użytkownika funkcję lub metodę określoną przez parametr funkcji, z następującymi argumentami. Ta funkcja musi być wywołana w kontekście metody, nie może być używana poza klasą ... jak wspomniano w http://php.net/manual/en/function.forward-static-call.php –

1

Można łatwo zrobić:

<?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 

i to działa dobrze, przetestowane na PHP 5.2> =

Powiązane problemy