PHP 5.3.0 'da, fonksiyon "kullanımı" nedir

4 Cevap php

Ben bazı php 5.3.0 özelliklerini kontrol ve oldukça komik görünüyor sitedeki bazı kod karşılaştım ediyorum:

public function getTotal($tax)
{
    $total = 0.00;

    $callback =
        /* This line here: */
        function ($quantity, $product) use ($tax, &$total)
        {
            $pricePerItem = constant(__CLASS__ . "::PRICE_" .
                strtoupper($product));
            $total += ($pricePerItem * $quantity) * ($tax + 1.0);
        };

    array_walk($this->products, $callback);
    return round($total, 2);
}

as on of the examples on : http://www.php.net/manual/en/functions.anonymous.php

Does anybody know about this ? Any documentation? And it looks evil, Should it ever be used?

4 Cevap

Bu PHP closure ifade nasıl. Bu hiç de kötü değil ve aslında oldukça güçlü ve yararlıdır.

Temelde ne Bunun anlamı kapsam dışında (bu durumda $tax ve $total bir başvuru) yerel değişkenleri "yakalama" ve onların değerlerini korumak için anonim fonksiyonu sağlayan olmasıdır (ya da $total kendisine $total referans durumunda) anonim işlev kendi içinde durum olarak.

Daha basit bir cevap.

function ($quantity) use ($tax, &$total) { .. };

  1. Kapak bir değişkene atanmış bir fonksiyondur, böylece etrafında iletebilirsiniz
  2. Bir kapatma normalde, bu ad dışında tanımlanan değişkenlere erişemezsiniz, ayrı bir ad alanıdır. use Anahtar kelime geliyor:
  3. use erişim sağlar (kullanım) kapatılması içindeki başarılı değişkenler.
  4. use erken bağlama olduğunu. Bu değişken değerleri kapatılmasını tanımlayan üzerine KOPYALANAN demektir. Bu nedenle, kapağın iç $ vergi modifiye harici bir etkisi vardır.
  5. Sen & $ toplam durumunda olduğu gibi işaretçiler gibi değişkenler iletebilirsiniz. Bu şekilde, $ toplam değerini değiştirerek harici bir etki, orijinal değişkenin değerini değişiklik var mı.
  6. Böyle kapatılması içinde kullanılmak için değişkenler yeniden adlandırabilirsiniz:

    function ($quantity) use ($tax, &$total as $alias) { .. };

  7. Kapağın içinde tanımlanmış değişkenler ya kapatılması dışından erişilebilir değildir.
  8. Kapaklar ve işlevleri aynı hıza sahip. Evet, komut üzerine hepsini kullanabilirsiniz.

Bu yardımcı umuyoruz.

kapanışları güzel! onlar anonim fonksiyonları ile gelen sorunların çoğunu çözmek, ve (en azından sürece biz php hakkında konuşmak gibi) gerçekten şık kod mümkün kılar.

bağlı değişkenler açıkça tanımlanmış değildir, çünkü javascript programcılar, hatta bazen bilmeden, Closures her zaman kullanabilirsiniz - bu "kullanmak" ne php içindir.

Yukarıda biri daha gerçek dünya örnekleri vardır. Bir alt-değer tarafından bir boyutlu bir dizi, ama önemli değişiklikleri sıralamak söylüyorlar sağlar.

<?php
    function generateComparisonFunctionForKey($key) {
        return function ($left, $right) use ($key) {
            if ($left[$key] == $right[$key])
                return 0;
            else
                return ($left[$key] < $right[$key]) ? -1 : 1;
        };
    }

    $myArray = array(
        array('name' => 'Alex', 'age' => 70),
        array('name' => 'Enrico', 'age' => 25)
    );

    $sortByName = generateComparisonFunctionForKey('name');
    $sortByAge  = generateComparisonFunctionForKey('age');

    usort($myArray, $sortByName);

    usort($myArray, $sortByAge);
?>

Uyarı: denenmemiş kodu (i PHP5.3 yüklü atm yok), ama böyle bir şey gibi görünmelidir.

Tek dezavantajı var: Eğer kapanışları ile yüzleşmek durumunda php geliştiricileri bir sürü biraz çaresiz olabilir.

Daha kapaklar güzel-ty anlamak için, sana başka bir örnek vereyim - javascript bu kez. sorunlardan biri kapsam belirleme ve tarayıcı doğasında asynchronity olduğunu. Özellikle, bu window.setTimeout(); (ya da-aralık) gelirse. parametrelerini sağlayan kodu çalıştırır, çünkü böylece, sen setTimeout bir fonksiyonu geçmek, ama sen gerçekten herhangi bir parametre veremem!

function getFunctionTextInASecond(value) {
    return function () {
        document.getElementsByName('body')[0].innerHTML = value; // "value" is the bound variable!
    }
}

var textToDisplay = prompt('text to show in a second', 'foo bar');

// this returns a function that sets the bodys innerHTML to the prompted value
var myFunction = getFunctionTextInASecond(textToDisplay);

window.setTimeout(myFunction, 1000);

myFunction bir tür-önceden tanımlanmış parametre ile bir işlevi döndüren!

Dürüst olmak gerekirse, ben php 5.3 ve anonim fonksiyonlar / kapanışları beri çok daha fazla seviyorum. ad alanları daha önemli olabilir, but they're a lot less sexy.

PHP aliasing için çeşitli "kullanımı", bir / (http://php.net/manual/en/language.namespaces.importing.php) ve kapaklar için başka ithal vardır.

Bu çok kafa karıştırıcı.