2009-09-03 3 views
5

У меня есть класс со статическими методами, и я хотел бы перехватить вызовы методов до вызова методов.Перехват вызовов методам в PHP

Так что, если я называю

$model = DataMapper::getById(12345); 

я хочу некоторый метод в DataMapper быть вызван до вызова этого метода, а затем, возможно, этот метод перехвата может впоследствии называть себя :: GetByID (12345). Есть ли способ сделать это?

Я реализую Memcache на своем сервере, поэтому я хочу перехватить вызовы методов. Я не хочу, чтобы статические методы запрашивали базу данных, если модели уже кэшированы, и я также не хочу изменять сотни различных методов сопоставления, избыточно, для поддержки memcache.

Я запускаю PHP 5.2.6.

ответ

1

This'd сделать работу: Triggering __call() in PHP even when method exists

Просто объявить статические методы, как protected поэтому они недоступны вне класса и получить магический метод __callStatic() для вызова их.

Edit: упс, вы будете нуждаться в 5.3, чтобы сделать это ...

+0

О, скорлупки. Я забыл, что уже задал этот же вопрос. * Утки * Спасибо. –

+0

Ха-ха, о, вау ... Я даже не заметил, что это был ты. Иронический. – brianreavis

0

Я думаю, вы могли бы создать некоторые магии с runkit, но вам нужно будет скомпилировать расширение с CVS, так как последняя версия не поддерживает 5.2.x

пример:

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

Итак, это просто еще одно расширение PHP, как и любое другое? Какую производительность я бы взял, если бы я использовал runkit таким образом? –

+0

См. Пример, добавленный в мой ответ ... – goddva

+0

Я не видел никаких проблем с производительностью. Тем не менее, у меня нет никакого кода runkit на производстве. Вы должны использовать runkit в тех случаях, когда у вас нет никаких параметров. :) – goddva

1

Это один из примеров, где вы можете рассмотреть вопрос о вынужденном статических методов в пользу полиморфизма. Если данные картограф был интерфейс, то вы могли бы иметь две реализации, один для базы данных и один для: кэша

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

я просто придумал способ перехвата вызовов методов в PHP - Check it out.

Это просто базовый пример, и классы, которые хотят быть перехваченными, должны «выбирать» - вы не можете вмешиваться в поведение классов, которые не реализуют два магических метода.

Я не знаю, если это отвечает вашим потребностям - но эта схема может быть реализована без генерации кода или выполнения байт-кода писак, и это должен быть плюс ;-)

Смежные вопросы