2009-09-03 16 views
5

Mam klasę z metodami statycznymi i chciałbym przechwycić wywołania metod przed wywołaniem metod.Przechwytywanie wywołań metod w PHP

Więc jeśli zadzwonię

$model = DataMapper::getById(12345); 

potem chcę jakiś sposób w DataMapper być wywołana przed ta metoda jest wywoływana, a następnie ewentualnie ta metoda przechwytywania można następnie zadzwonić self :: getById (12345). Czy jest jakiś sposób na zrobienie tego?

Implementuję Memcache na moim serwerze, dlatego właśnie chcę przechwytywać wywołania metod. Nie chcę, aby statyczne metody wysyłały zapytania do bazy danych, jeśli modele są już buforowane i nie chcę też modyfikować setek różnych metod odwzorowania, redundantnie, aby obsługiwać memcache.

Używam PHP 5.2.6.

Odpowiedz

1

This'd wykonać zadanie: Triggering __call() in PHP even when method exists

Wystarczy zadeklarować metody statyczne jak protected więc są niedostępne poza klasą i uzyskać __callStatic() magicznego sposobu ich powoływania.

Edit: oops, będziesz potrzebował 5.3 to zrobić ...

+0

Och, shucks. Zapomniałem, że zadałem już to samo pytanie. * kaczki * Dzięki. –

+0

Hahah, oh wow ... Nawet nie zauważyłem, że to ty. Ironiczny. – brianreavis

0

Chyba mógł stworzyć jakąś magię z runkit, ale trzeba by skompilować rozszerzenie z CVS, ponieważ najnowsza wersja nie obsługuje 5.2.x

Przykład:

<?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 
+0

To jest po prostu inne rozszerzenie PHP, jak każde inne? Jaki rodzaj wydajności wykonałbym, gdybym używał runkita w ten sposób? –

+0

Zobacz przykład dodany do mojej odpowiedzi ... – goddva

+0

Nie widziałem żadnych problemów z szybkością działania - Jednak nie mam żadnego kodu runkit w produkcji. Powinieneś używać runkita w przypadkach, gdy nie masz żadnych opcji .. :) – goddva

1

jest to jeden z przykładów, gdzie można rozważyć wodowania metody statyczne na rzecz polimorfizmu. Jeśli dane-mapper był interfejs wtedy można mieć dwie implementacje, jeden dla bazy danych i jeden dla memcache:

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 
} 
1

właśnie wymyślił sposób, aby przechwycić wywołania metod w PHP - Check it out.

To tylko podstawowy przykład, a zajęcia, które chcą być intercepcyjne, muszą "optować" - nie można ingerować w zachowanie klas, które nie realizują dwóch magicznych metod.

Nie wiem, czy to spełnia Twoje potrzeby - ale ten wzór może być realizowany bez generowania kodu lub kodu bajtowego Runtime hacki, a to musi być plusem ;-)

Powiązane problemy