Например WinAPI состоит из множества классов. И хотя многие PHP-программисты стараются сделать весь API в одном классе, нет ничего страшного в таком коде: PHP: <?php // Загрузка интерфейса БД $db = new db('localhost', 'root', 'pass'); // Загрузка интерфейса упраления сообщениями $messages = new messages($db); // Получение сообщения $message = $messages -> getById(1); При чем $message - объект.
[vs], имхо — неудобно так, как ты говоришь. с одним классом — я один раз его создал и один раз настроил его. а так — каждый раз придётся настраивать. а если я на одной странице хочу вывести, скажем, список категорий и список последних обновленных тем, то будет вообще неудобно: PHP: <?php $categories = new Api_Forum_Categories($config); foreach($categories->getAll() as $cat) { // bla-bla-bla } $topics = new Api_Forum_Topics ($config); foreach($topics->getLast() as $topic) { // bla-bla-bla } /*** V.S. ***/ $forum = new Api_Forum($config); foreach ($forum->getCategories() as $cat) { // bla-bla-bla } foreach ($forum->getLastTopics() as $topic) { // bla-bla-bla } А на счёт ВинАПИ, мне несколько дней назад один товарищ сишник сказал (не дословно):
Согласен что в PHP часто удобней держать в одном классе. Кстати как лучше PHP: $forum->topics->getById или $forum->topicsGetById ?
TheShock Согласен, что в использовании не так удобно. Но во втором случае будет либо гигантским монстром, либо будет неявно дергать те же отдельные классы api категорий и форумов, что усложняет модификацию. Так что дело вкуса.
$topics = Toolkit::getInstance()->getDataMaper()->find('Topic', array('id' => $ids)); хехе... смешная тема =)
Нормально спроектированный и написанный форум содержит в себе API по определению. API - это интерфейс, за которым скрыта реализация. Теперь берем определение ООП и читаем. Все модели и вспомогательные классы самодостаточны - бери, используй. Другое дело, если нужно внешнее API - кроссплатформенное, удаленное и т.д. и т.п. Это отдельные случаи которые нужно обсуждать отдельно.
Лишние сущности. универсально для получения любых данных из БД. У форума таблицы фиксированы, удобнее получать данные через специализироване методы, иначе их придется каждый раз писать вручную (например, чтобы выбрать и отсортировать), либо писать класс с этими методами, которые будут дергать этот find через задний проход.
а работает ли он с такими запросами: ... WHERE (foo=1) OR (bar=3 AND animal='cat')? и можешь ли им заделиться? Сейчас на гитхабе нашел такое PHP: <? $field1 = new Field('id', 0); $subq2 = new SelectQuery(array('bans')); $subq2->setSelect(array($field1)); $subq2->setWhere(new Condition('=', new Field('abc'), 10)); $subq = new SelectQuery(array('users')); $subq->setSelect(array($field1)); $subq->setWhere(new AndOp( new Condition('>', new Field('age'), 14), new Condition('in', new Field('id'), $subq2), new Condition('=', new Field('regdt'), '2009-01-01') )); $q = new SelectQuery(array('posts')); $q->setWhere(new AndOp( new Condition('>', new Field('comment'), 1), new Condition('in', new Field('user_id'), $subq), new Condition('=', new Field('funny'), 1) )); $this->assertEquals('SELECT `t0`.* FROM `posts` AS `t0` WHERE (`t0`.`comment` > :p1 AND `t0`.`user_id` IN (SELECT `t0`.`id` FROM `users` AS `t0` WHERE (`t0`.`age` > :p2 AND `t0`.`id` IN (SELECT `t0`.`id` FROM `bans` AS `t0` WHERE `t0`.`abc` = :p3) AND `t0`.`regdt` = :p4)) AND `t0`.`funny` = :p5)', $q->sql()); испытываю священный трепет от количества создаваемых объектов
Трепет здесь надо испытывать не от количества создаваемых объектов, хрен бы с ними, а от ебанутой на всю голову реализации.
разрешаю обсудить мой код )) PHP: <?php /** * @param string $SessionId * @return int|NULL */ public static function GetId($SessionId) { $Query = new KTF_Queryselect(); $Query->AddTable(new KTF_Querytable(USER_SESSION_TABLE)); $Query->AddField(new KTF_Queryfield(new KTF_Querytable(USER_SESSION_TABLE), 'id')); $WhereSessId = new KTF_Querycondition(); $WhereSessId->SetLeftObject(new KTF_Queryfield(new KTF_Querytable(USER_SESSION_TABLE), 'sess_id')); $WhereSessId->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KTF_EQUAL)); $WhereSessId->SetRightObject(new KTF_Queryvalue($SessionId, KTF_Db::KTF_Db_Format_Str)); $WhereLastUpdate = new KTF_Querycondition(); $OperatoinLastUpdate = new KTF_Querycondition(); $OperatoinLastUpdate->SetLeftObject(new KTF_Queryvalue(time(), KTF_Db::KTF_Db_Format_Int)); $OperatoinLastUpdate->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KTF_MINUS)); $OperatoinLastUpdate->SetRightObject(new KTF_Queryfield(new KTF_Querytable(USER_SESSION_TABLE), 'last_update')); $WhereLastUpdate->SetLeftObject($OperatoinLastUpdate); $WhereLastUpdate->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KTF_LESS)); $WhereLastUpdate->SetRightObject(new KTF_Queryvalue(USER_SESSION_TIMEOUT, KTF_Db::KTF_Db_Format_Int)); $WhereCreate = new KTF_Querycondition(); $OperatoinCreate = new KTF_Querycondition(); $OperatoinCreate->SetLeftObject(new KTF_Queryvalue(time(), KTF_Db::KTF_Db_Format_Int)); $OperatoinCreate->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KTF_MINUS)); $OperatoinCreate->SetRightObject(new KTF_Queryfield(new KTF_Querytable(USER_SESSION_TABLE), 'created')); $WhereCreate->SetLeftObject($OperatoinCreate); $WhereCreate->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KTF_LESS)); $WhereCreate->SetRightObject(new KTF_Queryvalue(USER_SESSION_LIFETIME, KTF_Db::KTF_Db_Format_Int)); $WhereSessId->AddCondition($WhereLastUpdate, new KTF_Queryoperator(KTF_Queryoperator::KTF_AND)); $WhereSessId->AddCondition($WhereCreate, new KTF_Queryoperator(KTF_Queryoperator::KTF_AND)); $Query->AddWhere($WhereSessId); $Result = KTF_Db::Query($Query->GetQueryString(), $Query->GetBinds())->FetchOne(); unset($WhereSessId); unset($WhereLastUpdate); unset($OperatoinLastUpdate); unset($WhereCreate); unset($OperatoinCreate); unset($Query); if($Result) { return $Result['id']; } else { $Query = new KTF_Querydelete(); $Query->AddTable(new KTF_Querytable(USER_SESSION_TABLE)); $WhereSessId = new KTF_Querycondition(); $WhereSessId->SetLeftObject(new KTF_Queryfield(new KTF_Querytable(USER_SESSION_TABLE), 'sess_id')); $WhereSessId->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KTF_EQUAL)); $WhereSessId->SetRightObject(new KTF_Queryvalue($SessionId, KTF_Db::KTF_Db_Format_Str)); $WhereLastUpdate = new KTF_Querycondition(); $OperatoinLastUpdate = new KTF_Querycondition(); $OperatoinLastUpdate->SetLeftObject(new KTF_Queryvalue(time(), KTF_Db::KTF_Db_Format_Int)); $OperatoinLastUpdate->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KTF_MINUS)); $OperatoinLastUpdate->SetRightObject(new KTF_Queryfield(new KTF_Querytable(USER_SESSION_TABLE), 'last_update')); $WhereLastUpdate->SetLeftObject($OperatoinLastUpdate); $WhereLastUpdate->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KFT_ABOVE_EQUAL)); $WhereLastUpdate->SetRightObject(new KTF_Queryvalue(USER_SESSION_TIMEOUT, KTF_Db::KTF_Db_Format_Int)); $WhereCreate = new KTF_Querycondition(); $OperatoinCreate = new KTF_Querycondition(); $OperatoinCreate->SetLeftObject(new KTF_Queryvalue(time(), KTF_Db::KTF_Db_Format_Int)); $OperatoinCreate->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KTF_MINUS)); $OperatoinCreate->SetRightObject(new KTF_Queryfield(new KTF_Querytable(USER_SESSION_TABLE), 'created')); $WhereCreate->SetLeftObject($OperatoinCreate); $WhereCreate->SetOperator(new KTF_Queryoperator(KTF_Queryoperator::KFT_ABOVE_EQUAL)); $WhereCreate->SetRightObject(new KTF_Queryvalue(USER_SESSION_LIFETIME, KTF_Db::KTF_Db_Format_Int)); $WhereSessId->AddCondition($WhereLastUpdate, new KTF_Queryoperator(KTF_Queryoperator::KTF_OR)); $WhereSessId->AddCondition($WhereCreate, new KTF_Queryoperator(KTF_Queryoperator::KTF_OR)); $Query->AddWhere($WhereSessId); KTF_Db::Query($Query->GetQueryString(), $Query->GetBinds()); unset($WhereSessId); unset($WhereLastUpdate); unset($OperatoinLastUpdate); unset($WhereCreate); unset($OperatoinCreate); unset($Query); return NULL; } } жесть, не правда ли? Зато один объект можно добавить в кучу запросов и он будет синхронно их менять, также с легкостью пишется класс миниОРМ для много чего и т.д. и т.п. У каждого свои тараканы ))
знаете, что я не люблю? когда в имена классов/файлов/переменных/функций вставляют названия продукта. KTF_Querycondition, EnigmaHTTPRequest, НО: я не против того что б одна папка с продуктом называлась как продукт. И не против что б он значился в @package. Просто вышеперичисленное должно иметь свой смысл. Database, Template, Request, Router upd: еще не люблю маленькие буквы в константах и переменные/ф-ции, начинающиеся с большой буквы.
kostyl, не страдаю такой ерундой. По прежнему sql builder от TheShock наиболее интересен, потому как там указывается тип данных, в отличие от Kahana Но мы удаляемся от темы, господа.