PHP-класс и метод переопределения - реализация обратных вызовов

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

Я предложил перейти к (переопределению) модели, которая имеет внешнюю структуру скелета кода. Скорее всего:

|- controllers
|- models
|- views
|- core
    |- controllers
         |- Controller1.php
    |- models
    |- views

Если вы затем захотите внести изменения в Controller1.php, вы скопируете его во внешнюю структуру и внесите изменения - автозагрузчик затем загрузит соответствующие файлы, если они существуют, сначала проверив структуру Skeleton, то есть

Loader::controller('Controller1');

Однако я задавался вопросом, можно ли пойти немного дальше этого - все это хорошо и хорошо переопределяет контроллер, если изменения необходимы, но тогда любые будущие расширения ядра или исправления могут не добавляться. Поэтому я думал, что вы можете возможно создать копию файла и переопределить только вызовы сингулярных методов. Полу-пример того, что я имею в виду, выглядит следующим образом:

class Override {

public function __call($method, $args) {
    return call_user_func_array(array('Something', $method), $args); 
}

public static function __callStatic($method, $args){
    return call_user_func_array(array('Something', $method), $args);
    }

}

// Core class
class Something {

    static function doTest() {
        echo "Class something <br/>";
    }

    static function doOtherTest() {
        echo "That works <br/>";
        self::doTest();
    }

}


// Overriding class - named differently for ease of example and reasons explained later
class SomethingElse extends Override {

    private static function doTest() {
        echo "Success <br/>";
    }

 }

 // Actual function calling
 SomethingElse::doTest();
 SomethingElse::doOtherTest();

Общая идея заключается в том, что если метод не существует в исходном классе, тогда действуйте из класса "parent" (который здесь жестко задан). Однако у меня есть два вопроса с этим методом:

  • Я думаю, что у меня будут проблемы, когда классы имеют одинаковые имена
  • Если я пытаюсь переопределить метод, который впоследствии вызывает родительский класс, он будет использовать его собственную версию метода, в отличие от той, которую я пытаюсь переопределить
    • Хотя "простое" решение заключается в том, что вы должны переопределить любые методы, которые в совокупности, но больше может быть добавлено позднее.

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

Однако я задавался вопросом, может ли какой-либо из великих умов StackOverflow узнать какой-либо ответ или настройку, которая могла бы помочь решить проблемы с переопределяющей идеей метода - пожалуйста, помните, что я работаю с существующей системой, хотя идея структуры скелета - это то, что я пытаюсь реализовать, чтобы привнести какую-то форму "контроля" над тем, что изменилось. В идеале ничто в ядре не изменилось бы (по крайней мере, не сильно), когда кто-то захочет переопределить метод или аналогичный.

Ответ 1

Ну, строгое решение OO типа, несомненно, должно было распространить ваш контроллер как абстрактные интерфейсы, которые могут быть реализованы несколькими различными подходами реального мира, а затем объединены композицией по принципу inheritace.

Как я понимаю, у вас есть существующий код здесь, который вы намерены переопределить или расширить. Если ваша PHP-версия позволяет использовать черты, это также может помочь вам:

PHP 5.4: почему классы могут переопределять методы trait с другой подписью?

Ответ 2

Хорошо, мы только что решили. Черты это!

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