PHP 6'da Olması Gereken Özellikler

December 4, 2008

Hayalini kurduğum framework için çıktığım yolda hergün yeni şeyler öğreniyorum. İtiraf etmem gerekiyorki ASP.NET mimarisinden çok etkilendim. Yazılım mimarileri ile uğraştığımdan dolayı sanırım C# diline ayrı bir sempatim var. Her açıdan çok iyi tasarlanmış bir dil. PHP’de web için biçilmiş kaftan fakat nesne yönelimli mimariler geliştirirken çok eksik olduğunu görüyoruz. Neden C# değilde PHP yazdığım sorusu aklınıza gelebilir. Bunun en büyük sebebi, C# projesinin Windows gibi baş ağrıtan kötü bir işletim sistemi üzerinde koşması geliyor. Mono ile daha önce bir web projesi geliştirmiş biri olarak yetersiz olduğunu söyleyebilirim.

Bu yazıda PHP6’da olması gerektiğini düşündüğüm özelliklerden söz edeceğim. Öncesinde küçük bir araştırma yaptım. Benim gibi PHP6 beklentileri olanlar var mı diye? Stephan Schmidt‘in 6 parçadan oluşan yazısı görmeliler.

  1. Namespaces
  2. Annountions
  3. Type Hint
  4. Reflection
  5. Delegate & Event & Lambda
  6. Function overloading
  7. Properties (Variable Get/Set)
  8. Extensions Methods & Partial Class

1. Namespaces

