2012-01-23 8 views
198

Czy istnieje sposób na łatwe rozwiązanie tego problemu, czy naprawdę muszę przepisać cały dotychczasowy kod?PHP 5.4 Przekazywanie połączeń w czasie rzeczywistym - łatwa naprawa?

PHP Fatal error: Call-time pass-by-reference has been removed in ... on line 30

Dzieje się tak wszędzie, gdy zmienne są przekazywane do funkcji jako referencje w całym kodzie.

+0

Powiązane: [Ostrzeżenie PHP: odwołanie do czasu połączenia zostało wycofane] (http://stackoverflow.com/q/4665782/2157640) – Palec

Odpowiedz

314

Powinieneś oznaczać wywołanie przez odwołanie w definicji funkcji, a nie faktyczne wywołanie. Ponieważ PHP zaczęło wyświetlać błędy usuwania w wersji 5.3, powiedziałbym, że dobrze byłoby przepisać kod.

From the documentation:

There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a); .

Na przykład, zamiast stosowania:

// Wrong way! 
myFunc(&$arg);    # Deprecated pass-by-reference argument 
function myFunc($arg) { } 

Zastosowanie:

// Right way! 
myFunc($var);    # pass-by-value argument 
function myFunc(&$arg) { } 
+8

Szkoda :(- przesyłam z 5,2 do 5,4 i to jest naprawdę denerwujące ... – bardiir

+9

Przestarzałość jest od PHP 5.0.0, wstecz tym razem z błędem poziomu "E_COMPILE_WARNING", dla odniesienia: http://www.php.net/manual/en/ini.core.php# ini.allow-call-time-pass-reference – hakre

+5

Miałem ten błąd, ale potrzebowałem usunąć & dodany do zmiennej – Diana

5

PHP i odniesienia są nieco unintuitive. Jeśli użyjesz odpowiednich odnośników we właściwych miejscach, możesz uzyskać znaczną poprawę wydajności lub uniknąć bardzo brzydkich obejść i nietypowego kodu.

Poniższa będzie produkować błąd:

function f(&$v){$v = true;} 
f(&$v); 

function f($v){$v = true;} 
f(&$v); 

Żaden z nich się nie powiedzie, gdyż mogą one przestrzegać zasad poniżej, ale nie mają wątpliwości zostały usunięte lub wyłączone, aby zapobiec wielu starszych zamieszania.

Jeśli zadziałały, oba wymagają redundantnej konwersji do referencji, a druga wiąże się z nadmiarową konwersją z powrotem do zmiennej zawierającej zakres.

Drugi był możliwy, umożliwiając przekazanie odwołania do kodu, który nie był przeznaczony do pracy z referencjami. Jest to wyjątkowo brzydkie ze względu na łatwość konserwacji.

To nic nie zrobi:

function f($v){$v = true;} 
$r = &$v; 
f($r); 

Dokładniej, okazuje odesłanie z powrotem do normalnej zmiennej a nie prosić o odniesienie.

to będzie działać:

function f(&$v){$v = true;} 
f($v); 

ten widzi, że jesteś przechodzącą Niereferencyjne ale chcą odniesienie więc zamienia ją odniesienie.

Oznacza to, że nie można przekazać odwołania do funkcji, w której odwołanie nie jest jawnie wymagane, aby uczynić go jednym z niewielu obszarów, w których PHP jest ścisłe dla typów przekazywania lub w tym przypadku bardziej typu meta .

Jeśli potrzebujesz bardziej dynamiczne zachowanie to będzie działać:

function f(&$v){$v = true;} 
$v = array(false,false,false); 
$r = &$v[1]; 
f($r); 

Tu widzi, że chcesz odniesienie i już odniesienie więc pozostawia w spokoju. Może również łączyć odniesienie, ale wątpię w to.

3

Dla każdego, kto, jak ja, czyta to, ponieważ musi zaktualizować gigantyczny projekt ze starszej wersji do wersji 5.6: jak wskazują tu odpowiedzi, nie ma szybkiej poprawki: naprawdę trzeba znaleźć każde wystąpienie problemu ręcznie i napraw to.

Najwygodniejszy sposób znajdowania wszystkich problematycznych linii w projekcie (brak użycia pełnego statycznego analizatora kodu, który jest bardzo dokładny, ale nie znam żadnego, który doprowadzi cię do właściwej pozycji w redaktor od razu) korzystał z kodu Visual Studio Code, który ma wbudowaną ładowną wtyczkę PHP, oraz funkcji wyszukiwania, która umożliwia wyszukiwanie według Regex. (Oczywiście, można użyć dowolnego IDE edytora/kodu dla tego, że robi PHP strzępienia i wyszukiwania regex).

Użycie tego wyrażenia regularnego:

^(?!.*function).*(\&\$) 

możliwe jest poszukiwanie całego projektu pod kątem występowania &$ tylko w wierszach, które nie są definicjami funkcji.

To nadal pokazuje wiele fałszywych alarmów, ale ułatwia to pracę.

Przeglądarka wyników wyszukiwania VSCode sprawia, że ​​przechodzenie i znajdowanie obraźliwych linii jest bardzo łatwe: wystarczy kliknąć każdy z wyników i zwrócić uwagę na te, które liner podkreśla na czerwono. Te, które musisz naprawić.

+1

Tego właśnie szukałem! – Sonny

+1

Dokładniejsze wyrażenie regularne, którego używam do tego celu: '(? ] [a-zA-Z0-9 _] + (? Mojo

Powiązane problemy