ага... вы сделаете новое правило роутинга... а завтра прийдет другой разраб и захочет хукнуть тот же метод. И создаст еще один класс который наследует оригинальный, а потом перекинет правило роутинга на себя.
Никогда не понимал зачем загонять себя в рамки только для того чтобы "все было правильно". :)
Ок, ну пусть даже мы загоним себя в рамки столь простых проектов в которых плагины и виджеты так редки что если один плагин в проекте и будет, то это круто... и значит конфликтов никаких не будет в нескольких хуках одного и того же метода.
Опять таки изменение правил роутинга будет делаться в ЧУЖОМ коде :)
В результате гоняясь за более "правильным ООП" мы лишимся главного преимущества ООП - скрытия внутренней структуры.
Вы предлагаете изменять ЧУЖОЙ код, а хуки как раз и предназначены для разделения кода расширений от прикладного кода, и иногда от кода ядра.
Проект одного разработчика, ну двух... ну максимум трех еще как-то может жить на такой парадигме, но если мы хотим более менее открытую архитектуру, то менять ЧУЖОЙ код нельзя.
автолоад это конечно хорошо, но если уже есть класс "ньюз" и я хочу внести в него небольшие изменения, то как мне это сделать?
из _ГЕТ мы получили название класса который надо вызывать. Ядро ЕГО и вызовет. Всё. Точка. Для вызова нашего нового класса который наследует наш "ньюз"... ну пусть будет "ньюз2лог" нам надо менять ссылку и в ней указывать другой метод. А это есть перделка половины проекта. Если же архитектура будет другая и не через ссылку передается модуль, то все равно нужно лезть в ЧУЖОЙ код чтобы изменить вызов "ньюз" на "ньюз2лог"
$class = new $_GET['module'];
конечно жесть, но думаю это вы для простоты примера :)
Но я не о том.
То что пхп хоть extends поддерживает я знаю :)
Я о другом.
Вот есть у меня:
.htaccess
RewriteEngine on Options +FollowSymlinks RewriteBase / RewriteRule ^.*$ core/istio.php
в core/istio.php:
...поскипано... // Инициируем ядро GLOBAL $istio; $istio = istio::init(); // Если есть файл описания проекта то выполним его if(file_exists('./../project.php')) require_once('./../project.php'); // Выполним все файлы из папки модулей foreach(scandir('./../mod/') as $f) if(file_exists('./../mod/'.$f) AND !is_dir('./../mod/'.$f) AND strstr($f,'.php')) require_once('./../mod/'.$f); // Обработаем запрошенный адрес или сообщим что страница не найдена $istio->go_map() OR $istio->notfound(); // *********************************************************************** // ** Основные функции ядра, хранение системных переменных и т.п. ** // *********************************************************************** class istio { ...поскипано... private $_config = array(); // глобальный файл конфигурации ....поскипано..... public function config($name) { if (isset($this->_config[$name])) return $this->_config[$name]; else return FALSE; } ....поскипано.... // Приватный конструктор может быть вызван только изнутри (singleton) private function __construct() { ...поскипано.... // Если есть конфиг то считаем его if(file_exists('./../config.cfg')) { $data = file('./../config.cfg'); foreach ($data as $d) { $d = trim($d);//уберем пробелы в начале if(strstr($d,'=') AND $d{0} <> '#') { list($name,$value) = explode('=',$d,2); if(strstr($name,'[')) { list($arr,$key) = explode('[',$name,2); list($key,) = explode(']',$key,2); $arr = trim($arr); $key = trim($key); if($key <> '') $this->_config[$arr][$key] = trim($value); else $this->_config[$arr][] = trim($value); } else $this->_config[trim($name)] = trim($value); } } } ...поскипано...... }
Вот как к примеру здесь пристроить чтение конфига не из файла а из базы?
или
// *********************************************************************** // ** Модуль работы с шаблонами страниц и вывода всего в браузер. ** // *********************************************************************** class _view { ...поскипано.... private $var_array=array(); // Массив переменных для подстановки ...поскипано.... public function say($name,$data=NULL) { // Если данные есть и имя переменной не body то добавим ее в массив if(!($data===NULL) AND $name<>'body' AND $name<>'BODY') $this->var_array[$name]=$this->escsay($data); // Если переменная есть, то вернем ее. Если нет, то вернем NULL if (isset($this->var_array[$name])) return $this->var_array[$name]; else return NULL; } public function lang($name) { $filename=$this->TEMPL_ROOT. $name . '.lng'; $data=array(); if(file_exists($filename)) $data=file($filename); foreach ($data as $d) { $d=rtrim($d,"\n\r"); $d=ltrim($d); if($d{0}<>'#') { list($name,$value) = explode('=',$d,2); if(strstr($name,'[')) { list($arr,$key) = explode('[',$name,2); list($key,) = explode(']',$key,2); $arr = trim($arr); $key = trim($key); if($key <> '') $this->var_array[$arr][$key] = $value; else $this->var_array[$arr][] = $value; } else $this->var_array[trim($name)] = $value; } } }
класс _view тоже синглтон и его экземпляр создается из конструктора istio и все его методы вызываются методами того же класса.
Как мне при этом методами ооп-пхп сделать учет того каким образом та или иная переменная оказалась в $var_array - через lang или через say?
Ну это так, к слову...
Ну а если разобрать Ваш код, то как в вашем коде допустим... ну что бы такое придумать.... ну допустим послесохранения новости я хочу теперь ее в лог сохранить.
Как мне это сделать? Причем естественно я хочу сохранить все пути неизменными, потому как из-за моего модуля никто не будет переписывать весь проект и все ссылки везде... да и ПС вряд-ли обрадуется что будет два одинаковых контента по http://oursite.ru/index.php?module=News и http://oursite.ru/index.php?module=News2log
пуф...
Почему наследие CodeIgniter я могу предположить, хоть ни разу в жизни не видел этот фреймворк.
В чем-то мой фреймворк похож на CodeIgniter - мой тоже будут критиковать за простоту :)
Но вот почему "тяжелое" я так и не понял. И как можно переопределить класс когда ты не можешь контролировать создание экземпляров этого класса я тоже не понял.
Черт, я всегда считал что я очень хорошо умею объяснять.
Ну почему еще ни разу не было, чтобы на мой вопрос ответили когда я спрашиваю по архитектуре совет? Неужели я такой тупой?
Суть вот в чем:
Я написал ядро ЦМС.
Dreammaker, написал под нее модуль... ну скажем блог.
Tarry, хочет сделать, чтобы при добавлении комментариев со ссылками или от новых пользователей номера этих комментариев добавлялись в специальную таблицу для модерации...
Что делать? Лезть в чужой код, а потом отслеживать каждую новую версию?
хуки дают возможность Dreammaker-у в каждой функции/методе сделать хук (обычно в начале и в конце функции) и тогда Tarry спокойно сможет повесить хук на функцию добавления комментария и спокойненько записав нужную информацию отдать дальше управление основной функции (отдается автоматом).
Или к примеру еще:
я написал ядро.
Dreammaker, решил, что для удобства отладки ему нужно знать какие переменные шаблонизатора были добавлены языковой функцией а какие из прикладного кода.
Конечно можно влезть в код ядра и сделать "девелоперскую" версию/сборку, но проще хукнуть функции $istio->lang() и $istio->say() если конечно я не забыл прописать для них хуки :)
т.е. хуки это те же события.
Но вопрос не в том.
Вопрос - в методе класса есть скажем return $istio->hook($return);
дальше в $istio->hook() мы определяем что нас вызвали из такого-то класса и такого-то объекта...
смотрим в таблице зарегистрированных хуков есть ли у нас хук для этого события?
вот тут и вопрос - хукать конкретный экземпляр или класс?
или и то и другое?
но если хукать и класс и экземпляр, то как им приоритет раздать, если есть оба?
На старом конечно редирект стоит.
Иначе бы за пару недель мне бы почти 5тыс страниц в индекс не засунуть :)
на основном домене (истио.ком) в индексе 5к+ страниц, из которых реально десяток от основного сайта, а все остальное непереиндексированные страницы от форума.
Валентин, тогда он был Ваш.
Не помню по каким вопросам, но мы тогда с Вами в аське общались...
Это была причина почему я к Вам и пошел тогда - предпочитаю работать со знакомыми.
что касается цены, то это не так критично когда речь идет о тиер 4 :)
Если человека не устроила ваша раскрутка то очевидно он обратился к другому исполнителю или тупо пошел в сеопульт или даже сапу покупать ссылки сам.
Внутреннюю вы ему уже сделали ведь :)
Тут остается два варианта - либо он поднял бюджет, либо просто удачнее чем вы проставляет ссылки.
Ну и потом возможен такой момент - вы ссылки сняли недавно, и не все еще проиндексировалось что ссылок нет. А Новые ссылки уже полезли, понимая что старые вы то снимете...
Зря вы вот это написали :)
Сижу и думаю: что-то такое смутно знакомое...
Как увидел мсил так вспомнил... hostbizua
Давно правда это было - вроде еще на биз.уа когда были.
Может и получше стало отношение к надежности, но все равно "золото нашли но осадок остался".
Помню перл:
- Дорогая поддержка, а почему у меня сайт лежит, так мало что лежит, еще и ваш сайт лежит, так мало что лежит, так даже не резолвится...
- Дорогой клиент, все в порядке - это у нас плановая еженедельная профилактика.
Не дословно, но суть была такая.
Понятно что и годы прошли, и проект уже другой, но... осадок остался.
А так увидев тиер 4 недорогой, да еще уа-их + УКТ думал взять под один критичный проект, но не рискну. Полгодика присмотримся.
Ну прикладные типовые решения думаю уже должны были более-менее подобтесать...
У меня просто конфигурация и без того из одного места сделана, а масштаб не маленький - 65 филиалов (в смысле географически раздельно расположенных офисов). В 8.0 глюков море. В 8.1 вроде большую часть из них исправили, но вот чего ждать от 8.2 не знаю...
ПЫСЫ: если это на что-то влияет - у меня с частью филлиалов связь очень нестабильная, а десяток вообще файловый обмен по флешке раз в неделю.