O küresellerle kullanmayan PHP 5.2.x 'te kapakları taklit etmek mümkün mü? Ben kapatılması için ekstra parametre olarak istenen değişkenleri geçerdi ama bu sadece iyi uygulama gibi gelmiyor bir şekilde düşünebilirim.
Herhangi bir fikir?
İlginç bir soru. I it's not possible at all söylüyorlar, ama bakalım istiyorum
Alıntı IBM - What's new in PHP5.3, Part 2
Bir kapatma birini veya fonksiyon çağrıldığında ulaşılabilir daha bağlı değişkenleri kendi ortamında, değerlendirildiğinde bir işlevdir.
ve ayrıca (vurgu benim)
Variables to be imported dış çevreden kapanma işlevi tanımının kullanılması fıkrasında belirtilmiştir. Varsayılan olarak, are passed by value, biz kapanma işlevi tanımı içinde geçti değerini güncelleştirmek olsaydı, bu dış değerini güncelleme olmaz yani.
O &
use
fıkrasında kullanarak bir kapatma ile referans değişkenleri bağlamak mümkün olsa kullanma global
referans geçmek ve olurdu zaten bir sapma 5.3 varsayılan davranış.
$var = 'yes';
$fn = create_function('', 'global $var; $var = "no";');
$fn();
echo $var; // outputs no
Siz örneğin, olsa değer bunu kullanmak için küresel değişkeni kopya olabilir
$var = 'yes';
$fn = create_function('', 'global $var; $tmp = $var; $tmp = "no";');
$fn();
echo $var; // outputs yes
Fonksiyonu oluşturulduğunda (bağlı) değerlendirilir ama olmayacak (create_function
kullanırken) ek olarak, küresel değişkenin değeri fonksiyon çalıştırıldığında
$var = 'yes';
$fn = create_function('', 'global $var; $tmp = $var; return $tmp;');
$var = 'maybe';
echo $fn(); // outputs maybe
$var = 'yes';
$fn = function() use ($var) { return $var; };
$var = 'maybe';
echo $fn(); // outputs yes
Ayrıca önemli olan
Bir nesnenin içinde tanımlanmış zaman, kullanışlı bir şey kapatma bunu açıkça ithal etmek gerek kalmadan, $ bu değişken üzerinden nesneye tam erişim olmasıdır. *Though I think this was dropped in final PHP5.3
Bu global
anahtar kelime ile imkansızdır ve ayrıca sadece kullanamazsınız $this
. create_function
ile fonksiyon gövdesini tanımlarken bir sınıftan bir özellik başvurmak için hiçbir yolu yoktur.
class A {
protected $prop = 'it works';
public function test()
{
$fn = create_function('', 'echo $this->prop;');
return $fn;
}
}
$a = new A;
$fn = $a->test();
$fn();
neden olur
Fatal error: Using $this when not in object context
To sum this up
While you can create a function importing a variable from the global scope, you cannot cannot create one using variables from another scope. And because you are technically not binding when using create_function
but importing when the created function is executed, I'd like to argue this limitation makes the closure a lambda.
EDIT: Aşağıda Onno Marsman tarafından sunulan çözüm olsa oldukça iyi. Tamamen Kapaklar taklit etmez ama uygulama oldukça yakındır.
Demek gibi Currying http://en.wikipedia.org/wiki/Currying
Daha sonra http://zaemis.blogspot.com/2009/06/currying-in-php.html
Değilse, boşver. :-)
Benim çözüm: http://techblog.triptic.nl/simulating-closures-in-php-versions-prior-to-php-5-3/
Ancak ilk argüman olarak kapatılması için bir nesne içindeki değişkenler geçmek yok.
Bunu bazı özel durumlar vardır.
Eğer (referans değil) değerine göre bir değişken yakalamak gerekir ve değeri daha sonra yukarıda bir dizi, dize veya dizi (nesneler ve kaynaklar ve fonksiyonları gibi türleri başvuramaz) gibi basit bir değer türü, sadece can ise kullanarak fonksiyon tanımı içine yerleştirin var_export()
:
$var = array(1, 3);
$f = create_function('',
'$var=' . var_export($var,true) . '; return $var;');
Eğer, fonksiyonun çağrıları karşısında kesilebilir durumunu korumak amacıyla referans değişkeni yakalamak için, ancak bir akümülatör oluşturmayı yarattığı orijinal kapsamında yansıyan değişiklikleri (örneğin olması gerekmez gerekiyor ama eğer değişiklikler toplamı) oluştururken kapsamında toplam değişkeni değiştirmek gerekmez, o zaman aynı şekilde yerleştirin, ancak statik bir değişken olarak yapabilirsiniz:
function make_accumulator($sum) {
$f = create_function('$x',
'static $var=' . var_export($var,true) . '; return $var += $x;');
return $f;
}