SORU
17 Temmuz 2011, Pazar


Parantez işlevi semantik değiştirme arama sonucu

Parantez içinde PHP bir işlev çağrısı sonucunda kaydırma bir şekilde aşağıdaki işleri tam teşekküllü bir ifade içine: sonuç dönüştürebilirsiniz another question belirtilmişti

<?php
error_reporting(E_ALL | E_STRICT);

function get_array() {
   return array();
}

function foo() {
   // return reset(get_array());
   //              ^ error: "Only variables should be passed by reference"

   return reset((get_array()));
   //           ^ OK
}

foo();

İçin belgelerinde bir şey bulmaya çalışıyorumaçıkçave açıkça burada neler olduğunu açıklayabilir. C aksine , PHP dilbilgisi hakkında yeterince bilgim yok ve tabloların tedavisi ifadeler kendim elde etmek/.

Hiçbir şey bu davranışı ile ilgili belgeler gizli var mı? Başkası varsayım başvurmadan açıklayamaz?


Güncelleme

Ben ilk this EBNF PHP dilbilgisi temsil gücünün buldum, ve benim komut decode etmeye çalıştım kendimi, ama sonunda vazgeçti.

Daha sonra using phc foo() iki türevleri, produced AST her iki komut için görüntüleri .dot bir dosya oluşturmak için aşağıdaki komutları kullanarak:

$ yum install phc graphviz
$ phc --dump-ast-dot test1.php > test1.dot
$ dot -Tpng test1.dot > test1.png
$ phc --dump-ast-dot test2.php > test2.dot
$ dot -Tpng test2.dot > test2.png

Her iki durumda da sonuç aynı oldu:

Parse tree of snippets 1 and 2

CEVAP
18 Temmuz 2011, PAZARTESİ


Bu davranış olarak sınıflandırılmış olabilirhatakesinlikle güvenmemelisiniz.

Bu mesaj için (basit) şartlarıdeğilbir işlev çağrısı üzerine atılmak üzere aşağıdaki (definition of the opcode ZEND_SEND_VAR_NO_REF):

  • bağımsız bir işlev çağrısı (ya da eğer varsa, başvuru döndürür) değildir
  • bağımsız bir referans ya da 1 Eğer bir referans oldu 1, başvuru sayısı (eğer varsa) başvuru sayısı var.

Hadi daha detaylı bir analiz bu.

İlk nokta doğru (bir işlev çağrısı değil)

Ek parantez nedeniyle, PHP artık bağımsız bir işlev çağrısı olduğunu algılar.

non empty function argument list bir ayrıştırma PHP için üç ihtimal var:

  • Bir 9**
  • 10**
  • (& variable referans ile çağırma zamanı kaldırılan geçmek için bir özellik) izledi

Sadece yazarken get_array() PHP variable olarak görüyor.

Diğer yandan (get_array()) variable olarak nitelendirin. expr_without_variable.

Bu sonuçta etkilediği kodu derler, yani genişletilmiş değer işlem kodu SEND_VAR_NO_REF artık bulunur bayrak ZEND_ARG_SEND_FUNCTION, hangi şekilde işlevini çağırın algılandı işlem kodu uygulaması.

İkinci nokta doğru (başvuru sayısı 1'dir)

Birkaç noktada, Çalışabilir Motor başvurular beklendiği sayısı 1 referansı olmayan başvurular sağlar. Bu bilgiler kullanıcının açık olmamalı, ama ne yazık ki burada.

Örnek başka bir yerden başvurulan olmayan bir dizi dönen sensin. Eğer olsaydı, hala bu mesajı almak istiyorsunuz, yani bu ikinci nokta doğru olmaz.

Aşağıdaki örneğe benzerçalışmıyor:

<?php

$a = array();
function get_array() {
   return $GLOBALS['a'];
}

return reset((get_array()));

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • cdgotx

    cdgotx

    8 Kasım 2011
  • FRED

    FRED

    1 EKİM 2005
  • Jejoab

    Jejoab

    4 NİSAN 2008