Комментарии 204
Спасибо :) Уверен, что это многим поможет избежать ошибок.
Поставил плюс в надежде на то, что автор позже напишет(как и обещает) более детальную и углубленную статью. Вот это будет действительно полезно. В этой статье тема освещена слишком поверхностно: дайте нам больше грязных подробностей =)
какой из пунктов разбирать первым?
Мне бы про №11 интересно было прочитать. Вообще конечно интересно прочитать о всех пунктах более деально :)
хорошо, в ближайшее время постараюсь…
НЛО прилетело и опубликовало эту надпись здесь
Не особо понял смысл этой обертки.
Другое дело, если бы при первом обращении к Session стартовалась бы сессия.
Другое дело, если бы при первом обращении к Session стартовалась бы сессия.
НЛО прилетело и опубликовало эту надпись здесь
Очень даже смысловая, особенно при использовании ajax fw (jquery например)…
if (session_id()==null) {
session_start();
}
На счет именно этой обёртки не скажу, а вообще использование $_SESSION приводит к созданию немасштабируемого (горизонтально) приложения, т.к. данные сессии хранятся в файловой системе.
НЛО прилетело и опубликовало эту надпись здесь
#7, #8 если можно. Очень интересует оптимизация SQL таблиц!
Можно добавить эту статю в избранные, а потом пункты в этой статье делать ссылками… и будет маленький ман :)
ах ты извращенец!: D
Правило №2 — под большим вопросом, очень уж часто хочется видеть красивые URL, а через mod-rewrite это сделать очень просто, и как правило хватает одного правила:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|php|js|ico|txt|gif|jpg|png|css|rss|zip|tar\.gz)$ index.php
Правило №8: наиболее частая операция в web, как ни крути, — это SELECT, а там индексы помогают.
И да, объясните, что имелось ввиду под пунктом №11. Никогда ни с чем подобным не сталкивался, приведите пример, где эти суперглобальные переменные работать не будут. Хотя через обертку работать удобней, но много зависит от архитектуры проекта.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|php|js|ico|txt|gif|jpg|png|css|rss|zip|tar\.gz)$ index.php
Правило №8: наиболее частая операция в web, как ни крути, — это SELECT, а там индексы помогают.
И да, объясните, что имелось ввиду под пунктом №11. Никогда ни с чем подобным не сталкивался, приведите пример, где эти суперглобальные переменные работать не будут. Хотя через обертку работать удобней, но много зависит от архитектуры проекта.
Вообще достаточно, т.к. в условии указано «если файл существует» иначе запрос обработает скрипт и если надо возратит Error 404, а вот обзор папок я думаю вообще не нужен…
но у многи в .htaccess такой лес встречал, что… причем даже у многих коммерческих CMS
Да и еще забыл написать, что нужно фиксировать длину текстовых полей например varchar(20), т.к. в MySQL используются статические буферы под которые соответственно выделяется память.
Да 11 пункт, очень специфичный, но дело в том, что проект из практики по мере его роста проходит не один этап масштабирования и код кочует с одного сервера на другой (например запустить PHP под FastCGI — производительность увеличиться), потом раскидывается на несколько, что тоже приводит к ряду проблем и все зависит от выбранного вами ПО. Я думаю в следующем посте стоит рассмотреть один из стандартных случаев масштабирования LAMP систем и на его примере попробовать решить эти задачи.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php
но у многи в .htaccess такой лес встречал, что… причем даже у многих коммерческих CMS
Правило №8: наиболее частая операция в web, как ни крути, — это SELECT, а там индексы помогают.Помогать-помогают, но время записи в таблице увеличивается и иногда их лучше вынести в отдельную таблицу и делать выборку по ней. Во время записи в БД таблица блокируется, добавляется запись и обновляются индексы и только после этого все остальные могут ее читать. Следовательно, чем больше индексов, тем больше потребуется времени для их обновления.
Да и еще забыл написать, что нужно фиксировать длину текстовых полей например varchar(20), т.к. в MySQL используются статические буферы под которые соответственно выделяется память.
Да 11 пункт, очень специфичный, но дело в том, что проект из практики по мере его роста проходит не один этап масштабирования и код кочует с одного сервера на другой (например запустить PHP под FastCGI — производительность увеличиться), потом раскидывается на несколько, что тоже приводит к ряду проблем и все зависит от выбранного вами ПО. Я думаю в следующем посте стоит рассмотреть один из стандартных случаев масштабирования LAMP систем и на его примере попробовать решить эти задачи.
Хм. Советовать избавляться от индексов, так как это тормозит БД при INSERT — это, по-моему, сродни совету бороться с головной болью путем отсекновению оной. INSERT в CMS — это как правило добавление страницы или коммента, т.е. очень редкое явление. А SELECT юзается при любой генерации страницы и по нескольку раз. Важнее оптимизаровать SELECT, а здесь индексы незаменимы.
У меня есть один проектик, где периодически идет массовый INSERT в таблицу с индексом по текстовому полю. Параллельно БД продолжает активно использоваться. Не наблюдаю какого-то заметного падения производительности в момент таких инсертов…
У меня есть один проектик, где периодически идет массовый INSERT в таблицу с индексом по текстовому полю. Параллельно БД продолжает активно использоваться. Не наблюдаю какого-то заметного падения производительности в момент таких инсертов…
про локание таблицы — вы про какую БД говорите, если про MySQL, то про какой движок?
Помогать-помогают, но время записи в таблице увеличивается и иногда их лучше вынести в отдельную таблицу и делать выборку по ней. Во время записи в БД таблица блокируется, добавляется запись и обновляются индексы и только после этого все остальные могут ее читать. Следовательно, чем больше индексов, тем больше потребуется времени для их обновления.
Таблица блокируется в MyISAM, а в InnoDB, например, такого нет.
Кстати, в большинстве (80%) случаев хватает правила, которое определяет схему «контроллер/метод/параметры». Правило по-умолчанию используется в Ruby on Rails, ASP.NET MVC Framework, Castle MonoRail и это действительно очень правильно.
Да, так оно и есть. Приведенное выше rewrite rule позволяет отдавать URL системе, которая сама знает чего с ним делать. Будь это стандартные 80% или что-то более экзотическое.
Ага, ну вообще даже по самой концепции REST должны быть контроллеры, у которых должно быть не более 7-ми методов, а остальное — параметры. И если информационная архитектура спроектирована правильно, то эта схема по идее должна быть применима вообще везде. Хотя, скорее это касается некоторых информационных систем, нежели веб-сайтов.
Возможно это более распространено, чем я думаю, но по крайней мере в среде PHP исторически сложился вариант модуль/контроллер/метод. И в случае пропуска какой-то из частей она заменяется на значение по умолчанию. Так что как минимум прийдётся в .htaccess писать несколько правил: для случая когда после базового УРЛа идёт 1, 2, 3 параметра, указывающих либо на index/index/метод, либо на index/контроллер/метод, либо на модуль/контроллер/метод, плюс правило для захода на главную страницу, там вообще ничего дополнительного в УРЛе не будет.
REST это CRUD веб-сервисов. Отлично подходит для простых запросов, например:
/articles/ SELECT * FROM article
/articles/1 SELECT * FROM article WHERE id = 1
Но бывают и более сложные запросы, более сложные веб-сервисы — посмотрите на Flickr API — www.flickr.com/services/api/
Для веб-сайтов — как вы реализуете login logout методы?
REST стоит использовать — это стандарт, но без фанатизма.
/articles/ SELECT * FROM article
/articles/1 SELECT * FROM article WHERE id = 1
Но бывают и более сложные запросы, более сложные веб-сервисы — посмотрите на Flickr API — www.flickr.com/services/api/
Для веб-сайтов — как вы реализуете login logout методы?
REST стоит использовать — это стандарт, но без фанатизма.
А что непонятного с логин/логаут?
/user/login
/user/logout
/user/login
/user/logout
ну как это ложится в CRUD?
А что, разве не ложится? Сессия — объект. При логине создаем, при добавление данных к сессии — апдейт, при логауте — делит.
Вы можете просто прочитать? Я даже приведу то что написано парой строк выше (и то на что сам комментировал)
> Ага, ну вообще даже по самой концепции REST должны быть контроллеры, у которых должно быть не более 7-ми методов, а остальное — параметры.
> И если информационная архитектура спроектирована правильно, то эта схема по идее должна быть применима вообще везде.
> Хотя, скорее это касается некоторых информационных систем, нежели веб-сайтов.
Как вы думаете к чему относится «не более 7-ми методов, а остальное — параметры»?
Посказываю — RESTful.
Давайте читать дальше — «если информационная архитектура спроектирована правильно, то эта схема по идее должна быть применима вообще везде.».
Вы согласны?
Теперь читаем мой коментарий — «как вы реализуете login logout методы?»
И таки как эти методы вписываются в RESTful?
А вот и ваш кометарий! «А что непонятного с логин/логаут?»
Ну и к чему? Что вы пытаетесь доказать прочитав только крайний пост???
> Ага, ну вообще даже по самой концепции REST должны быть контроллеры, у которых должно быть не более 7-ми методов, а остальное — параметры.
> И если информационная архитектура спроектирована правильно, то эта схема по идее должна быть применима вообще везде.
> Хотя, скорее это касается некоторых информационных систем, нежели веб-сайтов.
Как вы думаете к чему относится «не более 7-ми методов, а остальное — параметры»?
Посказываю — RESTful.
Давайте читать дальше — «если информационная архитектура спроектирована правильно, то эта схема по идее должна быть применима вообще везде.».
Вы согласны?
Теперь читаем мой коментарий — «как вы реализуете login logout методы?»
И таки как эти методы вписываются в RESTful?
А вот и ваш кометарий! «А что непонятного с логин/логаут?»
Ну и к чему? Что вы пытаетесь доказать прочитав только крайний пост???
По поводу правила номер два:
Если у сервака включены .htaccess, он при каждом запросе обходит все дерево в поисках этих файлов. На локальной машине, для девелоперского и тестового серверов — .htaccess вполне приемлим, но на продакшне лучше все эти условия кинуть в конфиг сервера, а .htaccess запретить вообще. Потому как явно на продакшне мы не будем каждый раз менять правила для различных директорий.
Вариант, когда мы на каком-нибудь шаред хостинге и у нас нет доступа к серверу, я, соответсвенно, не рассматривал :)
Если у сервака включены .htaccess, он при каждом запросе обходит все дерево в поисках этих файлов. На локальной машине, для девелоперского и тестового серверов — .htaccess вполне приемлим, но на продакшне лучше все эти условия кинуть в конфиг сервера, а .htaccess запретить вообще. Потому как явно на продакшне мы не будем каждый раз менять правила для различных директорий.
Вариант, когда мы на каком-нибудь шаред хостинге и у нас нет доступа к серверу, я, соответсвенно, не рассматривал :)
Сейчас ЧПУ все чазе заказывают при разработке сайта, это всегда почти на первом месте, если заказчик хоть что-то слышал (или нанял посредника, который слышал) про SEO
Директивы mod_rewrite можно писать в .htaccess в корне сайта (но это приведет к повторному разбору алиасов и парсингу ссылок)- по сути двойная нагрузка на Апач, а можно в httpdconf- и тогда ЧПУ будет работать без накладных расходов.
А можно чуть-чуть подробнее рассказать про эту возможность?
Директивы вписываются в httpd.conf примерно так:
(сорри за кавычки, хабрапарсер)
Вобщем все как и в .htaccess, подробнее в Гугле
#если включен mod_rewrite
«IfModule mod_rewrite.c»
#включить движок Rewrite
RewriteEngine on
#применять RewriteRule, если запрашиваемое имя файла не совпадает с именем какого-нибудь реального файла на сервере
RewriteCond %{REQUEST_FILENAME} !-f
#и не совпадает с именем какой-нибудь реальной директории
RewriteCond %{REQUEST_FILENAME} !-d
#переадресация запроса на index.php в виде параметра
RewriteRule ^(.*)$ index.php? do=$1 [L, NA]
#конец блока настроек модуля
«/IfModule»
(сорри за кавычки, хабрапарсер)
Вобщем все как и в .htaccess, подробнее в Гугле
Спасибо, не знал, как это делать. Раньше через обработку 404 делал
Обработка 404 приводит к распуханию логов Апача (а они ведутся на всех нормально настроенных серверах), можно и от хостера получить за это. Плюс своенравное поведение ИЕ. Так что лучше делать это через .htaccess (быстро, удобно, правильно) или через httpd.conf (если у вас свой сервер и hi-load сайт :)
Вот этого
Здесь не надо. У вас же уже написано правило, что все, что не является файлом или директорией, отдаем скрипту.
И, кстати, чтобы что-то отдавалось скрипту, надо это указать, хотя бы через PATH_INFO: index.php/$1
Я бы написал так:
Квадратные скобки — чтобы парсер не съел.
pdf|php|js|ico|txt|gif|jpg|png|css|rss|zip|tar\.gz
Здесь не надо. У вас же уже написано правило, что все, что не является файлом или директорией, отдаем скрипту.
И, кстати, чтобы что-то отдавалось скрипту, надо это указать, хотя бы через PATH_INFO: index.php/$1
Я бы написал так:
[IfModule mod_rewrite.c]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA, L]
[/IfModule]
Квадратные скобки — чтобы парсер не съел.
То есть Вы хотите всю статику скармливать php-скрипту? Оригинально-с :)
А что касается «чтобы что-то отдавалось скрипту, надо это указать, хотя бы через PATH_INFO»… Зачем всё уложнять? Ведь есть REQUEST_URI…
А что касается «чтобы что-то отдавалось скрипту, надо это указать, хотя бы через PATH_INFO»… Зачем всё уложнять? Ведь есть REQUEST_URI…
>Здесь не надо. У вас же уже написано правило, что все, что не является файлом или директорией, отдаем
скрипту.
Да, но ведь может такое быть, что мы попытка открыть несуществующую картинку будет перенаправляться на index.php, а это нам не нужно.
скрипту.
Да, но ведь может такое быть, что мы попытка открыть несуществующую картинку будет перенаправляться на index.php, а это нам не нужно.
и самое главное, не забудьте уточнить, как правила №№ 1, 2, 3 и 11 помогают с «распределением нагрузки при внезапно возросшей аудитории сайтов» ;)
Правило #2
В любом случае нужно, чтобы переправить на индекс файл все запросы.
А так по делу вобщем-то.
В любом случае нужно, чтобы переправить на индекс файл все запросы.
А так по делу вобщем-то.
Слишком категорично, имхо.
Если дальше пойти, можно добавить «не используйте memcached — на другом сервере его может не быть. Как и MySQL.»
Но в целом, вполне справедливо, если делать скидку на то, что CMS/CMF будет популярным и ставиться на множестве разных серверов. А масштабируемый код, думаю, по другим принципам пишется:)
Если дальше пойти, можно добавить «не используйте memcached — на другом сервере его может не быть. Как и MySQL.»
Но в целом, вполне справедливо, если делать скидку на то, что CMS/CMF будет популярным и ставиться на множестве разных серверов. А масштабируемый код, думаю, по другим принципам пишется:)
«не используйте memcached — на другом сервере его может не быть. Как и MySQL.»
не понял связи со статьей…
А масштабируемый код, думаю, по другим принципам пишется:)
Я рассматривал именно случаи не прогнозируемого взлета посетителей, встречал много блогов которые могли из-за одного поста привлечь сразу тысячи посетителей.
Если сразу рассчитывать на большую аудиторию разрабатывая стартап, не думаю, что кто-то выберет PHP для реализации ;) да и остальные компоненты LAMP (ну кроме Linux конечно).
мне вот стало интересно, а что выберут?
Это относится ко второму и одинадцатому пунктам — рассматривается случай переноса на другой сервер. Странно, что переносить будем на сервер, на котором не сможем поставить тот же Apache, mod_rewrite или что-то не самое распространённое на хостингах. Уж если мы предусматриваем MySQL Master-Slave, то наверняка и для mod_rewrite место найдётся:)
это уже выходит за рамки обычного хостинга и в примере рассматривалось распределение не на два сервера, их количество и тип зависит от нагрузки, а так же контента и специфики сайта.
Так же апач универсальная вещь, но как и все универсальные вещи он уступает узконаправленным веб-серверам, а так же MySQL Master-Slave имелось ввиду как мимнимум два разных физически сервера БД, работающих в простой связке репликации пишем на Master, читаем со Slaves.
Так же апач универсальная вещь, но как и все универсальные вещи он уступает узконаправленным веб-серверам, а так же MySQL Master-Slave имелось ввиду как мимнимум два разных физически сервера БД, работающих в простой связке репликации пишем на Master, читаем со Slaves.
Вы полагаете, у Хабра небольшая аудитория?
Википедия, Facebook, Вконтакте, Одноклассники, Мамба (знакомства) — небольшие домашние странички, использующие PHP, Mysql, apache…
Одноклассники используют PHP и Apache? О_О
А почему же в строке HTTP-ответа написано «Resin/2.1.16», а вместо страничек частенько выпадает что-то вроде такого?
А почему же в строке HTTP-ответа написано «Resin/2.1.16», а вместо страничек частенько выпадает что-то вроде такого?
500 Servlet Exception
one.ejb.control.client.ControllerFailureException: Can not obtain allowed
EJB service provider.
at one.app.community.dk.model.AWebModel.get(AWebModel.java:516)
at one.app.community.dk.model.AWebModel.handleEvent(AWebModel.java:444)
at one.app.community.dk.model.AWebModel.performLogin(AWebModel.java:280)
at one.app.community.dk.model.AWebModel.performLoginUser(AWebModel.java:268)
at one.app.community.dk.servlet.DesktopServlet.handleNotLoginnedException(DesktopServlet.java:240)
at one.app.community.dk.servlet.DesktopServlet.doPost(DesktopServlet.java:99)
at one.app.community.dk.servlet.DesktopServlet.doGet(DesktopServlet.java:54)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:126)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:103)
at com.caucho.server.http.FilterChainServlet.doFilter(FilterChainServlet.java:96)
at one.app.community.filter.BufferingFilter.doFilter(BufferingFilter.java:85)
at com.caucho.server.http.FilterChainFilter.doFilter(FilterChainFilter.java:88)
at com.caucho.http.filter.GzipFilter.doFilter(GzipFilter.java:128)
at com.caucho.server.http.FilterChainFilter.doFilter(FilterChainFilter.java:88)
at com.caucho.server.http.Invocation.service(Invocation.java:315)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:253)
at com.caucho.server.http.HttpRequest.handleConnection(HttpRequest.java:170)
at com.caucho.server.TcpConnection.run(TcpConnection.java:139)
at java.lang.Thread.run(Thread.java:619)
одноклассники на яве писаны
А если пойти еще дальше — то вообще не используйте ни php, ни apache, ни nginx — их отсутсвие может вас огорчить. Проще всего в такой ситуации нам будет написать свой собственный веб сервер на C, да и cms/cmf — тоже, вместе с базой данных в своем, нужном нам формате.
А в целом — советы никакие.
А в целом — советы никакие.
По первым двум пунктам я не соглашусь, всетаки apache + php + mysql самая распостраненная связка на хостингах, хотя если учитывать что то что вы описали аж никак не для маленьких домашних страничек. ф больше подходит под описание сильнонагруженых проектов, то тогда я думаю что разработчики используют на полную все аспекты выбраной конфигурации мало волнуясь за кросплатформенность
ммм… я хотел донести смысл до тех кто сейчас делает мелкие проекты на своем движке, не вкладывая в них много денег и сил, что он будет спокойно спать зная, что если вдруг на его чудо сайт обрушится шквал посетителей, но он всегда сможет быстро среагировать и без особых проблем его масштабировать.
Шквал посетителей не берется ни с того ни с сего и не удерживается долго. Если речь идет про одноразовые всплески пользователькой активности, то тут вполне подойдет элементарное кеширование, а заниматься масштабированием из-за таких всплесков — это из пушки стрелять по воробьям.
Если аудитория моей домашней странички дорастет до аудитории Хабра, то простой оптимизацией тут не обойдешься. Нужно будет переделывать движек.
Готов поспорить насчет первого правила, во многих популярных cms/cmf все инклуды имеют расширение .module или .inc, что сделано для безопасности. Можно конечно define`ом проверять, но суть в том, что первое правило не совсем правильное.
Почему этого не стоит делать (в большинстве случаев), написано здесь: habrahabr.ru/blogs/php/38007/, п. 17
Как же это помогает безопасности?
Куча, поверь мне, куча уязвимостей даже в таких cms(f), как Drupal, Php-Nuke и прочих очень известных именно в файлах, которые по задумке автора должны только подключаться.
Странно, вырезалась ссылка google codesearch
Тогда можно было бы заменить это правило на правило «использовать подключаемые файлы только для объявления функций/классов, запускаемых в index». В таком случае можно обойтись и без дефайнов в начале.
Согласен, но каждый день на различных секьюрити — лентах появляются все новые и новые уведомления о подобных уязвимостях, а ведь сколько уже было написано…
Мне казалось сейчас уязвимости в основном сместились в область SQL-inj и XSS :) Остаётся надеятся, что разработчики, которые столкнулись с проблемами масштабируемости и читают эту статью уже прочитали какой-нибудь FAQ по безопасности.
Те, кто уже двадцать раз прочитал о том, как не надо использовать mysql_query, include, eval и system, порой могут отмочить что нибудь еще :)
Часто вижу, что при проверке в базу данных переменные вроде User_agent или Client-IP (X-forwarder-for) кладутся вообще без проверок, безумное использование import_request_variables или extract и куча других. Вспоминаем недавний баг в WordPress, я думал авторы уже научены предыдущими уязвимостями.
В версии 2.5.0 они решили сделать cookies юзера более защищенными
«wordpress_».COOKIEHASH = USERNAME. «|». EXPIRY_TIME. «|». HMAC
COOKIEHASH md5 хеш от имени сайта
USERNAME Имя пользователя
EXPIRY_TIME Срок жизни cookies до того как они станут невалидными
HMAC представляет из себя хеш из USERNAME и EXPIRY_TIME, основанный на ключе, полученный путем преобразования USERNAME, EXPIRY_TIME и SALT, проще говоря формула такая
HMAC_KEY = HMAC md5(USERNAME.EXPIRY_TIME, SALT), HMAC = HMAC md5(USERNAME.EXPIRY_TIME, HMAC_KEY)
$hmackey = hash_hmac('md5', $user. $time, $salt);
$hmacpass = hash_hmac('md5', $user. $time, $hmackey);
Вроде бы все хорошо, но нет, разработчикам надо было и тут ошибиться :)
Ошибка состоит в том, что при высчитывании хэша не используется разделительных знаков, те зарегестрировавшись с именем, полностью повторяющим уже существующее, но с добавлением в конце имени цифры позволит нам почувствовать себя в шкуре другого юзера.То есть кроме имени юзера, которым нам надо стать и аккаунта в блоге нам ничего не надо.
Объясняю популярно — имеем пользователя admin1, после входа в блог получаем куки
[admin1]|{1897534539}|hash
Теперь просто переделываем cookies так, чтобы левая часть перед hash была идентична для юзера admin
[admin|1](единичка переходит сюда){897534539}|hash
В новом билде хватились и исправили, но такое не забывается :)
Часто вижу, что при проверке в базу данных переменные вроде User_agent или Client-IP (X-forwarder-for) кладутся вообще без проверок, безумное использование import_request_variables или extract и куча других. Вспоминаем недавний баг в WordPress, я думал авторы уже научены предыдущими уязвимостями.
В версии 2.5.0 они решили сделать cookies юзера более защищенными
«wordpress_».COOKIEHASH = USERNAME. «|». EXPIRY_TIME. «|». HMAC
COOKIEHASH md5 хеш от имени сайта
USERNAME Имя пользователя
EXPIRY_TIME Срок жизни cookies до того как они станут невалидными
HMAC представляет из себя хеш из USERNAME и EXPIRY_TIME, основанный на ключе, полученный путем преобразования USERNAME, EXPIRY_TIME и SALT, проще говоря формула такая
HMAC_KEY = HMAC md5(USERNAME.EXPIRY_TIME, SALT), HMAC = HMAC md5(USERNAME.EXPIRY_TIME, HMAC_KEY)
$hmackey = hash_hmac('md5', $user. $time, $salt);
$hmacpass = hash_hmac('md5', $user. $time, $hmackey);
Вроде бы все хорошо, но нет, разработчикам надо было и тут ошибиться :)
Ошибка состоит в том, что при высчитывании хэша не используется разделительных знаков, те зарегестрировавшись с именем, полностью повторяющим уже существующее, но с добавлением в конце имени цифры позволит нам почувствовать себя в шкуре другого юзера.То есть кроме имени юзера, которым нам надо стать и аккаунта в блоге нам ничего не надо.
Объясняю популярно — имеем пользователя admin1, после входа в блог получаем куки
[admin1]|{1897534539}|hash
Теперь просто переделываем cookies так, чтобы левая часть перед hash была идентична для юзера admin
[admin|1](единичка переходит сюда){897534539}|hash
В новом билде хватились и исправили, но такое не забывается :)
Три часа ночи, пока писал мог мысль потерять, если кто чего не понял могу разъяснить xD
Ведь вполне спасает старая добрая конструкция
defined(«MY_SUPER_CMS») or die («Access denied»);
в начале подключаемых файлов.
defined(«MY_SUPER_CMS») or die («Access denied»);
в начале подключаемых файлов.
Я бы даже сказал устаревшая:) Так писали во времена PHP3. Ну и PHP-Nuke так написан:)
лучше записать в каталог с классами .htaccess с «Deny from all»
Оно понятно) Но вдруг htaccess не будет работать на целевом хостинге(да, вдруг мы пишем форум который и на бесплатных хостингах ставиться будет)? Не оставлять же пользователей незащищенными… Хотя, по сути, ничего не произойдёт при запуске подключаемого файла(если он .php). Переменные установятся, да и фиг с ними.
имхо, нельзя вообще вбивать инфу об оптимизации людям, надо вбивать нормальное проектирование (а то будет оптимизация на ранних стадиях что есть зло)
а подобные заметки:
> не будет проблем при запуске на другом веб-сервере, а также для безопасности.
для криворуких недопрограммистов. Если человек не уверен в том, что происходит на сервере — нельзя его вообще к кодингу допускать. А если уверен — уж в состоянии настроить расширения файлов и связать их с обработчиками.
Или (туда же):
> т.к. другой веб-сервер не поддерживает .htaccess
Что значит не поддерживает? Не сумели настроить или что? Нет — идите книги читайте как настроить httpd (или что там еще).
Вот еще замечание:
> использовать полные пути при работе с файлами и хранить пути к папкам в конфиге
> т.к. статику обычно переносят на другой сервер
Нет, не поэтому. Потому что когда вы делаете include вы будете точно знать где файл ищется. На phpclub.ru где-то есть прекрасная статья об использовании полных путей.
И еще:
> Правило #6: при рендере страницы не должно быть лишних SQL-запросов вставляющих записи в таблицу
> статистику отдайте Google Analytics и логам веб-сервера
Снова таки, не в том дело. Не в том дело, что гугл аналитикс молодец. А в том, что делать статистику можно внешним js-файлом (да да, так же, как и гугл аналитикс). Это позволяет погрузить статистику (в будущем, если надо!) на другой сервак, + если тот сервак упадёт (или вообще статистику отключить) — ничего не случится с сайтом.
В общем (это сугубо моё личное мнение), статья ужасна. Предлагаю автору попробовать написать об общем проектировании (чтоб была расширяемость и возможность _дальнейшей_ оптимизации).
а подобные заметки:
> не будет проблем при запуске на другом веб-сервере, а также для безопасности.
для криворуких недопрограммистов. Если человек не уверен в том, что происходит на сервере — нельзя его вообще к кодингу допускать. А если уверен — уж в состоянии настроить расширения файлов и связать их с обработчиками.
Или (туда же):
> т.к. другой веб-сервер не поддерживает .htaccess
Что значит не поддерживает? Не сумели настроить или что? Нет — идите книги читайте как настроить httpd (или что там еще).
Вот еще замечание:
> использовать полные пути при работе с файлами и хранить пути к папкам в конфиге
> т.к. статику обычно переносят на другой сервер
Нет, не поэтому. Потому что когда вы делаете include вы будете точно знать где файл ищется. На phpclub.ru где-то есть прекрасная статья об использовании полных путей.
И еще:
> Правило #6: при рендере страницы не должно быть лишних SQL-запросов вставляющих записи в таблицу
> статистику отдайте Google Analytics и логам веб-сервера
Снова таки, не в том дело. Не в том дело, что гугл аналитикс молодец. А в том, что делать статистику можно внешним js-файлом (да да, так же, как и гугл аналитикс). Это позволяет погрузить статистику (в будущем, если надо!) на другой сервак, + если тот сервак упадёт (или вообще статистику отключить) — ничего не случится с сайтом.
В общем (это сугубо моё личное мнение), статья ужасна. Предлагаю автору попробовать написать об общем проектировании (чтоб была расширяемость и возможность _дальнейшей_ оптимизации).
Согласен с вами, статья сводится к следующему — «не используй php, на другом сервере его может не быть».
Пятый пункт, в котором говорится о кэширование в файл — тоже спорный момент, кэширование в файл очень плохо сказывается на сервер при большой нагрузке.
Пятый пункт, в котором говорится о кэширование в файл — тоже спорный момент, кэширование в файл очень плохо сказывается на сервер при большой нагрузке.
p.s.: иногда минусуют карму за обычные себе посты с выражением точки зрения, что кажется что снова боты на хабре :-)
Что значит не поддерживает? Не сумели настроить или что? Нет — идите книги читайте как настроить httpd (или что там еще).
кроме httpd в мире еще существуют сотни веб-серверов, а также способы запустить PHP
Нет, не поэтому. Потому что когда вы делаете include вы будете точно знать где файл ищется. На phpclub.ru где-то есть прекрасная статья об использовании полных путей.
имелось ввиду не скрипты, а статический контент (изображения, видео, архивы и т.д.) т.к. они действительно могут находиться физически на другом сервере (статику отделяют при масштабирование, одни из первых этапов отделить Frontend и Backend).
Снова таки, не в том дело. Не в том дело, что гугл аналитикс молодец. А в том, что делать статистику можно внешним js-файлом (да да, так же, как и гугл аналитикс). Это позволяет погрузить статистику (в будущем, если надо!) на другой сервак, + если тот сервак упадёт (или вообще статистику отключить) — ничего не случится с сайтом.
Здесь дело в том, что если статистика будет считаться средствами цмс, то это как минимум + 1 INSERT в БД, даже при небольшой нагрузке просто упадет сайт из-за таблицы статистики, но почему-то многие стараются запихнуть это в цмс (одна из распространенных ошибок)
> кроме httpd в мире еще существуют сотни веб-серверов, а также способы запустить PHP
Да. Именно поэтому я написал
1. httpd (или что там еще) — httpd либо другой веб-сервер
2. Не сумели настроить или что? Нет — идите книги читайте как настроить — о том, что нужно правильно настроить веб-сервер и всё, а не думать во время разработки о том, что ж там будет. + нормальные проекты (требующие расширения) могут позволить себе сервер «с нуля», где всё настраивается вами. Любимые версии любимых программ под любимую ОС.
> имелось ввиду не скрипты, а статический контент (изображения, видео, архивы и т.д.) т.к. они действительно могут находиться физически на другом сервере (статику отделяют при масштабирование, одни из первых этапов отделить Frontend и Backend).
Нууу… А бывает статику разносят на несколько серваком (когда нагруженный проект типа ютуб). Тогда уж полные пути для статики — полное зло. В общем, хэлперы для формирования ссылок — наше всё.
> но почему-то многие стараются запихнуть это в цмс (одна из распространенных ошибок)
Ну, здесь мои способности телепата отсутствуют, но я лично видел человека два за жизнь, которые статистику таки пихали в скрипты (кстати, иногда это таки надо). Возможно вы правы, стоит предупредить этих умельцев, рас уж их так много.
Да. Именно поэтому я написал
1. httpd (или что там еще) — httpd либо другой веб-сервер
2. Не сумели настроить или что? Нет — идите книги читайте как настроить — о том, что нужно правильно настроить веб-сервер и всё, а не думать во время разработки о том, что ж там будет. + нормальные проекты (требующие расширения) могут позволить себе сервер «с нуля», где всё настраивается вами. Любимые версии любимых программ под любимую ОС.
> имелось ввиду не скрипты, а статический контент (изображения, видео, архивы и т.д.) т.к. они действительно могут находиться физически на другом сервере (статику отделяют при масштабирование, одни из первых этапов отделить Frontend и Backend).
Нууу… А бывает статику разносят на несколько серваком (когда нагруженный проект типа ютуб). Тогда уж полные пути для статики — полное зло. В общем, хэлперы для формирования ссылок — наше всё.
> но почему-то многие стараются запихнуть это в цмс (одна из распространенных ошибок)
Ну, здесь мои способности телепата отсутствуют, но я лично видел человека два за жизнь, которые статистику таки пихали в скрипты (кстати, иногда это таки надо). Возможно вы правы, стоит предупредить этих умельцев, рас уж их так много.
Или (туда же):
> т.к. другой веб-сервер не поддерживает .htaccess
Что значит не поддерживает? Не сумели настроить или что? Нет — идите книги читайте как настроить httpd (или что там еще).
Вы будете смеяться, но, к примеру, в nginx нет .htaccess. То есть вообще нет. Все изменения делаются на уровне конфигурации сервера. Да, там есть механизм перезаписи URL (я только про перезапись URL говорить буду, а не о различии в конфигах, которые всё-таки могут быть весьма и весьма существенными, как по синтаксису, так и по возможностям). Если для Вас переписывать полста правил из формата mod_rewrite апача в формат rewrite nginx'a — в порядке вещей, то я замолкаю: меня такие задачи очень удручают, но люди-то все разные, кто-то не чурается однообразного механического труда :)
Вот еще замечание:
> использовать полные пути при работе с файлами и хранить пути к папкам в конфиге
> т.к. статику обычно переносят на другой сервер
Нет, не поэтому. Потому что когда вы делаете include вы будете точно знать где файл ищется. На phpclub.ru где-то есть прекрасная статья об использовании полных путей.
Инклюды «как есть» лучше вообще не использовать. Автозагрузчики, вызывающие обёртку ,которая решает, каким образом подключать файл существенно увеличит гибкость программы. Это так, на тему «я зануда» :)
Вы будете смеяться, но, к примеру, в nginx нет .htaccess.
Стандартная архитектура вэб-сервера предполагает nginx как фронт-энд и Апач как бак-энд. Использовать nginx для реврайта- имхо изврат. Отдача статики, контролируемая загрузка, кэширование- это его задачи. Или вы к nginx будете привязывать сразу php?
Стандартная архитектура вэб-сервера предполагает nginx как фронт-энд и Апач как бак-энд. Использовать nginx для реврайта- имхо изврат. Отдача статики, контролируемая загрузка, кэширование- это его задачи. Или вы к nginx будете привязывать сразу php?
Буду, почему же нет. Использую в качестве бэкенда FastCGI и вполне себе доволен жизнью. Подход с заворотом всех запросов несуществующих файлов на фронтконтроллер PHP-приложения считаю удачным решением и менять точку зрения не собираюсь :)
А от апача пришлось отказаться при повышении трафика. Дюже он прожорливым оказался на ресурсы (не надейтесь, вся статика отдавалась nginx'ом и физически находилась на другом сервере). После переезда на nginx+fastcgi жить стало много легче.
А от апача пришлось отказаться при повышении трафика. Дюже он прожорливым оказался на ресурсы (не надейтесь, вся статика отдавалась nginx'ом и физически находилась на другом сервере). После переезда на nginx+fastcgi жить стало много легче.
> Если для Вас переписывать полста правил из формата mod_rewrite апача в формат rewrite nginx'a — в порядке вещей, то я замолкаю
Нет, но для меня проще изначально определиться чего я хочу и поставить любимый веб-сервер (если сайт написан с кучей мод_реврайтов апача кому в голову придет устанавливать на новом серваке не апач а нгикс??? Киньте в него камнем!)
> Инклюды «как есть» лучше вообще не использовать. Автозагрузчики, вызывающие обёртку, которая решает, каким образом подключать файл существенно увеличит гибкость программы. Это так, на тему «я зануда» :)
Автозагрузчики — зло, имхо. Тормозят и запутывают программу. А в чем гибкость увеличивается я не понял, если честно.
Нет, но для меня проще изначально определиться чего я хочу и поставить любимый веб-сервер (если сайт написан с кучей мод_реврайтов апача кому в голову придет устанавливать на новом серваке не апач а нгикс??? Киньте в него камнем!)
> Инклюды «как есть» лучше вообще не использовать. Автозагрузчики, вызывающие обёртку, которая решает, каким образом подключать файл существенно увеличит гибкость программы. Это так, на тему «я зануда» :)
Автозагрузчики — зло, имхо. Тормозят и запутывают программу. А в чем гибкость увеличивается я не понял, если честно.
Нет, но для меня проще изначально определиться чего я хочу и поставить любимый веб-сервер (если сайт написан с кучей мод_реврайтов апача кому в голову придет устанавливать на новом серваке не апач а нгикс??? Киньте в него камнем!)Одна из самых страшных ошибок в вебе — недооценка перспектив роста популярности. Я на этом уже обжигался :)
Чем увеличивается гибкость:
Разве плохо? :)
А чем запутывают — не придумал. Может, приведёте пример?
Что касается тормозов: может, они и замедляют работу скрипта, но несущественно. Основная часть времени уходит не на определение загруженных классов, а на инклюд файла (работа с ФС вообще не самая быстрая штука). Не думаю, что работа одного вызова автозагрузчика будет сильно различаться по времени с работой явного инклюда.
- Вам не надо задумываться, какой класс подключить, чтобы тот или иной функционал стал доступен; с другой стороны не надо грузить всё подряд. Требуемый класс будет подключен по запросу.
- Если структура файлов и папок поменяется, Вам не придётся судорожно искать все инклюды в коде проекта, а всего лишь поправить один метод или функцию, изменив логику вызовов.
Разве плохо? :)
А чем запутывают — не придумал. Может, приведёте пример?
Что касается тормозов: может, они и замедляют работу скрипта, но несущественно. Основная часть времени уходит не на определение загруженных классов, а на инклюд файла (работа с ФС вообще не самая быстрая штука). Не думаю, что работа одного вызова автозагрузчика будет сильно различаться по времени с работой явного инклюда.
Запутанность? Очень просто. Вы читаете чей-то код и видите использование класса Foo. Хотите его найти. Придется читать (или дебажить) загрузчик.
Еще запутанность. У вас структура такова, что класс Zend_View_Abstract хранится в classes/Zend/View/Abstract.php, в то же время класс из другого фрэймворка, называющийся someFooBar хранится в classes/someframework/FooBar.php. Это усложняет загружчик. А еще и Smarty надо бы, а еще и PEAR, который где-то в include_path. А еще модели хранятся отдельно, интерфейсы отдельно, контроллеры отдельно, view отдельно.
Еще запутанность. У вас структура такова, что класс Zend_View_Abstract хранится в classes/Zend/View/Abstract.php, в то же время класс из другого фрэймворка, называющийся someFooBar хранится в classes/someframework/FooBar.php. Это усложняет загружчик. А еще и Smarty надо бы, а еще и PEAR, который где-то в include_path. А еще модели хранятся отдельно, интерфейсы отдельно, контроллеры отдельно, view отдельно.
Вы читаете чей-то код и видите использование класса Foo. Хотите его найти. Придется читать (или дебажить) загрузчик
В любом уважающем себя IDE (а так же в некоторых «умных» текстовых редакторах) есть возможность перейти на место декларации класса, функции или метода. Например, в Eclipse PDT это можно сделать, просто щёлкнув по функции\классу\свойству, удерживая CTRL.
Еще запутанность. У вас структура такова, что класс Zend_View_Abstract хранится в classes/Zend/View/Abstract.php, в то же время класс из другого фрэймворка, называющийся someFooBar хранится в classes/someframework/FooBar.php. Это усложняет загружчик. А еще и Smarty надо бы, а еще и PEAR, который где-то в include_path. А еще модели хранятся отдельно, интерфейсы отдельно, контроллеры отдельно, view отдельно.
А что мешает сделать несколько автозагрузчиков? Благо SPL такую возможность предоставляет. Для классов ZF используйте один лоадер (который, к примеру, будет оборачивать Zend_Loader), для Smarty второй, для PEAR третий, для моделей и прочего — тоже. В общем, на сколько фантазии хватит :)
В общем, мне кажется что каждый раз нажимать на класс и идти в его декларацию чтоб просто понять где он — мозг загружает (и время отнимает). А если при написании кода человек не знает где лежит класс и лишь надеется на загрузчик — тоже плохо. А если знает где класс лежит и знает как загрузчик работает — тоже лишняя работа мозга (вспоминать как тот работает).
Несколько загрузчиков — да, отлично. Еще и о нескольких загрузчиках думать.
В общем, я так понял, мы дошли до черты где важно дело вкуса.
p.s.: так и не понял зачем они нужны вообще. «Изменение структуры папок» — и часто у вас такое бывает? А если отталкиваться от ROOT_CLASSES_DIR то вообще не пойму, как кроме перемещения всех классов куда-либо можно извратиться.
Несколько загрузчиков — да, отлично. Еще и о нескольких загрузчиках думать.
В общем, я так понял, мы дошли до черты где важно дело вкуса.
p.s.: так и не понял зачем они нужны вообще. «Изменение структуры папок» — и часто у вас такое бывает? А если отталкиваться от ROOT_CLASSES_DIR то вообще не пойму, как кроме перемещения всех классов куда-либо можно извратиться.
Гибкая разработка — это когда о загрузчиках думать не надо. Равно как и не надо думать о том, в каком файле лежит тот или иной класс. Надо всего лишь знать, что при обращении к нему он (класс) автоматом подключится, а при желании можно быстро ознакомиться с его (класса) интерфейсом. В этом опять же здорово помогут IDE.
Насчёт черты про дело вкуса — не согласен, но спорить не буду :)
Насчёт черты про дело вкуса — не согласен, но спорить не буду :)
> Гибкая разработка — это когда о загрузчиках думать не надо.
Не понял при чем здесь первое ко второму (кстати, в include'ах о загрузчиках думать не надо :-)
> Равно как и не надо думать о том, в каком файле лежит тот или иной класс.
Правильно. Но знать это надо (используете вы ИДЕ или нет). А чтоб знать — надо думать о загрузчике (см. пункт выше :-)
Не понял при чем здесь первое ко второму (кстати, в include'ах о загрузчиках думать не надо :-)
> Равно как и не надо думать о том, в каком файле лежит тот или иной класс.
Правильно. Но знать это надо (используете вы ИДЕ или нет). А чтоб знать — надо думать о загрузчике (см. пункт выше :-)
Вопрос в лоб: а зачем знать, где лежит тот или иной файл?
Всё ясно. Дальше спорить смысла не вижу.
Оставить последнее слово за собой — мудрое решение. Но вы меня просто заинтересовали. Может, всё-таки аргументируете?
ну ок. Ответите тогда на встречный вопрос? Зачем знать html если есть визуальные редакторы/IDE?
Если хотите — оставьте последнее слово за собой.
Если хотите — оставьте последнее слово за собой.
Вопрос глупый, но отвечу: причин много. Например, зачастую WYSIWYG генерит избыточный код, из-за которого нарушается семантика и увеличивается вес страницы. Про SEO молчу, к делу не очень относится :)
Теперь моя очередь: зачем знать, где именно хранится класс (в отдельном файле, в подключаемом файле с кучей функций или вообще пятью строками выше), если я точно знаю, что этот класс к моменту создания инстанции гарантированно будет подключен, а при необходимости я с лёгкостью увижу его интерфейс, реализацию или даже отредактирую его.
Теперь моя очередь: зачем знать, где именно хранится класс (в отдельном файле, в подключаемом файле с кучей функций или вообще пятью строками выше), если я точно знаю, что этот класс к моменту создания инстанции гарантированно будет подключен, а при необходимости я с лёгкостью увижу его интерфейс, реализацию или даже отредактирую его.
Отвечаю. Потому же, почему WISIWIG плох для html.
Вы полностью зависите от IDE. И если она не найдёт ваш файл, содержащий класс — вы обречены. А вдруг IDE некорректно пропарсит файлы и покажет вам другой файл с классом с тем же именем? (когда тестировал вышеупомянутый pdt — не раз случалось, а иногда оно один и тот же файл два раза парсило, в общем — глюков много) Вообще прекрасно.
Зависить в разработке программы от IDE — всё равно что верстать в визивиге.
Вы полностью зависите от IDE. И если она не найдёт ваш файл, содержащий класс — вы обречены. А вдруг IDE некорректно пропарсит файлы и покажет вам другой файл с классом с тем же именем? (когда тестировал вышеупомянутый pdt — не раз случалось, а иногда оно один и тот же файл два раза парсило, в общем — глюков много) Вообще прекрасно.
Зависить в разработке программы от IDE — всё равно что верстать в визивиге.
А вдруг IDE некорректно пропарсит файлы и покажет вам другой файл с классом с тем же именем?А вдруг завтра небо нам на головы упадёт? :) Кроме того, классов с одинаковым именем в пределах одного проекта не должно существовать…
Последнее сравнение надуманное и притянутое за уши.
НЛО прилетело и опубликовало эту надпись здесь
а как быть с правилом №8
и с тем что индексы нужны полюбому иначе даже репликация не поможет
и что запись не обязательно лочит всю таблицу
и что скорость записи в сравнении с селектом не так критична
(если ваш проект не сервер сатистики конечно)? =)
и с тем что индексы нужны полюбому иначе даже репликация не поможет
и что запись не обязательно лочит всю таблицу
и что скорость записи в сравнении с селектом не так критична
(если ваш проект не сервер сатистики конечно)? =)
правило №8 действительно имеет место?
мне кажется, вставки в таблицы обычно происходят реже, чем чтение из них и выборка, в которой эти индексы активно участвуют.
мне кажется, вставки в таблицы обычно происходят реже, чем чтение из них и выборка, в которой эти индексы активно участвуют.
№11 — улыбнуло! раскажите мне в крадце, на каких веб серверах нету переменных $_POST или $_GET? ну и про сессии поподробней…
Видимо на тех, где нету php :)
Нет, совет то конечно хроший, но представлен совсем невразумительно. Переделаем его так:
Не обращайтесь напрямую к серверным переменным, особенно к $_POST и $_GET, потому как там находится «сырые данные» пришедшие от пользователя, которому, как известно доверять нельзя. Луше потратиь 40 минут и написать небольшую облочку для них, реализовав в удобной для вас парадигме, которая позвоила бы легко отфильтровать различный мусор, и не боятся, что вас можно ломануть до боли знакомыми способами.
Мне к примеру нравится связка объектов Request и Response, через которые мы общаемся с пользователем и с десяток различных фильтров, которые мы можем настроить под себя как угодно.
Нет, совет то конечно хроший, но представлен совсем невразумительно. Переделаем его так:
Не обращайтесь напрямую к серверным переменным, особенно к $_POST и $_GET, потому как там находится «сырые данные» пришедшие от пользователя, которому, как известно доверять нельзя. Луше потратиь 40 минут и написать небольшую облочку для них, реализовав в удобной для вас парадигме, которая позвоила бы легко отфильтровать различный мусор, и не боятся, что вас можно ломануть до боли знакомыми способами.
Мне к примеру нравится связка объектов Request и Response, через которые мы общаемся с пользователем и с десяток различных фильтров, которые мы можем настроить под себя как угодно.
Возможен ещё такой момент, что в будущих версиях изменят эти глобальные переменные PHP, как это было с переходом с 3-ки на 4-ку. Если они будут объявлены в одном месте, то можно будет и исправить легко и отфильтровать сразу что не нужно.
Уж насколько я люблю распихать все по объектам — но здесь даже я логики не вижу, как раз таки главное отличие $HTTP_***_VARS от $_*** в том что последние — суперглобальные, и доступны в любой области видимости, оборачивать их в зависимые от области видимости объекты — минимум нелогично, да и использоваться они должны при грамотной архитектуре (мы-же о фреймворках говорим?) в специально отведенных для этого местах, и уж Зенд вдруг резко сойдет с ума и переименует эти массивы, безусловно не оставив обратной совместимости (которая по отношению к $HTTP_***_VARS кстати есть), а потом сойдут с ума все хостеры, обновив интерпритатор на эту, веселых расцветок, версию — то заменить пару-тройку переменных в нескольких файлах я думаю не составит такого огромного труда, в современных IDE это можно сделать одной операцией.
С такой позицией тогда уж и каждую используемую встроенную функцию нужно обернуть в пользовательскую или объект, и то, от безумных, с налитыми кровью глазами и кровавой пеной у рта, разработчиков Зенда, удаливших в новой версии интерпритатора все языковые конструкции, начиная от оператора присвоения, заканчивая условными операторами и циклами — это не спасет :)
С такой позицией тогда уж и каждую используемую встроенную функцию нужно обернуть в пользовательскую или объект, и то, от безумных, с налитыми кровью глазами и кровавой пеной у рта, разработчиков Зенда, удаливших в новой версии интерпритатора все языковые конструкции, начиная от оператора присвоения, заканчивая условными операторами и циклами — это не спасет :)
Интересные у Вас проекты, если обращение к суперглобалам у Вас случается 2-3 раза в нескольких файлах. А я вот думаю, что обёртка суперглобалов — это правильно. Даже если взять в учёт тот маловероятный случай с «весёлых расцветок версией», изменение придётся делать в одном классе, что, согласитесь, лучше Вашего варианта :)
А что самое главное — благодаря обёрткам можно избавиться от необходимости выполнять
и тому подобный ужас, тем самым сократив полезный код и сделав его более читабельным.
А что самое главное — благодаря обёрткам можно избавиться от необходимости выполнять
<code>if (array_key_exists('foo', $_GET)) { print $_GET['foo']; }</code>
и тому подобный ужас, тем самым сократив полезный код и сделав его более читабельным.
Об этом и говорится. Разве что насчёт 2-3х автор погорячился, должно быть в одном конечно :)
Вы говорите об обертках для массивов, а я о том что при разделении например модель-вид-контроллер (чем хвастают большинство фреймворков и цмс) — работать с этими массивами предстоит только контроллеру, и даже при отстутсвии этого разделения входные данные неплохо-бы обрабатывать централизовано, если код пестрит if($_GET['param']) { echo $_POST['param']; } то тогда конечно это осложнит замену в нем этих массивов в ручном режиме. Я почему-то считаю это правильным — сначала получить необходимые данные из суперглобальных массивов в переменные, привести к нужным типам, сделать необходимые проверки на правильность их содержимого и уже затем с этими переменными работать.
при разделении например модель-вид-контроллер (чем хвастают большинство фреймворков и цмс) — работать с этими массивами предстоит только контроллеруМежду прочим, не факт. Простейший пример — страница с результатами поиска, на которой необходимо написать что-то типа «вы искали: сиськи третьего размера»). Можно, конечно, передавать поисковый запрос из контроллера, не могу сказать, что это неправильно. Но с другой стороны — это, как ни крути, логика отображения. Если надпись захочется убрать, ничего не поломается. Тогда зачем передавать лишние данные? :)
Я бы в данном случае просто обратился к данным из GET прямо в шаблоне. К примеру, Smarty позволяет это делать (самое важное — не забыть про возможные XSS и кастануть фильтрами типа ESCAPE). Лично у меня используется объект httpRequest, из которого можно получить все данные о запросе. Вызывать этот объект можно и в контроллере, и в шаблонах (которые, кстати, могут быть как на основе Smarty, так и pure php).
Я считаю этот подход правильным, а единообразие интерфейса в шаблонах и контроллерах радует :)
Я почему-то считаю это правильным — сначала получить необходимые данные из суперглобальных массивов в переменные, привести к нужным типам, сделать необходимые проверки на правильность их содержимого и уже затем с этими переменными работатьЯ когда-то, много лет назад, делал так же. Потом, когда переменных становилось всё больше, понял, что надо что-то менять… :)
в php3 было
$HTTP_GET_VARS
$HTTP_POST_VARS
$HTTP_GET_VARS
$HTTP_POST_VARS
Может кому-нибудь пригодится такая простая проверка url'а в PHP 5 на наличие всякого мусора ^___^
// проверяем url на наличие опасных символов
function checkUrlOnXss(){
$u = urldecode(@$_SERVER['REQUEST_URI']);
if (!$u) return;
$str = 'javascript, document.write, <script, <iframe, src=, ../, ..\\';
$str = html_entity_decode($str); // переводим < => < чтобы регулярко всё кушала
$str = preg_quote($str, '/');
$str = str_replace(', ', '|', $str);
if (preg_match(«/({$str})/i», $u) > 0) simpleError('XSS detected');
}
Вот такая наивная защита от XSS.
// проверяем url на наличие опасных символов
function checkUrlOnXss(){
$u = urldecode(@$_SERVER['REQUEST_URI']);
if (!$u) return;
$str = 'javascript, document.write, <script, <iframe, src=, ../, ..\\';
$str = html_entity_decode($str); // переводим < => < чтобы регулярко всё кушала
$str = preg_quote($str, '/');
$str = str_replace(', ', '|', $str);
if (preg_match(«/({$str})/i», $u) > 0) simpleError('XSS detected');
}
Вот такая наивная защита от XSS.
Слишком наивная ;) IE(старый), к примеру, поймёт протокол javascript в href ссылки даже если будет написан в виде jav asc\tript. Аналогично с пробелом после < в <script и <iframe
НЛО прилетело и опубликовало эту надпись здесь
и не забывайте, что во время записи лочится таблица
В MySQL есть тип таблиц InnoDB с per-row locking. Если используете какой то инструмент, то неплохо бы сначала изучить его, перед тем как давать советы другим.
надеялся прочитать какую-то интересную теорию, а оказался бред для малолетних программистов
НЛО прилетело и опубликовало эту надпись здесь
Не хочу никого обидеть, но все настолько примитивно, что статью нужно назвать не «Советы для разработчиков CMS и фреймворков на PHP», а «Если вы не знаете даже этого, то не вздумайте разрабатывать FW or CMS»
Ну и несогласия есть: mod_r.., htaccess, и тд.
Ну и несогласия есть: mod_r.., htaccess, и тд.
«чем больше индексов, тем больше время записи и не забывайте, что во время записи лочится таблица» — за это яб поубивал нахрен
Это откуда такое, первый раз слышу, чтоб лочилась таблица при индексе, да не спорю, работа медленнее, но зато эффект колосальный.
Так как большинество приложений чаше делает все таки SELECT, чем INSERT, и если вы исключите индексы, то вы тогда при маштабировании, когда 100ккк записей не дождетесь ответа сервера, так как любой запрос будет вызывать Фул скан, так как индексов нет и база не знает как ей найти например товар с идентификатором 10000.
, вообще вы представили «как бы хотелось программировать», но не «Советы для разработчиков CMS и фреймворков на PHP»
где отделение представления от функциональности, где выделение отдельно классов по функционалльности, где выбор шаблонизатора, и редактора, это ИМХО советы как сделать хоме-паге), но не поллноценную CMS.
Это откуда такое, первый раз слышу, чтоб лочилась таблица при индексе, да не спорю, работа медленнее, но зато эффект колосальный.
Так как большинество приложений чаше делает все таки SELECT, чем INSERT, и если вы исключите индексы, то вы тогда при маштабировании, когда 100ккк записей не дождетесь ответа сервера, так как любой запрос будет вызывать Фул скан, так как индексов нет и база не знает как ей найти например товар с идентификатором 10000.
, вообще вы представили «как бы хотелось программировать», но не «Советы для разработчиков CMS и фреймворков на PHP»
где отделение представления от функциональности, где выделение отдельно классов по функционалльности, где выбор шаблонизатора, и редактора, это ИМХО советы как сделать хоме-паге), но не поллноценную CMS.
Правило #11: PHP, все-таки, объектно-ориентированный язык, поэтому обращайтесь не напрямую к серверным переменным ($_SERVER, $_POST, $_GET, $_SESSION) — используйте объекты
1) переменные окружения настраиваются администратором вебсервера, если у вас чтото настроенно не верно — это проблемы администратора
2) если админ попался упертый — то вначале проекта делаем include «./hack.php»; в котором приводим переменный окружения данного сервера в гармонию с кодом
следствие: если админ упертый, то есть смысл сменить хостинг.
Правило #5: не бойтесь кэшировать контент в файлы, статическая html-ка отдается быстрее чем php-скрипт открывающий файл с кэшем на диске
замечания:
1) кешировать в файл не всегда удобно (memcached/sql)
2) кешировать нужно с умом, тк при большом количестве файлов в одной дирректории на некоторых фаловых системах могут возникать приличные тормоза
>1) вам тоже стоит прочитать что такое файл
тогда я вам рекомендую прочитать что такое файловая система и как происходит доступ к файлам
>2) а в sql или этой примитивной хэш табличке с таймерами(мемкэшд) — это вызывает меньше проблем?
иногда нужно рапределить кеш между несколькими серверами, а иногда удобно класть кеш в sqlite (например в симфонии есть такой вариант кеширования) вместо обычных файлов
тогда я вам рекомендую прочитать что такое файловая система и как происходит доступ к файлам
>2) а в sql или этой примитивной хэш табличке с таймерами(мемкэшд) — это вызывает меньше проблем?
иногда нужно рапределить кеш между несколькими серверами, а иногда удобно класть кеш в sqlite (например в симфонии есть такой вариант кеширования) вместо обычных файлов
Интересно, а кто-нибудь из тех кто минусуют смогут аргументировать свои действия: D
Уже совсем в минуса загнали, а ведь они даже не догадываются о том что вместо того чтобы складывать готовый хтмл в мемкэш, будет лучше положить его на сетевом диске а из пхп говорить фронтенду о том чтобы он забрал этот файл и отправил клиенту.
А для тех кто критикует мифический файл, следовало бы ознакомиться с религией юниксов или сразу с plan9 :)
Уже совсем в минуса загнали, а ведь они даже не догадываются о том что вместо того чтобы складывать готовый хтмл в мемкэш, будет лучше положить его на сетевом диске а из пхп говорить фронтенду о том чтобы он забрал этот файл и отправил клиенту.
А для тех кто критикует мифический файл, следовало бы ознакомиться с религией юниксов или сразу с plan9 :)
а вы не задумывались почему все используют memcached? а зря… самое важное здесь — скорость доступа к данным.
ознакомтесь с теорией файловых систем, не путайте представление файла в ОС и на уровне ФС
ознакомтесь с теорией файловых систем, не путайте представление файла в ОС и на уровне ФС
>а вы не задумывались почему все используют memcached? а зря… самое важное здесь — скорость доступа к данным.
Обещаю, что если вы сделаете то что я описал — скорость доступа к данным будет выше :) Вам даже не понадобится пропускать через php скрипт весь хтмльник из мемкэшеда… вы фронтенду скажите x-sendfile вон с того компьютера… а тот в свою очередь не будет через свои промежуточные буфферы копировать, а напрямую отсплайсит в сокет ;)
Обещаю, что если вы сделаете то что я описал — скорость доступа к данным будет выше :) Вам даже не понадобится пропускать через php скрипт весь хтмльник из мемкэшеда… вы фронтенду скажите x-sendfile вон с того компьютера… а тот в свою очередь не будет через свои промежуточные буфферы копировать, а напрямую отсплайсит в сокет ;)
Правило #0: говнокод — это плохо. не забывайте что есть стиль оформления кода, комментарии и мануал.
не поленился прочитал все коменты
Статья в общем то дельная, я согласен с пунктами 1, 3, 4, 5, 6, 9, 10 и 11
На счёт многотабличных запросов и индексов не согласен полностью.
Если использовать InnoDB, то можно юзать такие вкусняшки, как внешние ключи, благодаря которым многотабличные запросы значительно ускоряются.
Что касается текстового поиска по другой таблице, согласен, но не по таблице надо искать, а воспользоваться например Sphinx. Полгода как прикрутил к своим проектам и нарадоваться не могу. А для построения индекса достаточно сделать представление, чтобы не дублировать данные. Один сложный запрос раз в сутки — не критично, а каждый раз добавлять записи в таблицу с FULLTEXT это эже проблема, тем более что в MySql это возможно только с MyISAM
Статья в общем то дельная, я согласен с пунктами 1, 3, 4, 5, 6, 9, 10 и 11
На счёт многотабличных запросов и индексов не согласен полностью.
Если использовать InnoDB, то можно юзать такие вкусняшки, как внешние ключи, благодаря которым многотабличные запросы значительно ускоряются.
Что касается текстового поиска по другой таблице, согласен, но не по таблице надо искать, а воспользоваться например Sphinx. Полгода как прикрутил к своим проектам и нарадоваться не могу. А для построения индекса достаточно сделать представление, чтобы не дублировать данные. Один сложный запрос раз в сутки — не критично, а каждый раз добавлять записи в таблицу с FULLTEXT это эже проблема, тем более что в MySql это возможно только с MyISAM
НЛО прилетело и опубликовало эту надпись здесь
Правило #1: все исполняемые скрипты должны иметь расширение .php и только .php, даже инклюды. не будет проблем при запуске на другом веб-сервере, а также для безопасности.
Отчасти правильно, отчасти нет. Во-первых более уверенная безопасность достигается вынесением инклюдов выше корня сайта. Во-вторых если инклюд имеет расширение, например, .module, то запрет на него делается в .htaccess. Бывает, что расширение отличное от .php промогает движку CMS узнать где его модули, а где какие-то другие скрипты, не имеющие отношения к CMS. Так например делает Друпал.
Правило #2: по минимуму использовать функции .htaccess и тем более никаких параметров типа:
RewriteRule ^(.+)$ index.php? path=$1
т.к. другой веб-сервер не поддерживает .htaccess, а в конфиге не всегда удастся настроить так же и отнимет больше времени
Ерунда, вплоть до наоборот. Если сервер не поддерживает .htaccess стоит задуматься о компетентности его администраторов и компетентности того, кто купил такой хостинг, если конечно речь про Apache. Отдача статики минуя index.php делается просто «пальцем об асфальт»
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php? path=$1
Таким образом CMS имеет одну точку входа. Я допускаю, что можно не использовать такую архитектуру, но это исключение, а не правило.
Правило #3: не злоупотреблять mod_rewrite-ом, не использовать виртуальных путей для статических файлов (jpg, gif, css, js и т.д.)
статика должна быть статикой
Далеко не всегда. Для элементов дизайна — да, однозначно. А если вы, например, раздаете mp3 за деньги, то совсем не так. То, что через mod_rewrite может спокойно отдавать статику есть в пункте выше.
Правило #4: использовать полные пути при работе с файлами и хранить пути к папкам в конфиге
т.к. статику обычно переносят на другой сервер
Слишком категорично. Полные пути, конечно, избавляют от многих проблем. Но структура папок может быть динамической (как в том же Друпале). Тут все зависит от архитектуры проектируемой CMS. А статику переносят на другой сервер достаточно нагруженные проекты. Особенно странно звучит это утверждение, в свете что вы закладываетесь на владельцев говнохостинга где нет .htaccess (опять же если речь идет про Apache).
Правило #5: не бойтесь кэшировать контент в файлы, статическая html-ка отдается быстрее чем php-скрипт открывающий файл с кэшем на диске.
не забывайте, можно кэшировать не только html но и xml и т.п.
И здесь все зависит от архитектуры. Кеширование вообще отдельная тема. Часто кешировать надо на уровне блоков.
Правило #6: при рендере страницы не должно быть лишних SQL-запросов вставляющих записи в таблицу
статистику отдайте Google Analytics и логам веб-сервера
Получается что любой модуль CMS, ведущий статистику – лишний? Google Analytics – хорошо, но лучше предоставить пользователю CMS выбирать что лишнее, а что нет.
Правило #7: чем проще SQL запрос, тем больше его скорость работы
сопоставление таблиц — это красиво, но не эффективно, особенно при больших объемах
Да, известно, что MySQL не очень любит join-ы (если вы про них), но тут совсем все не так однозначно. Бывает и join эффективнее, чем разбиение на несколько запросов. В любом случае есть EXPLAIN, и возможность тюнинговать запросы, если хочешь сделать быструю CMS.
Правило #8: использовать минимум индексов, избавиться по возможности от индексов в текстовых полях
чем больше индексов, тем больше время записи и не забывайте, что во время записи лочится таблица
Во-первых таблица лочится только в MyISAM, в InnoDB лочится строка (если речь идет про MySQL).
Во-вторых минимум индексов не есть оптимально. Индексы прекрасный инструмент ускорения выборки, но их надо тоже тонко проектировать в зависимости от того какие преимущественно запросы будут к таблице.
Правило #9: не использовать поля с полнотекстовым поиском в основных таблицах
для поиска используйте отдельную таблицу
Это все зависит от того, как реализовывать поиск. Возможно, если вы напишете статью, как эффективно организовать поиск, где будет показано что отдельная таблица эффективнее в очень широком круге применения, то тогда можно будет претендовать на однозначность.
Правило #11: PHP, все-таки, объектно-ориентированный язык, поэтому обращайтесь не напрямую к серверным переменным ($_SERVER, $_POST, $_GET, $_SESSION) — используйте объекты
Некоторые переменные в других веб-серверах имеют другие имена, а некоторых вовсе нет и их придется вычислять или придумывать (печально дело обстоит с сессиях)
Вообще первый раз об этом слышу. Либо я чего-то упустил в этой жизни, либо это ерунда. Приведите, пожалуйста пример версии PHP или хостинга, где переменные имеют другие названия. Например, $HTTP_GET_VARS – это не другое название, это устаревшее название.
Отчасти правильно, отчасти нет. Во-первых более уверенная безопасность достигается вынесением инклюдов выше корня сайта. Во-вторых если инклюд имеет расширение, например, .module, то запрет на него делается в .htaccess. Бывает, что расширение отличное от .php промогает движку CMS узнать где его модули, а где какие-то другие скрипты, не имеющие отношения к CMS. Так например делает Друпал.
Правило #2: по минимуму использовать функции .htaccess и тем более никаких параметров типа:
RewriteRule ^(.+)$ index.php? path=$1
т.к. другой веб-сервер не поддерживает .htaccess, а в конфиге не всегда удастся настроить так же и отнимет больше времени
Ерунда, вплоть до наоборот. Если сервер не поддерживает .htaccess стоит задуматься о компетентности его администраторов и компетентности того, кто купил такой хостинг, если конечно речь про Apache. Отдача статики минуя index.php делается просто «пальцем об асфальт»
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php? path=$1
Таким образом CMS имеет одну точку входа. Я допускаю, что можно не использовать такую архитектуру, но это исключение, а не правило.
Правило #3: не злоупотреблять mod_rewrite-ом, не использовать виртуальных путей для статических файлов (jpg, gif, css, js и т.д.)
статика должна быть статикой
Далеко не всегда. Для элементов дизайна — да, однозначно. А если вы, например, раздаете mp3 за деньги, то совсем не так. То, что через mod_rewrite может спокойно отдавать статику есть в пункте выше.
Правило #4: использовать полные пути при работе с файлами и хранить пути к папкам в конфиге
т.к. статику обычно переносят на другой сервер
Слишком категорично. Полные пути, конечно, избавляют от многих проблем. Но структура папок может быть динамической (как в том же Друпале). Тут все зависит от архитектуры проектируемой CMS. А статику переносят на другой сервер достаточно нагруженные проекты. Особенно странно звучит это утверждение, в свете что вы закладываетесь на владельцев говнохостинга где нет .htaccess (опять же если речь идет про Apache).
Правило #5: не бойтесь кэшировать контент в файлы, статическая html-ка отдается быстрее чем php-скрипт открывающий файл с кэшем на диске.
не забывайте, можно кэшировать не только html но и xml и т.п.
И здесь все зависит от архитектуры. Кеширование вообще отдельная тема. Часто кешировать надо на уровне блоков.
Правило #6: при рендере страницы не должно быть лишних SQL-запросов вставляющих записи в таблицу
статистику отдайте Google Analytics и логам веб-сервера
Получается что любой модуль CMS, ведущий статистику – лишний? Google Analytics – хорошо, но лучше предоставить пользователю CMS выбирать что лишнее, а что нет.
Правило #7: чем проще SQL запрос, тем больше его скорость работы
сопоставление таблиц — это красиво, но не эффективно, особенно при больших объемах
Да, известно, что MySQL не очень любит join-ы (если вы про них), но тут совсем все не так однозначно. Бывает и join эффективнее, чем разбиение на несколько запросов. В любом случае есть EXPLAIN, и возможность тюнинговать запросы, если хочешь сделать быструю CMS.
Правило #8: использовать минимум индексов, избавиться по возможности от индексов в текстовых полях
чем больше индексов, тем больше время записи и не забывайте, что во время записи лочится таблица
Во-первых таблица лочится только в MyISAM, в InnoDB лочится строка (если речь идет про MySQL).
Во-вторых минимум индексов не есть оптимально. Индексы прекрасный инструмент ускорения выборки, но их надо тоже тонко проектировать в зависимости от того какие преимущественно запросы будут к таблице.
Правило #9: не использовать поля с полнотекстовым поиском в основных таблицах
для поиска используйте отдельную таблицу
Это все зависит от того, как реализовывать поиск. Возможно, если вы напишете статью, как эффективно организовать поиск, где будет показано что отдельная таблица эффективнее в очень широком круге применения, то тогда можно будет претендовать на однозначность.
Правило #11: PHP, все-таки, объектно-ориентированный язык, поэтому обращайтесь не напрямую к серверным переменным ($_SERVER, $_POST, $_GET, $_SESSION) — используйте объекты
Некоторые переменные в других веб-серверах имеют другие имена, а некоторых вовсе нет и их придется вычислять или придумывать (печально дело обстоит с сессиях)
Вообще первый раз об этом слышу. Либо я чего-то упустил в этой жизни, либо это ерунда. Приведите, пожалуйста пример версии PHP или хостинга, где переменные имеют другие названия. Например, $HTTP_GET_VARS – это не другое название, это устаревшее название.
Все тут упирается в вопрос, как вы масштабируетесь. Если вы покупаете вместо виртуального хостинга выделенный сервер, это одно (для этого половина ваших советов не принципиальна). Если к выделенному серверу покупаете еще один под базу, то почти все ваши советы (кроме оптимизации запросов и модреврайтов на статику) не принципиальны. Если вы масштабируете двух серверную архитектуру, то правила у вас уже будут другие)).
Про индексы, как уже высказывались, вы не правы. Тот же InnoDB спасает по вопросам лока.
А про кэш — это опять же говорили уже, отдельная и весьма объемная тема.
Вывод: давать такие советы нужно в контексте архитектуры, чтобы понятна была среда (сколько серверов, где мускуль, есть ли распределенная бд или фс, сколько даунлоадеров или все это просто один виртуальный хостинг).
Про индексы, как уже высказывались, вы не правы. Тот же InnoDB спасает по вопросам лока.
А про кэш — это опять же говорили уже, отдельная и весьма объемная тема.
Вывод: давать такие советы нужно в контексте архитектуры, чтобы понятна была среда (сколько серверов, где мускуль, есть ли распределенная бд или фс, сколько даунлоадеров или все это просто один виртуальный хостинг).
Статья для читательниц журнала Cosmopolitan.
Очередной бесполезный и ограниченный набор советов
Ой-ё-моё
Всётаки сумели запутать!
Всётаки сумели запутать!
Перенесите в блог «Юмор на Хабре», пожалуйста :)
Для такого рода творчества, думаю, лучше подойдёт блог с названием «Я плакал!» :)
Поспорил бы со второй частью 7го правила
Много спорных и ничем не обоснованных советов…
Да почему спорных ине обоснованных, я бы сказал ожидаемых.
Первая фраза статьи «Уже не раз сталкиваюсь с подобной проблемой, когда люди приходят и просят помочь в решении проблем распределения нагрузки при внезапном возрастании аудитории их сайтов»
При затачивании проекта и увеличение его производительности от оберток для БД отказываются, т.к. они занимают время на инициализацию и управление. Ну и вообще, многое можно покритиковать. Все как-то скопом и разрознено.
При затачивании проекта и увеличение его производительности от оберток для БД отказываются, т.к. они занимают время на инициализацию и управление. Ну и вообще, многое можно покритиковать. Все как-то скопом и разрознено.
Весь текст про то как сделать лучше и в конце такой ляп — 11ое правило. Ну зачем городить огород и для доступа к суперглобальным массивам использовать ООП?
>> (печально дело обстоит с сессиях)
исправьте на «в сессиях»
исправьте на «в сессиях»
читал комментарии весь вечер. Много думал… :)
… о чём? :)
угу, что примечательно, многие повторяют друг за другом «советы чушь, пост ацтой», однако при этом в треде скопилось довольно много реально ценных, особенно для начинающих, комментов, и тред из ацтойного превратился в полезный.
и всем впустую фыркающим следует сесть и запостить свой развернутый список советов и опыта, вместо того, чтобы засорять ценные комменты
и всем впустую фыркающим следует сесть и запостить свой развернутый список советов и опыта, вместо того, чтобы засорять ценные комменты
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Я бы добавил под #12:
Сначала разрабатываем архитектуру проекта (контроллеры, вьюеры, бд, связи и т.п. ) — потом подбираем инструментарий (язык, fw и т.п.)
Чтобы потом не было ремонта двигателя через выxлопную систему.
Сначала разрабатываем архитектуру проекта (контроллеры, вьюеры, бд, связи и т.п. ) — потом подбираем инструментарий (язык, fw и т.п.)
Чтобы потом не было ремонта двигателя через выxлопную систему.
НЛО прилетело и опубликовало эту надпись здесь
Походу мне намеренно заминусовали карму, теперь не могу постить, позже гдде-нибудь еще выложу как и обещал продолжение…
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Советы для разработчиков CMS и фреймворков на PHP