Muszę być w stanie wywołać funkcję, ale nazwa funkcji jest przechowywana w zmiennej, czy to możliwe? na przykład:
funkcja foo () { // kod tutaj } pasek funkcji () { // kod tutaj } $ functionName = "foo"; // muszę wywołać funkcję w oparciu o wartość $ functionName
php
dynamic-function
Jaszczurka
źródło
źródło
is_callable
funkcji. Sprawdza, czy zmienna zawiera coś, co można wywołać jako funkcję (czy to nazwa funkcji, tablica zawierająca instancję obiektu i nazwę funkcji, czy anonimowa funkcja / zamknięcie)call_user_func(array('ClassName', 'method'), $args)
Moja ulubiona wersja to wersja wbudowana:
Zmienne lub wyrażenia możesz również umieszczać w nawiasach!
źródło
{"functionName"}();
jest niezgodny z prawem i zgłosi błąd składniowy.Tak to mozliwe:
Źródło: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2
źródło
Jak już wspomniano, istnieje kilka sposobów, aby to osiągnąć za pomocą możliwie najbezpieczniejszej metody
call_user_func()
lub, jeśli to konieczne, możesz również zejść trasą$function_name()
. Możliwe jest przekazywanie argumentów przy użyciu obu tych metodJeśli funkcja, którą wywołujesz, należy do obiektu, nadal możesz użyć jednego z nich
Jeśli jednak zamierzasz użyć tej
$function_name()
metody, dobrym pomysłem może być przetestowanie istnienia funkcji, jeśli nazwa jest w jakikolwiek sposób dynamicznaźródło
W przypadku, gdy ktoś jest tu sprowadzany przez Google, ponieważ próbował użyć zmiennej dla metody w klasie, poniżej znajduje się przykładowy kod, który faktycznie będzie działał. Żadne z powyższych nie działało w mojej sytuacji. Kluczową różnicą jest
&
deklaracja$c = & new...
i&$c
przekazaniecall_user_func
.Mój szczególny przypadek dotyczy implementacji czyjegoś kodu związanego z kolorami i dwiema metodami składowymi
lighten()
orazdarken()
z klasy csscolor.php. Z jakiegokolwiek powodu chciałem, aby ten sam kod mógł wywoływać rozjaśnianie lub przyciemnianie zamiast wybierać go za pomocą logiki. Może to wynikać z mojego uporu, by nie używać tylko if-else lub zmieniać kod wywołujący tę metodę.Zauważ, że próbowanie czegokolwiek z
$c->{...}
nie działało. Po zapoznaniu się z treściami napisanymi przez czytelników na dole strony php.netcall_user_func
, udało mi się poskładać powyższe. Zauważ też, że$params
jako tablica nie działała dla mnie:Ta powyższa próba dałaby ostrzeżenie o metodzie oczekującej drugiego argumentu (procent).
źródło
Kilka lat spóźnienia, ale teraz jest to najlepszy sposób, imho:
źródło
Dla kompletności możesz również użyć eval () :
Jednak
call_user_func()
to jest właściwy sposób.źródło
eval
nie jest rozwiązaniem tego pytania.Rozwiązanie: użyj PHP7
Uwaga: Aby uzyskać podsumowaną wersję, patrz TL; DR na końcu odpowiedzi.
Stare metody
Aktualizacja : Jedna ze starych opisanych tutaj metod została usunięta. Wyjaśnienia na temat innych metod można znaleźć w innych odpowiedziach, które nie są tutaj omówione. Nawiasem mówiąc, jeśli ta odpowiedź ci nie pomoże, powinieneś zaktualizować swoje rzeczy. Obsługa PHP 5.6 zakończyła się w styczniu 2019 r. (Obecnie nawet PHP 7.0 i 7.1 nie są obsługiwane). Aby uzyskać więcej informacji, zobacz obsługiwane wersje .
Jak wspomniano inni, w PHP5 (a także w nowszych wersjach, takich jak PHP7) możemy używać zmiennych jako nazw funkcji, używać
call_user_func()
icall_user_func_array()
(które osobiście nienawidzę tych funkcji) itp.Nowe metody
Od PHP7 wprowadzono nowe sposoby:
Uwaga: Wszystko w
<something>
nawiasach oznacza jedno lub więcej wyrażeń, aby coś utworzyć, np.<function_name>
Oznacza wyrażenia tworzące nazwę funkcji.Dynamiczne wywołanie funkcji: nazwa funkcji w locie
Możemy użyć jednego lub więcej wyrażeń w nawiasach jako nazwy funkcji za jednym razem, w postaci:
Na przykład:
Uwaga: Chociaż usunięcie nawiasów wokoło
str_replace()
nie jest błędem, umieszczenie nawiasów czyni kod bardziej czytelnym. Czasami jednak nie możesz tego zrobić, np. Podczas używania.
operatora. Aby zachować spójność, zawsze zaleca się umieszczanie nawiasów.Dynamiczne wywołanie metody: nazwa metody w locie
Podobnie jak dynamiczne wywołania funkcji, możemy zrobić to samo z wywołaniami metod, otoczonymi nawiasami klamrowymi zamiast nawiasów (w przypadku dodatkowych formularzy przejdź do sekcji TL; DR):
Zobacz to w przykładzie:
Dynamiczne wywołanie metody: składnia macierzy
Bardziej elegancki sposób dodany w PHP7 jest następujący:
Jako przykład:
Uwaga: Zaletą korzystania z tej metody w porównaniu z poprzednią jest to, że nie obchodzi Cię typ połączenia (tj. Czy jest statyczny czy nie).
Dodatkowy przykład: korzystanie z anonimowych klas
Sprawiając nieco komplikację, możesz użyć kombinacji anonimowych klas i powyższych funkcji:
TL; DR (Podsumowanie)
Ogólnie rzecz biorąc, w PHP7 możliwe są wszystkie następujące formularze:
Oparte głównie na tej rozmowie PHP .
źródło
(expressions)->$bar()
Dynamiczne nazwy funkcji i przestrzenie nazw
Wystarczy dodać punkt o nazwach funkcji dynamicznych podczas korzystania z przestrzeni nazw.
Jeśli używasz przestrzeni nazw, następujące czynności nie będą działać, z wyjątkiem sytuacji, gdy twoja funkcja znajduje się w globalnej przestrzeni nazw:
Co robić?
Zamiast tego musisz użyć
call_user_func()
:źródło
Uzupełniając odpowiedź @Chris K, jeśli chcesz wywołać metodę obiektu, możesz wywołać ją za pomocą jednej zmiennej za pomocą zamknięcia:
Tutaj zamieściłem inny przykład
źródło
Czego nauczyłem się z tego pytania i odpowiedzi. Dziękuje wszystkim!
Powiedzmy, że mam te zmienne i funkcje:
Aby wywołać funkcję bez argumentów
Aby wywołać funkcję z 1 argumentem
Aby wywołać funkcję z 1 lub więcej argumentami Przyda się to, jeśli dynamicznie wywołujesz swoje funkcje, a każda funkcja ma inną liczbę argumentów. To jest mój przypadek, którego szukałem (i rozwiązałem).
call_user_func_array
jest kluczemCześć!
źródło
Użyj funkcji call_user_func.
źródło
Poniższy kod może pomóc napisać funkcję dynamiczną w PHP. teraz nazwę funkcji można dynamicznie zmieniać za pomocą zmiennej „$ current_page”.
źródło
$function
zmienną bez żadnego powodu.Najłatwiejszym sposobem na bezpieczne wywołanie funkcji przy użyciu nazwy zapisanej w zmiennej jest:
Użyłem jak poniżej do dynamicznego tworzenia tabel migracji w Laravel,
źródło
Jedno niekonwencjonalne podejście, jakie przyszło mi do głowy, to takie, że jeśli nie generujesz całego kodu za pomocą super ultra autonomicznej sztucznej inteligencji, która sama się pisze , istnieje duże prawdopodobieństwo, że funkcje, które chcesz „dynamicznie” wywołać, są już zdefiniowane w twoim kodzie baza. Dlaczego więc nie po prostu sprawdzić łańcucha i zrobić niesławny
ifelse
taniec, aby przywołać ... rozumiesz?na przykład.
switch-case
Można go nawet użyć, jeśli nie lubisz łagodnego smakuifelse
drabiny.Rozumiem, że istnieją przypadki, w których „ dynamiczne wywoływanie funkcji ” byłoby absolutną koniecznością ( jak pewna logika rekurencyjna, która się modyfikuje ). Ale większość codziennych trywialnych przypadków użycia można uniknąć.
Usuwa wiele niepewności z aplikacji, dając jednocześnie szansę na wykonanie funkcji rezerwowej, jeśli ciąg znaków nie pasuje do żadnej z dostępnych funkcji. MOIM ZDANIEM.
źródło
if (method_exists($functionName)) $functionName(); else //exception or handle
Nie wiem, dlaczego musisz tego używać, wcale nie brzmi dla mnie tak dobrze, ale jeśli jest tylko niewielka liczba funkcji, możesz użyć konstrukcji if / elseif. Nie wiem, czy możliwe jest bezpośrednie rozwiązanie.
coś jak $ foo = "bar"; $ test = "foo"; test echa $$;
powinien zwrócić pasek, możesz spróbować, ale nie sądzę, że to zadziała dla funkcji
źródło