PHP ile aslında 5 ile beraber bize lambda operatörü olmasa da aynı kolaylığı sağlıyordu.! In line functions ozelliği olmasa bunu kullanmanın bir yolunu buluyorduk. Anonymous fonksiyonlar olmasa da create_function ile aynı işi görebiliyorduk. Eventlarımızı call_user_func ile hallediyorduk.
Javascript yazarken hep keşke phpde de olsa dediğim in line functions ve lambda phpde closures ile beraber 5.3 te en esnek halini almış. kapalı fonksiyonlara da use parametresiyle çare bulmuşlar.
0 | $myLambda= function($adi,$soyadi) { return $adi.' '.$soyadi;}; |
isimsiz fonksiyonumuz artık $myLambda(“Tufan”,”YILDIRIM”) gibi çağrılabilecek. lambda fonksiyonu objesini incelemek istediğimizde türünün Closures olduğunu goruyoruz. Reflection olayını kolaylaştırma amaçlı yaptıkları Closures sınıfı incelenince anlaşılabiliyor.
0 1 2 3 4 5 6 7 8 | object(Closure)#1 (1) { ["parameter"]=> array(2) { ["$adi"]=> string(10) "<required>" ["$soyadi"]=> string(10) "<required>" } } |
bu sınıfla bebaber incelememiz gereken bir de sihirbaz metod var “__invoke” C# ın Type sınıfını (Reflection olaylarının temeli) script esnekliğiyle sunabilmişler. bu olayların hepsi aslında php nin ” eval() ” yeteneğiyle dolaylı da olsa yapabiliyorduk. başlıca Reflection elemanlarını da kısaca verelim
get_included_files();
get_defined_constants();
get_defined_functions();
get_defined_vars();get_declared_classes();
get_declared_interfaces();get_called_class();
get_class_methods();
get_class_vars();
get_parent_class();
get_object_vars();get_extension_funcs();
get_loaded_extensions();gettype();
bu elemanlar bize self debugginden tutun da reflection olaylarına kadar cok iyi yardımcı olabiliyor. metodların işlevleri isimlerinden de anlaşılabildiği için fazla ayrıntıya girmiyorum . php.net ten inceleybilirsiniz. şimdi bahsettiğimiz __invoke metodunu incelelim
0 1 2 3 4 5 6 7 8 9 | <?php class Lambda{ private $adi="Tufan Barış"; public function __invoke($soyadi){ return $this->adi.' '.$soyadi; } } ?> |
bu sınıftan bir objeyi Lambda gibi ($Object()) kullanmaya kaltığımızda tetiklenecek olan metod işimize ne kadar yaraycak bilmiyorum (Çok yetenekli bir plugin sistemi yapılabilir) ama reflection adına güzel bir çalışma olmuş. bkz: C# ta MethodInfo.Invoke
kullanıcı tanımlı parametreler dışında bir de dışardan aldığı de farklı çözüm bulmuşlar demiştik şimdi bir de kullanıcının verdiği parametreler dışında alabileceği değişkenleri inceleyelim.
0 1 2 3 4 | $ikinciAdi="Barış"; $myLambda= function($adi,$soyadi) use ($ikinciAdi) { return $adi.' '.$ikinciAdi.' '.$soyadi;}; echo $myLambda("Tufan","YILDIRIM"); // output : Tufan Barış YILDIRIM |
Lambda Okunaklığı arttırır.
0 1 2 3 4 5 6 7 | function replace_spaces ($text) { if (!function_exists ('replace_spaces_helper')) { function replace_spaces_helper ($matches) { return str_replace ($matches[1], ' ', ' ').' '; } } return preg_replace_callback ('/( +) /', 'replace_spaces_helper', $text); } |
örneğimizi inceleyelim ilk once. bu metod örnekte replace_spaces fonksiyonu içinde isim verilerek bir fonksiyon daha tanımlanmış. bu fonksiyon her tetiklendiğinde tekrar oluşmaması için de function_exists() ile kontrol edilmiş. okunması zor ve oluşan hataları takip etmesi de zor. lambda örneğini de birazdan inceleyeceğiz.
Not : Lambda runtime’da metod cağırma sınıf tanımlama yöntemi değildir. php bunu zaten yapar. bkz : __call,
Lambda objeleri parametre olarak “callback” ya da “funcname” isteyen her heryerde kullanılabilir olarak tasarlanmıştır. aşağıdaki orneklerin inceleyelim.
$lambda (); // doğru kullanım
call_user_func($lambda); // doğru kullanım
call_user_func_array($lambda, array()); // doğru kullanım
üç örnekte de gördüğümüz gibi $lambda objemiz hem metod gibi hem callbackName gibi hem de funcName gibi kullanılabiliyor.
lambda tekrar oluşturulmada hata vermez cünkü eşsiz bir isimle oluşturulur.
örnek :
0 1 2 3 4 5 | function replace_spaces ($text) { $replacement = function ($matches) { return str_replace ($matches[1], ' ', ' ').' '; }; return preg_replace_callback ('/( +) /', $replacement, $text); } |
lambda fonksiyonların en cok sevindiren ozelliği de inline yazılabilmesi :
örnek :
function replace_spaces ($text) {
return preg_replace_callback ('/( +) /',
function ($matches) {
return str_replace ($matches[1], ' ', ' ').' ';
}, $text);
}
Kapalı Fonksiyon desteği:
0 | function (normal parameters) use ($var1, $var2, &$refvar) {} |
OOP kullanımda Clousers
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class Example { private $search; public function __construct ($search) { $this->search = $search; } public function setSearch ($search) { $this->search = $search; } public function getReplacer ($replacement) { return function ($text) use ($replacement) { return str_replace ($this->search, $replacement, $text); }; } } $example = new Example ('hello'); $replacer = $example->getReplacer ('goodbye'); echo $replacer ('hello world'); // goodbye world $example->setSearch ('world'); echo $replacer ('hello world'); // hello goodbye |
sınıf içerisinde kullanılan lambdalara kapalı olarak $this in verilesi sonradan kaldırılmış ve bunun acıklaması da şurda belirtimiş
http://wiki.php.net/rfc/closures/removal-of-this
Closures objelerinin Reflection Sınıfıyla beraber kullanılması :
0 1 2 3 | $m = new ReflectionMethod ($closure); $p = new ReflectionParameter ($closure, 0); $p = new ReflectionParameter ($closure, 'a'); $p = new ReflectionParameter (array ($closure, '__invoke'), 0); // metodumuz yoksa __invoke veriyoruz |
Konuyla iligli araştırma yapmak isteyenlerin bu adresleri incelemelerini öneririm :
http://wiki.php.net/rfc/closures
http://wiki.php.net/rfc/closures/removal-of-this
http://msdn.microsoft.com/en-us/library/136wx94f(v=VS.100).aspx
http://msdn.microsoft.com/en-us/library/system.type.aspx
http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx
http://msdn.microsoft.com/en-us/library/bb397687.aspx
iyi çalışmalar..








[...] İlk önce PHP ‘nin bize Reflector sınıflardan önce Reflection adına sunduğu ve daha önce Lambda konusunda kısaca değindim fonksiyonları incelemek [...]