Sadece değişkenler referans olarak kabul edilebilir

7 Cevap php

Ben bir tavşan deliğinden beni neden olan bir özel hata işleyicisi kullanarak parlak bir fikri vardı.

Aşağıdaki kodu (özel hata işleyicisi ile ve olmadan) verir: Fatal error: Only variables can be passed by reference

function foo(){
    $b=array_pop(array("a","b","c"));
    return $b;
}
print_r(foo());

Aşağıdaki kodu verir (only with a custom error handler): (2048) Only variables should be passed by reference

function foo(){
    $a=explode( '/' , 'a/b/c');
    $c=array_pop(array_slice($a,-2,1));
    return $c;
}
print_r(foo());

Ben 'kompakt' bir sürü kod var çünkü ikinci bir beni endişelendiriyor. Yani, ben de (benim günlük modülü geliştirmek için) veya tüm kodumu genişletmek bir özel hata işleyicisi kullanarak parlak bir fikir hendek.

Iyi fikirler herkes? Ayrıca, WTF?

UPDATE:

Php hata işleme nasıl çalıştığı hakkında bir şeyler öğrendim cevaplar sayesinde. E_STRICT (php 5) dahil değil E_ALL ait karışıklık serin değil.

Tüm bunların üstüne, kendi özel hata işleyicisi oluşturma varsayılan ve sorunlar başlar thats tarafından E_STRICT sağlar.

Hikayenin ahlaki onları TÜM yakalamak ve filtreleme yapmak hata sabitleri (E_STRICT, E_USER_WARNING, E_USER_ERROR, vb) kullanmak için kendi hata işleyicisi kullanmaktır.

Değişken başvuruları ve bazı fonksiyonları ile 'hafıza yolsuzluk sorunu' gelince, ben ne diyebilirim? Çifte cool. Benim hata işleyicisi ve hayat devam ediyor in E_STRICT görmezden (Eğer gerektiği anlamına gelmez ki) olacak.

7 Cevap

array_pop () parametre olarak geçirilen bu değeri değiştirmek için çalışır. Şimdi ikinci örnekte bu array_slice () dan dönüş değeridir. Motor açısından bu bir "geçici bir değer" olduğunu ve böyle bir değer referansları tarafından kabul edilemez. ne gerek geçici bir değişkendir:

function foo(){
    $a=explode( '/' , 'a/b/c');
    $b=array_slice($a,-2,1);
    $c=array_pop($b);
    return $c;
}
print_r(foo());

Sonra $ b için bir referans () array_pop geçirilebilir. http://php.net/references başvuruları hakkında daha fazla bilgi için bkz.

İşte php-cli ikinci php kod parçacığını çalışırken ne olsun after setting error_reporting to E_ALL | E_STRICT

    gparis@techosaure:~/workspace/universcine.com$ php -a
Interactive shell

php > function foo(){
php {     $a=explode( '/' , 'a/b/c');
php {     $c=array_pop(array_slice($a,-2,1));
php {     return $c;
php { }
php > print_r(foo());
PHP Strict standards:  Only variables should be passed by reference in php shell code on line 3
PHP Stack trace:
PHP   1. {main}() php shell code:0
PHP   2. foo() php shell code:1

Gördüğünüz gibi, burada sadece sıkı standartlar bulunuyor. Ve kolayca (olsun değerine göre: 2048, örneğin burada) özel hata işleyicisi bunları görmezden sağlayabilirsiniz.

Php 5.3 itibariyle, E_ALL bu bak, E_STRICT içermez:

php > foreach(array("E_ALL", "E_DEPRECATED", "E_STRICT", "E_NOTICE", "E_PARSE", "E_WARNING") as $const) echo $const . "  :\t" . constant($const) ."\t". decbin(constant($const)). "\n";
E_ALL  :        30719   111011111111111
E_DEPRECATED  : 8192    10000000000000
E_STRICT  :     2048    100000000000
E_NOTICE  :     8       1000
E_PARSE  :      4       100
E_WARNING  :    2       10

Php 5.4 itibariyle E_ALL içerir E_STRICT etmez:

E_ALL  :            32767   111111111111111
E_DEPRECATED  :     8192    10000000000000
E_STRICT  :         2048    100000000000
E_NOTICE  :         8       1000
E_PARSE  :          4       100
E_WARNING  :        2       10

Bu (PHP dev ekibi göre) bir bellek bozulması mesele. Sadece bir atama atmak:

function foo(){
    $b = array_pop($arr = array("a","b","c"));
    return $b;
}
print_r(foo());

:

function foo(){
    $a = explode( '/' , 'a/b/c');
    $c = array_pop($arr = array_slice($a,-2,1));
    return $c;
}
print_r(foo());

İkinci bir E_STRICT üretir. (Eğer bu işlevleri değiştirmek istemiyorsanız) dilerseniz farklı hata işleyicisi bu işleyebilir.

array_pop() hata geliyor nerede kendisine iletilen bu değer değiştirir. Bir fonksiyon değiştirilemez. , Ve sonra çalıştırın array_pop(): (manual ref) Başka bir deyişle, bir değişkenin birinci dizi atamanız gerekir.

İhtiyacınız kod şudur:

function foo(){
    $a = array("a","b","c");
    $b = array_pop($a);
    return $b;
}

Edit: Bahsettiğiniz iki fonksiyon da aynı sorun var. Bir değişkene dizi atayın ve array_pop() için değişken geçmek.

Ben şimdi (php 5 beri) olması gerektiğini düşünüyorum:

function &foo(){ //NOTICE THE &
    $b=array_pop(array("a","b","c"));
    return $b;
}
print_r(foo());

ve

function &foo(){ //NOTICE THE &
    $a=explode( '/' , 'a/b/c');
    $c=array_pop(array_slice($a, $b = -2, $c = 1)); //NOW NO DIRECT VALUES ARE PASSED IT MUST BE VARIABLES
    return $c;
}
print_r(foo());

ama sadece bir acemi değilim :)

Bu deneyin:

function foo(){
    $a = array("a","b","c");
    $b = array_pop($a);
    return $b;
}