2010-02-27 11 views
5

aynı nesne yöntemi kullanarak. Bulduğum bir şey, birden fazla fonksiyon arasında mantığı kopyaladığım.

Basitleştirilmiş örnek:

class Configurable{ 

    protected $configurations = array(); 

    protected static $static_configurations = array(); 

    public function configure($name, $value){ 

     // ...lots of validation logic... 

     $this->configurations[$name] = $value; 

     } 

    public static function static_configure($name, $value){ 

     // ...lots of validation logic (repeated)... 

     self::$static_configurations[$name] = $value; 

     } 

    } 

Ben buna bir çözüm bulduk, ama gerçekten kirli hissediyor: Ben boyunca yapılandırmaları ayarlayabilirsiniz böylece

class Configurable{ 

    protected $configurations = array(); 

    protected static $static_configurations = array(); 

    public function configure($name, $value){ 

     // ...lots of validation logic... 

     if (isset($this)){ 
      $this->configurations[$name] = $value; 
      } 
     else{ 
      self::$static_configurations[$name] = $value; 
      } 

     } 

    } 

Ben de statik işlev gerekir uygulama. Ayrıca, bu teknikle güzel olan şey, her iki kapsamda da aynı yöntem isimlerini kullanabilmem.

böyle test kapsamı ile herhangi bir sorun var mı? Performans sorunları, ileri uyumluluk sorunları, vb. Her şey benim için PHP 5.2'de çalışıyor ve < 5 desteğine ihtiyacım yok.

cevap

2

Hata bildiriminde hataya yol açacak ikinci yöntem sorunudur. E_STRICT olarak ayarlanmıştır. Örneğin:

sıkı standartlar: Non-statik yöntem fan :: çubuğu() hattı üzerinde /home/yacoby/dev/php/test.php statik olarak değil denilen 10

bir PHP6 ile nokta, E_STRICT hatalarının E_ALL'ye taşınmasıdır. Diğer bir deyişle, E_ALL statik olmayan yöntemleri statik olarak çağırmanıza izin vermemek de dahil olmak üzere tüm hataları kapsayacaktır.

alternatif bir yöntem, bir statik işlevi doğrulama mantığını taşımak olabilir. Bu şekilde statik olmayan işlev ve statik işlev, doğrulama mantığını çağırabilir.

+1

Tamam, katı hatadan başka, ikinci yöntemle ilgili herhangi bir sorun var mı? Muhtemelen tavsiyelerinizde bunu değiştireceğim ama bu gibi kodları kullanarak gerçek sorunları anlamak isterim. Gelecekteki PHP sürümlerinden kaldırılması olası bir özellik midir yoksa statik olmayan yöntemleri statik olarak her zaman arayabilecek misiniz? – Rowan

+1

'E_STRICT' hataları," Bu gerçekten kötü bir fikir gibi görünüyor, ancak yine de yapmaya çalışmanıza izin vereceğiz. " Böyle bir şeyin her zaman işe yaracağına dair bir garanti yoktur, ancak muhtemelen tamamen kullanımdan kaldırılmadan önce “E_NOTICE” veya “E_WARN” e dönüştürülecektir. – MightyE

+0

@MightyE – Rowan

2

Statik yöntemler nesnel muadili daha argümanlar farklı sayıda gerektirecektir - ek bağımsız değişken bir yürütme içeriği olacaktır. Yürütme bağlamı yoksa, yalnızca statik olarak adlandırmak anlamlıdır. Benim tercih edilen yaklaşım Böyle çoklu arayüze sahip olan bir kütüphane inşa ediyorum düşünülürse

, statik sınıf ve dinamik bir sınıf yaratmaktır. Bir vekilini diğerine çağır. Örneğin:

class DynamicClass { 
    protected $foo; 
    protected $bar; 
    public function baz($arg1) { 
     return StaticClass::bar($this->foo, $arg1); 
    } 
    public function zop($arg1, $arg2) { 
     return StaticClass::zop($this->foo, $this->bar, $arg1, $arg2); 
    } 
    // Context-less helper function 
    public function womp($arg1) { 
     return StaticClass::womp($arg1); 
    } 
} 

