У меня есть код на основе пространства имен с папкой «Модель». Я называю свои модели статически везде в моем коде:
\Myapp\Model\PersonModel::doSomething()
Теперь я хотел бы распространить свое приложение в нескольких странах и иметь возможность переопределить некоторые функции PersonModel для некоторых стран (и добавить модели для некоторых стран и т. Д.).
У меня будет:
\MyApp\Model\France\PersonModel::doSomething()
Я хотел бы иметь возможность использовать специализированную версию, имея в виду:
Одним из решений было бы специализировать каждый контроллер для каждой страны и везде использовать полные имена, но я не уверен, что это реалистично (отнимает много времени и, возможно, даже не работает).
Другим решением было бы переопределить каждую модель и добавить куда-нибудь функцию, которая давала бы мне имя полностью определенного класса (для текущей страны), но код стал бы уродливым, и я потерял бы завершение кода.
Третье решение — создать репозиторий для каждой страны и попытаться изменить все так, чтобы основной код находился в подмодуле Git, а все остальное — специализированные классы … Мне кажется, это лучшее решение, но похоже, что работа на Титане, и я бы предпочел, чтобы все страны в одном и том же хранилище держали все под контролем.
У меня действительно нет другой идеи. Я уверен, что я не единственный с этой проблемой, но я искал и ничего не нашел. Пожалуйста, скажите мне, что есть волшебная особенность для пространств имен, о которой я не знал, или что-то еще? 🙂
Изменить: это частично решено
Сейчас я использую собственный автозагрузчик, который загружает соответствующий класс для конкретной страны. Но все страновые классы будут разделять так же пространство имен (которое будет работать, потому что мы используем только одну страну в данный момент времени). Тем не менее, я теряю завершение кода, но это компромисс, с которым я в порядке. Если у кого-то есть решение, которое бы также Позвольте сохранить код завершения, пожалуйста, не стесняйтесь ответить!
Еще одна идея, вытекающая из моих мыслей в комментариях. Переместить это:
\Myapp\Model\PersonModel
здесь (случайное местоположение, так как я не знаю вашу территорию по умолчанию):
\Myapp\Model\Germany\PersonModel
Теперь у вас будет два класса со страной в пространстве имен, и, конечно, вы можете добавить больше. Теперь вы можете добавить новый обобщенный класс, таким образом:
namespace \Myapp\Model;
/*
* Document your methods here using @method, so you get autocompletion
*/
class PersonModel
{
public function __callStatic($name, $args)
{
// Convert the call to an appropriate static call on the correct class.
// The first parameter is always the country name, which you can examine
// and then remove from the list. Throw an exception if $args[0] is
// empty.
}
}
Затем вы можете сделать это:
\MyApp\Model\PersonModel::doSomething('France', $args);
Использование @method
(посмотреть здесь) обеспечит автоматическое заполнение, и вы сможете больше узнать о вызовите магические методы здесь.
Конечно, убедитесь, что ваши языковые классы ссылаются на родительский класс, чтобы не дублировать большие фрагменты кода. Некоторые методы могут также не заботиться о языке, и в этом случае они могут войти в \Myapp\Model\PersonModel
с тем преимуществом, что им не нужны записи phpdoc вручную.
Хорошо, я нашел глобально удовлетворительное решение:
Все страновые классы будут делиться так же пространство имен (например, «Myapp \ Model \ Custom *»), которое не вызовет конфликтов, поскольку одновременно существует только одна страна.
Пользовательский автозагрузчик загрузит соответствующий класс / файл в зависимости от текущей страны.
Недостатками этого решения являются:
Преимущества:
Пожалуйста, не стесняйтесь размещать более элегантное решение, я буду рад его прочитать (и принять)!