Как стать автором
Обновить

Комментарии 20

Всё проще:
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>

Не файл и не директория (там может быть свой index.php|html|htm e.t.c.) — тогда вам на index.php.

А по сути — Вы только что процитировали практически любой MVC-фреймворк: ZF, CodeIgniter, Kohana, CakePHP, Yui, Symfony и так далее
Вы абсолютно правы, концепция единой точки входа является основой практически всех распространенных фреймворков. На это и нацелена первая половина статьи — объяснить как это происходит, основу этого архитектурного решения, так как, как это ни парадоксально, некоторые разработчики попросту не знают, как называется этот механизм и не до конца понимают всех целей, которые им преследуются. В частности программисты возрастом менее двух профессиональных лет, а то и старше затрудняются ответить на вопрос, что такое «избыточность кода» и к чему она приводит.

Я дописал статью до конца, надеюсь во второй половине и вы найдете интересные моменты.
Охохо, сейчас что-то будет :)
Использование статиков не всегда оправдано — это раз.
Определение аяксовости запросов надо делать через $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'? а не разделять по точкам входа. При этом, у Вас точка входа всё-таки одна и Вы теперь придумываете простейший роутинг (либо dispatcher, кому как нравится). При этом, ajax, json, xml и http точки входов отличаются только способом отображения (т.е. — подгружаемыми шаблонами) и их разделение — задача как раз FrontController на основе каких-либо параметров, а не Dispatcher.
Вы правы абсолютно на 100%, но моя ошибка заключается в выборе предметной части примеров, а цель неизменна и до сих пор — описать способ, так сказать Дизайн Единой Точки входа с маршрутизацией не на уровне сервера, а на уровне программного кода.
FrontController должен быть описан в методе execute финального потомка entryPoint, это неявно подразумевается в коде.
Использование статиков не всегда оправдано — это раз.

Опять же все зависит от ситуации, например есть в проекте файл utilities.php в котором содержится 5 тысяч строк программного кода и в каждом отдельном запросе используется лишь часть его — разве классы со статиками не выход, тем более что подключаться они будут не всем скопом, а через autoload? а как Вы прокомментируете существование .net фреймворка?
При этом, ajax, json, xml и http точки входов отличаются только способом отображения (т.е. — подгружаемыми шаблонами) и их разделение — задача как раз FrontController на основе каких-либо параметров, а не Dispatcher.

Это наверное уже зависит от желания автора и конкретной задачи, понятно, что если перечисленные точки входа отличаются лишь способом отображения, то фронт-контроллера вполне хватит, но как я писал в статье, могут возникнуть концептульно несхожие задачи, и тогда выход = диспетчер.
Например есть у дилингового цента сайт и через него поставляются котировки в режиме реального времени в клиентские терминалы, причем раздача котировок достаточно активная и отдаваемые данные непосредственно связанны с данными фигурирующими на сайте, т.е. нужно принципиально новое приложение, которое имеет много связей с существующим. Я уверен, вы предложите много вариантов решения данной проблемы, вплоть до выделения этого приложения в отдельное на собственном сервере, но к примеру нагрузка еще не настолько велика и какой-нибудь большой рефакторинг просто финансово не может быть обоснован, что же делать?

Можно придумать еще очень много примеров, на которые естественно можно придумать и опровержения, но вы сами должны понимать, что программирование это весьма спорное ремесло и у каждой задачи есть не один десяток как обоснованных, так и необоснованных решений.

Огромное спасибо вам за внимание к статье, я еще раз попытаюсь переосмыслить ее и изложить ее в более качественной форме.
Скажем так — у каждой части MVC-приложения есть вполне определённые задачи.
Модель — оперирует данными и, часто, реализует бизнес-логику.
Контроллер — Обрабатывает запросы пользователей оперируя алгоритмом (бизнес-логика — в модели) — т.е. — принимает решение: «По данным запроса — какие данные мне надо получить».
Вью (отображение) — как раз и определяет, как же будет показан набор данных, полученных от Модели.

Т.е., в идеале, логика одна (либо незначительно отличающаяся) для различных вариантов отображения (будь то REST API, ajax, либо простой http). Т.е. меняется только набор вью + некоторые части (авторизация, например, и т.д.). Таким образом — Ваш EntryPoint — всего лишь начало Dispatcher-a.

Почему использование статических классов не всегда оправдано? Тут всё проще — содержимое статического класса держится в памяти до смерти скрипта, а вот переменная, содержащая в себе инстанциированный класс, будет уничтожена как только пропадёт последняя ссылка на неё (Garbage Collector постарается — т.е. я сделаю unset переменной в которой хранился инстанс класса, в котором, в свою очередь, было поле с объектом другого класса — зачистятся оба).

П.С. — перенесите в какой-нибудь профильный блог (PHP, например — так больше народу статью увидит).
извените, ошибся местом ответа, Вам ответил ниже.
содержимое статического класса держится в памяти до смерти скрипта

