Anonim işlevler

Anonim işlevler isim belirtmeksizin oluşturulabilen işlevlerdir. Çoğunlukla geriçağırım işlevi olarak işlev değiştirgelerinde kullanılırsa da kullanımı bununla sınırlı değildir.

Anonim işlevler Closure sınıfı kullanılarak gerçeklenir.

Örnek 1 - Anonim işlev örneği

<?php
echo preg_replace_callback('~-([a-z])~',
      function (
$match) {
       return 
strtoupper($match[1]);
      },
      
'hello-world');
// Çıktısı: helloWorld
?>

Anonim işlevler birer değişken değeri olarak da bildirilebilir. Bu durumda PHP, işlevi özdevinimli olarak sınıfının nesnel bir örneği haline getirir. Bir anonim işlev, bir değişkene sıradan bir deyim gibi, bir noktalı virgül ile biten bir işlev olarak atanabilir:

Örnek 2 - Değişkene anonim işlev atama örneği

<?php
$greet 
= function($isim)
{
    
printf("Merhaba %s\r\n"$isim);
};

$greet('Dünya');
$greet('PHP');
?>

Anonim işlevler değişkenleri üst etki alanından miras alabilirler. Böyle değişkenler use dil oluşumuna aktarılmalıdır. PHP 7.1 itibariyle, bu değişkenler süper küreseller, $this veya bir değiştirge ile aynı isimdeki değişkenleri içeremez.

Örnek 3 Değikenleri üst etki alanından miras almak

<?php
$message 
'hello';

// "use" olmaksızın
$example = function () {
    
var_dump($message);
};
$example();

// $message miras alınır
$example = function () use ($message) {
    
var_dump($message);
};
$example();

// Miras alınan deşkenin değeri işlevin tanımından gelir, çağrısından değil.
$message 'world';
$example();

// message sıfırlanır
$message 'hello';

// Gönderimle miras alma
$example = function () use (&$message) {
    
var_dump($message);
};
$example();

// Üst etki alanında değişen değer
// işlev çağrısı içinde yansıtılır.
$message 'world';
$example();

// Anonim işlevler sıradan değiştirgeleri de kabul edebilir
$example = function ($arg) use ($message) {
    
var_dump($arg ' ' $message);
};
$example("hello");
?>

Yukarıdaki örnek şuna benzer bir çıktı üretir:

Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) "hello"
string(5) "hello"
string(5) "hello"
string(5) "world"
string(11) "hello world"

Üst etki alanından miras alınan değişkenler küresel değişkenler gibi ele alınmazlar. Küresel değişkenler, işlevin çalıştığı etki alanında tanımlı değişkenlerdir. Anonim işlevin üst etki alanı ise içinde bildirildiği işlevin etki alanıdır (Anonim işlevin bildirildiği etki alanı ile çağrıldığı etki alanı aynı olmak zorunda değildir). Aşağıdaki örneğe bakalım:

Örnek 4 - Anonim işlevler ve etki alanı

<?php
// Ürünleri eklemek üzere bir Sepet oluşturalım.
// Eklenen ürünlerin toplam fiyatını döndürmek
// üzere bir geriçağırım işlevi kullanalım.
class Sepet
{
  const 
PRICE_BUTTER 1.00;
  const 
PRICE_MILK 3.00;
  const 
PRICE_EGGS 6.95;

  protected 
$ürünler = Array();


  public static function 
ekle($ürün$miktar)
  {
    
$this->ürünler[$ürün] = $miktar;
  }

 public static function 
miktarıGetir($ürün)
 {
    return isset(
$this->ürünler[$ürün]) ? $this->ürünler[$ürün] : FALSE;

  }

  public function 
Toplam($kdv)
  {
      
$toplam 0.00;

      
$işlev =
          function (
$miktar$ürün) use ($kdv, &$toplam)
          {
              
$birimFiyat constant(__CLASS__ "::FiYAT_" .
                  
strtoupper($ürün));
              
$toplam += ($birimFiyat $miktar) * ($kdv 1.0);
          };

      
array_walk($this->ürünler$işlev);
      return 
round($toplam2);
  }
}

$sepetim = new Sepet;

// Sepete birşeyler ekleyelim
$sepetim->ekle('Peynir'1);
$sepetim->ekle('Süt'3);
$sepetim->ekle('Yumurta'6);

// %5 KDV ile toplamı döndürelim
print $sepetim->Toplam(0.05) . "\n";
// sonuç: is 54.29
?>

Örnek 5 $this'in özdevinimli bağlanması

<?php

class Test
{
    public function 
testing()
    {
        return function() {
            
var_dump($this);
        };
    }
}

$object = new Test;
$function $object->testing();
$function();
    
?>

Yukarıdaki örneğin çıktısı:

object(Test)#1 (0) {
}

Yukarıdaki örneğin PHP 5.3 çıktısı:

Notice: Undefined variable: this in script.php on line 8
NULL

PHP 5.4.0 itibariyle, bir sınıf başka bir sınıfın içinde bildirildiğinde $this'i işlevin etki alanı içinde kullanılabilir kılarak özdevinimli olarak ona bağlanır. Bu özdevinimli bağlantı istenmiyorsa bunun yerine duruk anonim işlevler kullanılabilir.

Duruk anonim işlevler

PHP 5.4 itibariyle, anonim işlevler duruk olarak bildirilebilmektedir. Böylece, geçerli sınıfın özdevinimli olarak bunlara bağlanamaması sağlanabilir. Çalışma anında nesneler de özdevinimli olarak bunlara bağlanamayacaktır.

Örnek 6 - Duruk anonim bir işlevin içinde $this kullanmaya çalışmak

<?php

class Foo
{
    function 
__construct()
    {
        
$func = static function() {
            
var_dump($this);
        };
        
$func();
    }
};
new 
Foo();

?>

Yukarıdaki örneğin çıktısı:

Notice: Undefined variable: this in %s on line %d
NULL

Örnek 7 - Duruk anonim bir işleve bir nesne bağlamaya çalışmak

<?php

$func 
= static function() {
    
// işlev gövdesi
};

$func $func->bindTo(new StdClass);
$func();

?>

Yukarıdaki örneğin çıktısı:

Warning: Cannot bind an instance to a static closure in %s on line %d

Sürüm Bilgisi

Sürüm: Açıklama
7.1.0 Anonim işlev değişkenleri süper küreseller, $this veya bir değiştirge ile aynı isimdeki değişkenleri içeremez.
5.4.0 Duruk olarak bildirilmek koşuluyla anonim işlevlerde $this kullanılabilir.
5.3.0 Anonim işlevler kullanılabilir oldu.

Notlar

Bilginize: func_num_args(), func_get_args() ve func_get_args() işlevini bir anonim işlev içinde kullanmak mümkündür.