Intereting Posts
Каким образом лучше всего использовать хэш-пароль? PHP – Как установить драйвер PDO? (Windows) PHP: отдельное значение в массиве в соответствии с порядком алфавита Как вы используете библиотеку PHP OpenPGP? проверьте, не меняется ли переменная Невозможно разобрать XML-данные с двоеточием (:) из ответа с помощью getNamespaces () IP-адрес PayPal, генерирующий ошибку HTTP 302 с использованием PHP PHP – Строгие стандарты: только переменные должны передаваться по ссылке Поиск активной поддержки математической библиотеки для php Соединение SQL в CodeIgniter с активной записью Mysql запрашивает самую последнюю запись с завихрением почему мне нужно использовать mb_convert_encoding ($ name, 'ISO-8859-15', 'utf-8'), чтобы отобразить акцентированные символы? PHP date () для JavaScript new Data () – Внутренний массив Запланированная задача на CakePHP Получить «правильный» год определенной даты с PHP DateTime

PHP: обернуть все функции класса в подкласс

Работа с классом библиотеки PHP, и я хотел бы обернуть все свои публичные функции в подкласс … Что-то вроде строк:

class BaseClass { function do_something() { some; stuff; } function do_something_else() { other; stuff; } /* * 20-or-so other functions here! */ } class SubClass extends BaseClass { function magicalOverrideEveryone() { stuff-to-do-before; // ie Display header call_original_function(); // ie Display otherwise-undecorated content stuff-to-do-after; // ie Display footer } } 

Кипятите его, я бы предпочел не переопределять каждый метод суперкласса с тем же кодом оболочки, если есть [несколько элегантный / чистый] способ сделать все это в одном месте.

Это возможно? Я подозреваю, что я нахожусь здесь в метапрограммировании земли и даже не знаю, предлагает ли PHP такого зверя, но решил, что я спрошу …

    Вы можете сделать это легко с помощью метода __call magic и общего класса «прокси», который не наследуется непосредственно из базового класса.

    Вот (почти) полная реализация проксируемого класса, который обертывает любой объект, который вы передаете. Он будет вызывать код «до» и «после» вокруг каждого вызова метода.

     class MyProxy { function __construct($object) { $this->object = $object; } function __call($method, $args) { // Run before code here // Invoke original method on our proxied object call_user_func_array(array($this->object, $method), $args); // Run after code here } } $base = new BaseClass(); $proxy = new MyProxy($base); $proxy->doSomething(); // invoke $base->doSomething(); 

    Конечно, вы хотели бы добавить немного обработки ошибок, например, просить прокси-объект, если он отвечает на данный метод в __call и поднимает ошибку, если это не так. Вы даже можете создать класс Proxy для базового класса для других прокси. Дочерние классы-посредники могут реализовывать before и after методов.

    Недостатком является то, что ваш «дочерний класс» больше не реализует BaseClass , что означает, что если вы используете BaseClass типов и хотите потребовать, чтобы в BaseClass были переданы только объекты типа BaseClass , этот подход потерпит неудачу.

    Если имена методов SubClass могут немного отличаться от первоначальных имен методов BaseClass, вы можете написать общую оболочку с __call() . Если имена методов должны совпадать, я не вижу, как вы могли бы достичь своей цели, не перезаписывая каждый метод вручную. Может быть, вы можете использовать funcall PECL для этого, но вы должны иметь возможность загрузить этот PECL в первую очередь.

    Если вы можете protected методы BaseClass, то будет работать подход __call() в SubClass.

    Если вам не нужно расширять класс, подход @ meager идеально подходит. Обратите внимание, что __call () и call_user_func_array () действительно налагают определенные накладные расходы.

    Если я правильно понимаю, вы хотите расширить класс, но не разрешать вызовы методов из родительского объекта. Вместо этого вы хотите вызвать все методы самостоятельно одним методом в новом классе.

    Итак, почему вы даже хотите наследовать в первую очередь? Это звучит очень похоже на то, что вы должны просто создать адаптер / декоратор для вашего BaseClass.

     class SubClass { function magicalOverrideEveryone() { BaseClass bc = new BaseClass(); bc.do_something(); bc.do_something_else(); } } 

    вы можете искать шаблон декоратора:

     class A { function do1(){ } } class DecoratorForA extends A { private A original; public DecoratorForA( A original ) { this.original = original; } function do1(){ //<-- override keyword in php? stuffBefore(); original->do1(); stuffAfter(); } } - class A { function do1(){ } } class DecoratorForA extends A { private A original; public DecoratorForA( A original ) { this.original = original; } function do1(){ //<-- override keyword in php? stuffBefore(); original->do1(); stuffAfter(); } } 

    потому что это не то, что вы хотите, может быть, эта ссылка поможет? http://code.google.com/p/php-aop/