Parametre olarak anonim işlevi kullanarak dış değişkene erişim


95

Temel olarak bu kullanışlı işlevi db satırlarını işlemek için kullanıyorum (PDO ve / veya diğer şeylere bir göz atın)

function fetch($query,$func) {
    $query = mysql_query($query);   
    while($r = mysql_fetch_assoc($query)) {
        $func($r);
    }
}

Bu işlevle şunları yapabilirim:

fetch("SELECT title FROM tbl", function($r){
   //> $r['title'] contains the title
});

Şimdi diyelim ki hepsini $r['title']bir var içinde birleştirmem gerekiyor (bu sadece bir örnek).

Bunu nasıl yapabilirim? Bunun gibi bir şey düşünüyordum ama pek şık değil:

$result = '';
fetch("SELECT title FROM tbl", function($r){
   global $result;
   $result .= $r['title'];
});

echo $result;

Yanıtlar:


191

Dokümanlarda açıklandığıuse gibi kullanmanız gerekir :

Kapanışlar ayrıca değişkenleri üst kapsamdan devralabilir. Bu tür değişkenler, işlev başlığında bildirilmelidir. Değişkenleri üst kapsamdan devralmak, genel değişkenleri kullanmakla aynı şey değildir. Global değişkenler, hangi fonksiyonun çalıştırıldığına bakılmaksızın aynı olan global kapsamda mevcuttur.

Kod:

$result = '';
fetch("SELECT title FROM tbl", function($r) use (&$result) {
   $result .= $r['title'];
});

Ancak dikkatli olun (önceki bağlantıdaki yorumlardan birinden alınmıştır):

use () parametreleri erken bağlamadır - değişkenin değerini lambda işlevinin çağrıldığı noktadan ziyade lambda işlevinin bildirildiği noktada kullanırlar (geç bağlama).


1
Bu küresel yavaşlamanın kaldırılması gerekmez mi?
aziz punjani

19
+1 early binding,. Bununla birlikte, yukarıdaki örnekte use (&$result), referansla ne zaman geçildiğini tahmin ediyorum , gerçekten önemli değil?
Dimitry K

4
@DimitryK Evet, referans burada varsayılan davranışı atlamak için kullanılır (erken bağlama).
Xaerxess

3
@machineaddict temel use almaktadır erken bağlama - eğer ortalama geçici çözüm geç bağlanma için - Eğer içinden değişkeni geçerdi usereferans olarak - kullanarak &=> use (&$result)ve alter $resultanonim fonksiyonunu (ya da bir şey, o çağrıları bunu) diyoruz değişken önce
jave.web

1
Sınıf örnekleri her zaman referansla aktarıldığından, onlar için & kullanmanıza gerek kalmaz. (örneğin tamamen üzerine yazmadığınız sürece).
Joel Harkes

0

$ Func'ı yalnızca bir kez çağırmak için 'fetch'i yeniden yazmak ne olacak?

function fetch($query,$func) {
    $query = mysql_query($query);   
    $retVal = array();
    while($r = mysql_fetch_assoc($query)) {
        $retVal[] = $r;
    }
    $func($retVal);
}

Bu şekilde $ func'u yalnızca bir kez çağırır ve getirildikten sonra diziyi yeniden işlersiniz? Performanstan emin değilim, bir işlevi 200 kez çağırmak bile kulağa iyi bir fikir gibi gelmiyor.


Evet haklısın. Bununla birlikte, mysql_fetch_assoc () yerine mysql_fetch_row () kullanabilirsiniz, burada ve orada birkaç ms kazanmak istiyorsanız, bununla başa çıkmak çok zor çünkü sütun konumunuzu bilmeniz gerekir. Bunu yaparak, her biri 30 satırlık 2000 istekte 0.205'ten 0.180'e geçersiniz.
user103307
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.