PHP yöntemleri çağrıları Intercepting

4 Cevap php

Ben statik yöntemlerle bir sınıf var ve ben yöntemleri denir önce yöntem çağrıları önünü istiyorum.

Ben çağrı Yani eğer

$model = DataMapper::getById(12345);

sonra ben bu yöntemi çağrılmadan önce DataMapper bazı yöntem denilen olmak istiyorum, ve sonra isteğe bağlı olarak bu müdahale yöntem sonradan kendini :: GetById (12345) çağırabilirsiniz. Bunu yapmak için bir yolu var mı?

Benim sunucuda Memcache uygulama ediyorum, bu yüzden yöntem çağrıları önünü istiyorum bu yüzden. Ben modelleri zaten önbelleğe ise statik yöntemler veritabanını sorgulamak istemiyorum, ve ben de memcache desteklemek için, gereğinden fazla, farklı mapper yöntemlerinin yüzlerce değiştirmek zorunda istemiyorum.

PHP 5.2.6 kullanıyorum.

4 Cevap

This'd do the job: http://stackoverflow.com/questions/1071894/triggering-call-in-php-even-when-method-exists

Sadece statik yöntemler olarak protected beyan yüzden sınıf dışında erişilemez konum ve __callStatic() sihirli yöntem onları çağırmak için olsun.

Edit:, oops bunu yapmak için 5,3 ihtiyacı olacak ...

Bu polimorfizm lehine statik yöntemleri terkediyor düşünebilirsiniz bir örnektir. Veri mapper bir arayüz ise, o zaman iki uygulamaları, veritabanı için bir ve memcache için biri olabilir:

interface DataMapper {
    public function getById($id);
    // other data mapper methods
}

class DataMapper_DB implements DataMapper {

    public function getById($id) {
        // retrieve from db
    }
    // other methods
}

class DataMapper_Memcache implements DataMapper {

    private $db;        

    public function __construct(DataMapper_DB $db, $host, ...) {
        $this->db = $db;
        // other set up
    }

    public function getById($id) {

        // if in memcache return that

        // else 
        $record = $this->db->getById($id);

        // add record to memcache

        return $record
    }
    //other methods
}

Ben sadece PHP yöntem çağrıları önünü bir yol ile geldi - Check it out.

Bu sadece basit bir örnek, ve interceptible olmak istiyorum sınıfları "opt" için var - iki sihirli yöntemlerini uygulamak gerekmez sınıfların davranışı ile müdahale edemez.

Bu ihtiyaçlarınızı karşılıyorsa bilmiyorum - ama bu desen kod üretimi veya çalışma zamanı baytkodu kesmek olmadan uygulanabilir ve bu lazım bir artı olmalı ;-)

Sana runkit ile bazı sihirli yaratabilirdi, ama sanırım son sürümü 5.2.x desteklemiyor beri, cvs gelen uzantısı derlemek gerekir

Örnek:

<?php

/* Orig code */
class DataMapper {
  static public function getById($value) {
    echo "I'm " . __CLASS__ . "\n";
  }
}


/* New Cache Mapper */
class DataMapper_Cache {
  static public function getById($value) {
    echo "I'm " . __CLASS__ . "\n";
  }
}


// Running before rename and adopt
DataMapper::getById(12345);

// Do the renaming and adopt
runkit_method_rename('DataMapper', 'getById', 'getById_old');
runkit_class_adopt('DataMapper','DataMapper_Cache');

// Run the same code..
DataMapper::getById(12345);

?>

Output:
  I'm DataMapper
  I'm DataMapper_Cache