Интеграция 2-х систем, и конфликт глобальных объектов
Строится средненькое по крупности веб-приложение. Состоит из форума phpBB и одной коммерчесской CMS.
Проблемка заключается в следующем:
и там и там юзается объект для БД, и в обеих системах имя ему - $db. Естественно, объекты в двух системах создаются разных классов.
Конфликта как таковово нету, т.к. пхп глотает подобные вещи на уровне интерпретации кода. Однако когда скрипты phpbb пытаються обратиться к методам, скажем $db->sql_escape(), то естественно ничего не выходит, т.к. в этом конкретном месте, при обращении к $db вызывается объект объявленный в CMS , у которого такого метода нет.
Проблема при этом возникает не во всём коде, а только в некоторых скриптах phpbb (которые подключаются в скриптах cms).
Изменять имя объекта, и следовательно тормошить все скрипты как в CMS, так и в phpBB - само собой идея херовая.
Вот и мучаюсь пока, подставляя в нужные места форумных скриптов кривые костыли, заменяя global $db на что-то вроде "$db = new dbal_mysql();".
Помогите найти выход из ситтуации.
Заранее спасибо.
$db = new dbal_mysql(); - тоже большой изврат.
Юзайте синглтон класс для БД, тогда все обращение к классу с БД будет как $db = DB::getInstance() или типа того. Намного понятней и удобнее.
Ну и можно заюзать что-то типа такого (дабы не потрошить исходные классы):
Код:
class DB_PHPBB {}
class DB_CMS {}
class DB {
private $_instance_db_phpbb = null;
private $_instance_db_cms = null;
private $_instance = null;
public static $IS_PHPBB = 1;
public static $IS_CMS = 2;
private function __construct() {}
public function load($db) {
switch($db) {
case self::IS_PHPBB:
if( is_null($this->_instance_db_phpbb) ) $this->_instance_db_phpbb = new DB_PHPBB;
return $this->_instance_db_phpbb;
break;
case self::IS_CMS:
if( is_null($this->_instance_db_cms) ) $this->_instance_db_cms = new DB_CMS;
return $this->_instance_db_cms;
break;
}
}
public static function getInstance($db) {
if( is_null($this->_instance) ) $this->_instance = new DB;
return $this->_instance->load($db);
}
}
class DB_CMS {}
class DB {
private $_instance_db_phpbb = null;
private $_instance_db_cms = null;
private $_instance = null;
public static $IS_PHPBB = 1;
public static $IS_CMS = 2;
private function __construct() {}
public function load($db) {
switch($db) {
case self::IS_PHPBB:
if( is_null($this->_instance_db_phpbb) ) $this->_instance_db_phpbb = new DB_PHPBB;
return $this->_instance_db_phpbb;
break;
case self::IS_CMS:
if( is_null($this->_instance_db_cms) ) $this->_instance_db_cms = new DB_CMS;
return $this->_instance_db_cms;
break;
}
}
public static function getInstance($db) {
if( is_null($this->_instance) ) $this->_instance = new DB;
return $this->_instance->load($db);
}
}
Тогда в функциях вместо global достаточно юзать лишь $db = DB::getInstance(DB::IS_PHPBB);
Изврат конечно, да и я не считаю такой вариант корректным и разумным, но ничего пока что в мою голову в столь поздний час не приходит. Остается только красивее это все ваше дело обернуть))
Ну или можно просто глобально переименовать $db в что-либо в какой-либо одной из двух движков.
Хотя в пхп есть ещё namespace в последних версиях, но чет я хз помогут они или нет) Проверьте, я с ними просто не работал в рамках пхп)
Или же просто синхронизируйте методы в классах, или вообще объедините все))
Идея с синглтоном понравилась. Однако, видимо, избежать изменения файлов ядра (как форумного так и движка), что-бы, элементарно, посносить все global и вставить "правильный" вызов объекта :(
полагаю не так много мест, где соприкасаются обе системы, в нужный момент подменяйте тот самый глобальный объект и возвращайте его в исходное состояние после вызова. в итоге исходники буду изменены только там, где они уже изменены для интеграции систем.
А если подменить классы? Ну т.е. в начале движков, где идет инициализация классов.
Т.е. также, как мой пример, только изначально будет что-то типа $db = new DB.
И сделай в DB метод __call(), который будет перехватывать вызываемые методы. И уже сам класс DB тогда будет определять, чей метод использовать (в зависимости от его имени).
Конечно, если названия методов пересекаются в обоих классах, то тут все может пойти шиворот-навыворот. Ну там сам додумай до нужного вида.
Просто я решение этой задачи вижу только в том, чтобы обернуть твои 2 БД-класса в какую-либо обертку.
Читаем умную книжку банды четырех про паттерны обьектно-ориентированного проектирования и все будет замечательно.
Romik : А вот где и сколько они соприкасаются - ох как не просто. Дело в том что я пока что кишки phpBB вообще не менял. Я только подключал нужные файлы, что-бы юзать их, с позволения сказать, API . А там ведь такая канитель.. подключаешь 1 файл, а он за собой тянет ещё пицоттыщ других.. причём в уровни вложенности я там не рискнул вникать....
[COLOR=Silver]А риторика на 4-м курсе - это пи3тец..... у меня вроде как, тьфу тьфу тьфу, нет никакого калла в расписании[/COLOR]