Вот здесь то наверное и расходятся наши мнения, так как я считаю это неоспоримым преимуществом.
Во первых, не забываем, что мы подключаем классы со статическими методами через __autoload, т.е. их нет в памяти до первого обращения, а во вторых я предлагаю в один класс комплектовать исключительно близкие по предметной области методы, в этом случае велика вероятность, что эти же методы, или их братья по контейнеру, в текущем контроллере или модели будут использованы неоднократно, следовательно если предмет текущей логики скрипта далек от функционала определенного класса, вероятно, что он не будет инициализирован. А в вашем случае, вы можете гарантировать, что деинициализированный объект класса Вам более не пригодится? Ведь если это произойдет, будет дополнительный расход ресурсов на повторную инициализацию.

И наверное в контексте общей темы топика я приведу еще один пример, который и был инициатором всей этой затеи, но потом ушел из зоны внимания — скрипт крон-менеджера. Его архитектура не базируется на паттерне MVC, так как ни контроллера ни тем более представления в нем нет и быть не может, есть, грубо говоря, только модель, в одном единственном экземпляре. Но он в то же время неотъемлемая часть системы и работает со всеми теми же данными. Т.е. это приложение абсолютно иного назначения, обязанное выполнятся в контексте сайта. А применив к нему описанную технологию, мы в нем урезаем избыточность, плюс к этому появляются новые возможности для отладки и логирования на одной общей базе.
Очень много задач можно решить базируясь на MVC и «скрипт крон-менеджера» этому не исключение. В нем также могут быть свои контроллеры, модели и отображения. Например, так сделано в Symfony1.4 для создания task-ов.
В скрипте крона есть как минимум модель и контроллер. Как иначе Вы собираетесь запрашивать действия модели? Плюс можно дампить некие вещи в консоль, вот и view появляется, а многие хостинги к тому же поддерживают отправку этого вывода на почту.
пошел учить мат. часть, как оказалось, мое представление о MVC-паттерне сходно с представлением большинства программистов с небольшим опытом, т.е. мой контроллер — это ТТУК — «Толстые тупые уродливые контроллеры» (http://ru.wikipedia.org/wiki/Model-View-Controller)
Как уже выше отметили, отделять ajax удобнее $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'

Добавлю лишь, что, мне удобнее да и нагляднее получать xml, json и тд так:
domain.com/module/action/index.xml
domain.com/module/action/index.json
domain.com/module/action/index.blabla

в то время как
domain.com/module/action/index.html — отдает нужный контент в html
мне кажется, что перед тем, как рассуждать над MVC нужно научиться использовать switch вместое elseif
Приведи пожалуйста хоть один довод тому, что if...elseif чем то уступает switch...case?
Я сознательно не использую конструкцию switch...case, в свое время один британец с 20-ти летним опытом, работающий в немаленькой компании Converteam, привел аргументированные доводы в пользу того, что конструкцию case...switch не стоит использовать в принципе, и все благодаря существованию такого оператора, как break.
А в остальном, это дело личного предпочтения.
по функционалу — ничем
выглядит намного понятней. чисто субъективно
чем плох break?
Его доводы были основаны на том, что возможность выхода из блока кода в любом месте — есть плохо. Т.е. кроме break, к плохим операторам так же были отнесены и continue и return.
Да, когда ты пишешь сам, ты знаешь все свои привычки и способен в случае появления, определить баг достаточно быстро, но когда работаешь в команде, проще и правильнее задать некоторые правила, благодаря которым исключительная ситуация просто не возникнет, в случае таких банальных вещей, как использование break;
А так может получится, что пишет человек код, внутри блока case каким то образом появляется условие с break внутри, а за этим условием еще добрая половина блока case, которая должна обязательно исполнится, и тут случается, так, что условие не в полной мере охватывает все варианты, все, у тебя по непонятной причине отваливается кусок логики, и повезет, если его писали недавно, то сориентироваться можно быстро, а если проект n-годовой давности и разрабатывал его не ты, хотел бы такого жучка встретить?

Тоже по теме преждевременного выхода из блоков кода — если немножко погуглить по фразе «Правила хорошего тона программирования» или «чистота кода», в нескольких источниках можно обнаружить рекомендации того, что оператор return в методе или функции должен встречаться единожды — в последней строке блока метода, доводы к этим рекомендациям примерно те же, что и в случае с оператором break;
Не использовать switch только потому, что при этом надо использовать break? о_О
До абсурда-то зачем доходить? Правила созданы для программиста, а не программист для правил ;)
Абсурд — это когда человек бросает громкие фразы, ничем их не подтверждая. Если вы имеете противоположную моей точку зрения, приложите хоть немного усилий, чтобы обосновать ее, иначе любое утверждение можно превратить фарс.
мне кажется, что перед тем, как рассуждать над MVC нужно научиться использовать switch вместое elseif

Этот вопрос на самом деле совершенно не имеет смысла. Оно будет вынесено в отдельный метод и будет читабельно, что if'ами, что switch'ами.
А раз уж решили выпендриться, то следовало вспомнить Фаулера и сказать фразу по-умнее, например «Стоит заменить условный оператор полиморфизмом». И это будет более в тему, потому что switch относиться к MVC ровно настолько же, насколько объявление константы.

Статья переработана.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.