class StaticClass { 
    public static function baz(&$fooContext, $arg1) { ... } 
    public static function zop(&$fooContext, &$barContext, $arg1, $arg2) { ... } 
    public static function womp($arg1) { ... } 
} 

Bu tam olarak nasıl statik sınıfına içeriğini geçirmek size kalmış - sizin için mantıklı ne gerekiyorsa yapmaya gerekecek. Çoğu fonksiyonda yapılan iş oldukça küçük olmalıdır (eğer çok çalışıyorsanız, muhtemelen bir kural olarak daha küçük fonksiyonlara çalışmanız gerekir) ve bu yüzden sadece bir kaç bağlam argümanı gerektirmelidir. Yoksa tam bağlam dizi oluşturmak ve sadece her çağrı önce DynamicClass ya da doldurma (her yerde o geçmesi, ya da başka hızlı & kolayca etrafında geçebilir böylece dizideki tüm DynamicClass özelliklerini izini sürebilir.


aslında rağmen o bir Singleton tasarım deseni yarar olabilir gibi görünüyor. ne görebilirsiniz itibaren, singleton tasarım deseni ile, oluşturun. global Configurable yaratmaya çalışıyoruz ve aynı zamanda bireysel yerel Configurable s oluşturma seçeneğine sahip olduğunuz Bir sınıfın küresel olarak erişilebilir bir versiyonunu (yalnızca OOP tasarım prensiplerini ihlal etmeden ve $ _GLOBALS vb.Örneğin:

class DynamicClass { 
    protected $foo; 
    protected $bar; 

    public function baz($arg1) { ... } 
    public function zop($arg1, $arg2) { ... } 

    public static function getSingleton() { 
     static $instance = null; 
     if ($instance === null) $instance = new DynamicClass(); 
     return $instance; 
    } 
} 

kodunuzda Nerede olursanız, size DynamicClass::getSingleton() ile aynı örneğine erişim elde edebilirsiniz. Ayrıca, bir kerelik tekil olmayan sürümler oluşturma seçeneğiniz de vardır. Sadece her iki dünya için de en iyisini elde edersiniz, sadece tüm yöntemlerinizi sadece akılda tutarak dinamik erişim ile yazmak zorundasınız.

2

o kadar saçma statik yanı örneğinde bir yöntemi çağırmak izin ve bulmuyorum. Benim durum: boş/yeni mantık ile benim sınıf fırsatlar

TestRecord::generateForm(); // Generate an empty form. 

    $test = new TestRecord($primaryKey); 
    [...] 
    $test->generateForm();  // Generate an edit form with actual $test values. 

Statik tarafı örneği tarafı canlı veri kullanılır manasına gelmektedir.

public function __call($name, $args) 
{ 
    if ($name == 'generateForm') { 
    $this->fields = static::createFields(); // Action 1 : static. 
    $this->fillFields();      // Action 2 : instance. 
    static::renderForm($this->fields);  // Action 3 : static. 
    } 
} 

public static function __callStatic($name, $args) 
{ 
    if ($name == 'generateForm') { 
    $fields = static::createFields();  // Action 1 : static. 
              // Action 2 : none. 
    static::renderForm($fields);   // Action 3 : static. 
    } 
} 

Not:

PHP 5.3 __call, __callStatic ve static:: kullanarak elde sağlar static:: geç bağlama niteleyici zaman 3 aksiyon yöntemleri (createFields, fillFields ve rendreForm) uygulanmaktadır için kullanılır abstract olan alt sınıflarında protected olarak belirtilmiştir. Bu, PHP'nin korunan üyelere her iki yönde de erişmesine izin vermesi nedeniyle mümkündür: tabandan alt sınıfa, ancak alt sınıftan üst sınıfa da. Bildiğim kadarıyla diğer OO dillerinden farklı.

-1

çekirdek php olarak biz çok kullandığımız gereken oop php aynı şeyi yapmak, index.php?var= kullanın.

İlgili konular