Eğer bir framework yazıyorsanız birbirine benzeyen sınıf isimleri olması çok doğaldır. Bu durumlarda namespace’ler olması çok işe yarar. Neyse ki PHP 5.3’ten itibaren gelecek olan bir özellik. (Ref. http://marc.info/?l=php-internals&m=118355320225178&w=2)

2. Annountions

C#’ta buna Attribute denir. Amaç kod içine meta veriler sokmaktır. Ve bu verileri Reflection yöntemiyle dinamik olarak okuyarak işleme tabii tutmaktır.

Bir örnek ile açıklamak gerekirse, MVC yapısı kurduğumuzu düşünün. Her sınıfın bir sayfa her methodununda action/view işlemini yaptığını varsayalım. Action bazlı sayfa giriş yetkilendirmesine ihtiyacımız var. Bu sayfa eğer ödeme sayfası ise, sadece https olarak erişilmesi gerekiyor. Bunuda bir şekilde belirtmek gerekir. İşte bu gibi ihtiyaçları tanımlamak için annountions özelliğine ihtiyacımız var. Henüz resmi olarak desteklenmesede PHP genişletmeleriyle eklenebilir.

@SimpleAnnotation
@SingleValuedAnnotation(true)
@SingleValuedAnnotation(-3.141592)
@SingleValuedAnnotation('Hello World!')
@SingleValuedAnnotationWithArray({1, 2, 3})
@MultiValuedAnnotation(key = 'value', anotherKey = false, andMore = 1234)

(Ref. http://code.google.com/p/addendum/)

3. Type Hint

Method parametreleri veya değişken tanımlarında, değişkenin tipini yazmak hem okunabilirliği arttırır. Hem de editörlerin kod tamamlama özelliğini daha sağlıklı yapılmasına imkan sağlar. Ayrıca hata yakalama işlemlerinde de büyük kolaylık sunar.

4. Reflection

Reflection dinamik olarak kod içerisinde gezinebilmeyi, kodu kısmen değiştirebilmeyi sağlar. Mesela; MVC’deki authentication işlemlerini sayfa sınıfının protected olan methodları için yap diyebiliriz.

self::set_module_name($class_name);
self::set_action_name($method);

eval("\$class = new $class_name();");
$reflect = new ReflectionMethod($class_name, $method);
if ($reflect->isProtected()) {
$class->authentication();
}
call_user_method_array($method, $class, $method_arguments);

Ayrıca reflectionlar sayesinde Dependency Injection diye adlandırılan mimariler yaratabiliriz. Dependency Injection, Bir kod parçasına dışarıdan müdahale etmek demektir. Örneğin bir scheduler uygulaması yazacaksınız. Bu schedulera “şu sınıfın şu methodunu” çalıştır demek için kullanabilirsiniz.

(Ref. http://tr2.php.net/reflection)

5. Delegate & Event & Lambda

Delegate kavramı C# ile beraber hayatımıza girmiştir.  Aslında C programcılarının bildiği gibi delegate’ler, fonksiyon göstericileridir. C# gibi dillerde sınıflar arasında global kavramı olmadığı için bir sınıftan diğerine mesaj yaptırmak  gerekebiliyor bazı durumlarda. İtiraf etmem gerekir ki bu bizi event mimarilerine ve lambda operatörüne götürür.  Delegate kullanımı C’deki prototip tanımlanması gibidir.

public delegate function int myDelegate(int $x);

Bu şu anlama gelir. Geri dönüş değeri int olan ve parametresi int olan fonksiyonu işaret et. Görüldüğü üzere bu tanım bize başka bir ihtiyaç daha doğurur. type hint ve method signs kavramları. Dinamik bir dilde bu kadar tip güvenli kod rahatsız etmiş olabilir. C# dilinde bunun çözümü lambda operatörüdür.

Lambda, kısaca değişken olarak tanımlanabilen process blockları demektir. İstenilen yerde yaratılır ve öldürülür.

6. Function overloading

Fonksiyon yazarken farklı parametrelerle aynı method adıyla yazabilme  durumudur function overloading.  Bilindiği üzere PHP dilinde parametre sınırı yok. İstenildiği kadar parametre girilebilir. Bu parametrelerin dinamikliği sayesinde, aynı method ismi ile farklı parametrelerde func_get_arg alınabilir. Fakat okunabilirliği zorlaştıracak bir kod bloğu oluşmasına sebep olur. Bunu desteklerken bu dinamik yapının kaldırılmasını elbette istemeyiz.

Method overloading yapabilmek için methodların imzasını tutmak gerekir. Bu imza parametrelerin tipleri ve geri donus deger tipleri ile birlikte oluşturulur.

int function fonk(int $b); int function fonk(int $b, string $c); Yukarıdaki örnek PHP'de syntax hatasına sebep olur. 7. Properties (Variable Get / Set) Properties kavramı C# dilinde kullanılan Cross-Cutting yada Aspect oriented denilen bir teknolojidir. Amacı sınıf değişkenlerinin aldığı değerlerin arasına girmenin bir yolunu bulmaktır. Özellikle get ve set işlemlerinin arasına girmek türetilen sınıflarda overloading yöntemi ile farklı bir şekilde değer atanmasını veya değer kontrolunun yapılması burada sağlanabilir.

private $_item; public property $Item { get { return $this->_item; } set { $this->_item = value; } } $this->Item = 4; Yukarıdaki kod blogu gibi olmasada AOP yontemiyle dolaylı olarak yapabilmek mümkün. Bunun için PHP Aspect'ten faydalanılabilir. 8. Extensions Methods & Partial Classes Aslında bu iki özellik betik(script) olan bir dilde ne gerek var diye düşünebilirsiniz. Bu iki özellikte özellikle projelere dahil olan 3. parti yazılımların bakımını yaparken çok işimize yarar. Genellikle 3. parti yazılımları projenin içine dahil ederken ufak değişiklikler yapar ve projeyi bir bakıma çatallamış (fork) etmiş oluruz. Yeni versiyon geçişlerinde ise sıkıntı yaşarız. Bunu engellemek için başka bir yerde bu 3. parti yazılımların sınıflarını genişletebilsek (partial class) veya methodlarını aşırı yükleye bilsek (extensions methods) hayat daha güzel bir hale gelebilir. Peki bunu nasıl yaparız? extend function string::is_null(string $value) { return ($value == null);  } Yukarıdaki şekilde tanımlanabilir. string nesnesi için is_null adında bir method eklenmiş olur. Ve aşağıdaki şekilde çalıştırılabilir. string $a = "merhaba"; if ($a::is_null()) { // biseyler yap } Partial class yapısı ise, bir sınıfı içeriğini bir parçasını aynı isimde başka bir sınıfı tanımı yaratarak onun içine atamak demektir. Bakıldığında partial class ile extensions methods'ların bir farkı olmayabilir. C# kendi tasarımlarında partial classlar aynı assembly (paket) içerisinde olmasını ön koşul olarak koşar. Fakat bu durum extensions method mimarisinde zorunlu değildir. Elbette bu iki özellik birleştirilerek daha iyi tasarlanabilir. Benim PHP'nin yeni versiyonundan beklediklerim aklıma geldiği kadarıyla bu şekilde. Aslında bunların bir kısmı PHPv6 ya alındı. Bir kısmı ise bekliyor. Daha detaylı bilgiye, Derick Rethans'ın toplantı notlarında bulabilirsiniz. Bu konu ilginizi çektiyse, toplantı notlarının yapılacak listesine ve hangilerinin yapıldığına  buradan erişebilirsiniz. Benim aklıma gelenler şimdilik bunlar. Programlama dillerine ve Nesneye Yönelimli PHP'ye yönelik yazılarımı öğrendikçe burada paylaşmaya devam edeceğim...