Судя по вашему коду, вам нужен не модуль, а компонент приложения:
class EMovieComponent extends CApplicationComponent
{
public $foo;
public function init()
{
// инициализация компонента
}
public function searchMovie($value)
{
// ...
}
}
Затем в конфиге в "components" подключаете компонент:
Спасибо за стандартное написание, но я нехочу "Ложить все яйца в одну корзину", а именно класов для работы дожно быть несколько (в данном случае 2). первый будет работать с подключением, поскольку там есть несколько своих ньансов, второй работать с данными. Можно конечно все в один клас - но это будет неудобно.
Я так понимаю это что нужен "скелет" компонента приложения который будет расширятся другими класам. А вот как должен выглядеть этот "скелет" ?
Не очень понятно, какого результата вы хотите достичь. В первом посте я вижу два обычных класса, на модуль в понимании Yii совсем не тянет. Остается их использовать либо "как есть", либо создавать Application Component?
Подключение, инициализация других классов, в общем всё, что потребуется для работы расширения (более верное название, чем "модуль"). Вся работа будет осуществляться через этот компонент.
Т.е., если хотим подключиться к сервису, то пишем:
Yii::app()->movie->connection->connect();
// теперь ищем movie
Yii::app()->movie->command->search('my movie');
movie->connection и movie->command - возвращают объекты соответствующих классов.
Получается, вы хотите работать с одним классом, но вызывать методы двух других. Тут вариантов не много:
Поместить все методы в один класс.
Delegation Pattern.
Сделать из классов Connect и Command поведения (Behavior). Выглядит проще, чем второй вариант, но совсем не гарантирует, что в момент времени t у класса будет метод search(), т.к. поведение можно в любой момент отключить.
Что такое интерфейсы, и зачем они нужны - вам лучше почитать отдельно и подробно. Я же говорю о том, что EMovieComponent должен содержать методы connect, search, lastMovie и т.д., но не реализовывать их, а вызывать методы соответствующих классов EMovieConnect и EMovieCommand. Хотя на самом деле интерфейсы здесь могут пригодится, если планируются различные типы подключений и команд, обладающих единым интерфейсом. Т.е., чтобы подключиться к ресурсу A, используются класс EMovieConnectA, а для подключения к B - класс EMovieConnectB. Оба реализуют интерфейс IMovieConnect.
Примерно так (уж не знаю, то ли это, что вам нужно):
interface IMovieConnect
{
public function openConnection();
public function closeConnection();
}
interface IMovieCommand
{
public function search($value);
}
class EMovieConnectA implements IMovieConnect
{
// реализация интерфейса IMovieConnect
}
class EMovieConnectB implements IMovieConnect
{
// другая реализация интерфейса IMovieConnect
}
class EMovie extends CApplicationComponent
{
private $connect;
private $command;
public function init()
{
if ($this->connect === null)
$this->setConnect('EMovieConnectA'); // коннект по умолчанию
// ...
}
public function setConnect($className)
{
$reflection = new ReflectionClass($className);
if ($reflection->implementsInterface('IMovieConnect'))
$this->connect = new $className();
else
throw new Exception();
}
public function setCommand($className)
{
// см. setConnect
}
public function connect()
{
$this->connect->openConnection();
}
public function search($value)
{
$this->command->search($value);
}
}
// конфиг
'components'=>array(
'movie'=>array(
'class'=>'path.to.EMovie',
'connect'=>'EMovieConnectB',
),
),
Почти то, вот только напряг в том что будет намного больше функций чем connect и search, а переопределять каждую в класе EMovie - неохота. Нужно что б определил функцию в
Тогда помогут только Behavior’ы. Но я бы посоветовал не лениться и еще раз подумать. Получается, что сначала вы хотите полностью разделить компоненты, а потом опять смешиваете их в кучу. Оставьте в классе EMovie только инициализацию этих компонентов, а нужные методы вызывайте “прозрачно”:
$movie->command->search('value');
Ведь в самом фреймворке не перемешиваются компоненты приложения. Если нужен объект для связи с базой данных, то пишем Yii::app()->db->createCommand(), а не Yii::app()->createCommand(). Последний вариант как раз является аналогией тому, что вы хотите сейчас сделать, но он явно "не тру".
Еще раз спасибо, похоже единственно нормальным решением будет объеденить это все в один класс. А там время покажет, нужно будет разделить - буду глядеть в сторону Behavior
public function init()
{
Yii::setPathOfAlias('Imagine',__DIR__.'/Imagine');
$className="Imagine\\{$this->driver}\\Imagine";
$this->_imagine=new $className;
parent::init();
}
public function __call($name,$parameters)
{
if(method_exists($this->_imagine,$name))
return call_user_func_array(array($this->_imagine,$name),$parameters);
return parent::__call($name,$parameters);
}
Не понятно, как это решает проблему. Если в классе нет метода, то метод ищется в двух других классах? Это и есть суть Behavior’ов, только здесь зачем-то это вручную реализовано.