Frontend vs Backend

Программирование

Метки (теги) : , , , ,

Автор: admin

Сделав за свою карьеру не один десяток сайтов, пришел к одному выводу. И вывод это такой: чем лучше написан backend, тем проще писать frontend. И это не просто слова, а вполне реальный факт, который я вынес за почти 5 лет работы.

В последнее время средние и большие проекты в нашей организации пишутся двумя программистами. Вот примерный ход работы над каким-либо бизнес порталом или большим сайтом для не коммерческой организации (сразу оговорюсь, что backend я тоже пишу, но несколько реже, это зависит не от меня):

  1. Мой сотрудник по тех. заданию пишет backend.
  2. Я в это время верстаю страницы из готовых psd дизайнов.
  3. Как только созданы таблицы в базе данных, и определена логика, я начинаю заполнять html шаблоны данными из базы данных.
  4. и т.д.

И вот тут начинается самое интересное. Так как я надеюсь, что логика backend выполнена на высшем уровне, я и не делаю очевидных проверок в скриптах на frontend. Кто-то конечно скажет, что проверки делать обязательно везде и всегда, но мне из опыта известно совсем другое. Как правило хостинги последнее время начинают урезать количество запросов в секунду к серверу БД. И я считаю это правильным, так как существуют вполне себе известные cms, которые не заботятся об этом факторе и у них на главной странице запросов к БД больше 30-40, хотя если все пересмотреть и подумать хорошенько, и воспользоваться join или выборкой из нескольких страниц, то это число можно сократить как минимум вдвое. Также очень  важно спроектировать изначально правильно структуру таблиц и связи между ними, учитывая преимущества реляционных БД, или преимущества NoSQL БД.

Ниже я буду приводить те примеры, которые видел сам и от которых хочу предостеречь вас. Так же хочу заметить, что эти примеры будут приводиться на php, mysql, но на самом деле не важно каким языком программирования и БД вы будете пользоваться. Главное здесь логика, взаимосвязь между логическими еденицами.

Пример 1

Исходные данные:

таблица БД “keywords” содердит ключевые слова для неких статей и других контентных страниц. Вот ее структура

id name
1 Hello
2 Code
3 Site

таблица БД “articles” тут все понятно, содержит поля типичные для статей. Я приведу лишь необходимую для примера структуру таблицы

id title content active keywords
1 test 1 test content 1 1 1,3
2 test 2 test content 2 1 2,3

как видите в поле keywords таблицы article записываются id кейвордов из таблицы keywords через запятую

Кто скажет сколько запросов нужно выполнить чтобы сделать поиск по кейвордам и вывести только те статьи, которые содержат найденные кейворды.
Тут и думать не нужно, первый запрос выведет все кейворды удовлетворяющие условию поиска из таблицы keywords, с помощью php мы сформируем массив $arrayKeywords из id, например “1,3″ и потом сделаем запрос к таблице articles, где в where используем такое условие articles.keywords REGEXP “[[:<:]]$str[[:>:]] OR  … (это условие через “OR” нужно повторить ровно столько раз сколько элементов в массиве  $arrayKeywords), где $str это одно id из массива arrayKeywords. Как видите запрос может получиться очень и очень длинным.

Основная задача, избежать лишнего запроса и соответственно ненужность php скрипта формировавшего строку айдишек и уменьшить длину основного запроса.

Первое что нужно сделать  - это создать еще одну таблицу “article_keyword” (название может быть любым), в ней будет всего два поля

id_article id_keyword
2 2
2 3

Думаю что тут все понятно, id_article – это id статьи, id_keyword – это id кейворда. Поле keywords в таблице articles уже не нужно.

Теперь я напишу sql запрос который выдаст только те статьи, в которых присутствуют найденные кейворды

SELECT DISTINCT article.id, article.title, article.content FROM keywords, article_keyword, articles WHERE keywords.name LIKE ‘hel%’ AND article_keyword.id_keyword = keywords.id AND articles.id = article_keyword.id_article

 

Пример 2

Часто встречается такая проблема: при редактировании какого-либо материала в backend – е, если поле имеет редактор типа TinyMCE или FCKEditor и в поле что-то пописать, а потом все стереть, то остается либо <br /> , либо &nbsp; , либо еще какой-то html тег . Если даже ничего в поле не вставлять, все равно там будет один из этих тегов. Как правило его так и записывают в базу. Ну конечно если это поле не обязательное к заполнению. А потом начинаются трудности. При выводе во frontend функция trim не приносит нам никакой помощи, так как пробел этот является html мнемоникой. И если нам нужно сделать проверку, выводить тег, обрамляющий текст из редактора, только в том случае, если это поле пустое, то такая проверка тоже не прокатит if( strlen($value)>0 ), так как $value содержит html мнемонику(и). В данном случае, если не брать во внимание backend, то для решения данной проблемы нужно писать регулярные выражения. Вроде бы ничего страшного.

Правильное решение данного вопроса:

Нужно в админке (backend) перед сохранением в БД данных этого поля, сделать такую проверку :

if(strlen(preg_replace(‘/^&nbsp;/i’, ”,trim(strip_tags($value))))>0){
записывать в базу значение переменной
}

else {
запись в базу пустого значения
}

Теперь самое важное – оценим пользу в случает проверки в backend – е.
Материал в админке редактируется как правило редко, точнее на него тратят время при создании, потом еще пару часиков на поправление всяких недочетов в словах или оформлении. То есть можно предположить, что проверка которую я привел для админки будет отработана в среднем раз 100 в год, 5 материалов – 500 в год. А теперь посмотрим на frontend (клиентская часть). Если предположить, что на сайте 5 статей с нашим полем и каждую посещают минимум 3 человека в день, то за год выходит в среднем 5500 проверок. Ну думаю дальше объяснять не нужно. 99% проверок над данными нужно делать в админке – это факт.

 

Пример 3

Этот пример непосредственно касается SQL. Часто так бывает, что программисты хорошо знают язык программирования, но не достаточно полно владеют языком запросов SQL .
Не один сайт не обходиться без включения или выключения какого-то материала в определенный момент времени. Часто поле отвечающее за эту фунцию называют “active” и значение оно может принимать либо 0 (деактивировано), либо 1 (активировано). В админке, как правило, в списке этих материалов есть кнопочка рядом с этим материалом, нажимая на которую мы либо активируем деактивированный материал, либо наоборот. Вот как делает большинство знакомых мне программистов: они посылают на сервер ajax запрос и двумя SQL запросами меняют значение поля “active”. Первым запросом узнают текущее значение поля данной записи, и в зависимости от значения, записывают в поле либо 0, либо 1. Вот пример кода:

$select = mysql_query(‘SELECT `active` FROM `articles` WHERE id=1′);
$result = mysql_fetch_array($select);
if($result ['active']== 0){
mysql_query(‘UPDATE `articles` SET active = 1 where id=1′); // записываем в поле 1, то есть активируем запись
} else {
mysql_query(‘UPDATE `articles` SET active = 0 where id=1′); // записываем в поле 0, то есть деактивируем запись
}

Здесь как минимум две лишние операции, первая – это “$select = mysql_query(‘SELECT `active` FROM `articles` WHERE id=1′);” , вторая – “if($result == 0)” . Весь выше приведенный код можно уместить в одну строку запроса. Вот она, берите и пользуйтесь на здоровье :

UPDATE `articles` SET active = IF(active = 1, 0, 1) where …

Но и это еще не все глупости,  которые, обычно, делают некоторые молодые (а может и со стажем тоже) программисты. Вот пример как делать не нужно :

если в списке материалов в админке, мы выбрали несколько материалов, отметив чекбоксы, а потом передали на сервер список id  этих материалов и на сервере получили из строки $stringId, например 1,2,3,4,5,6, массив $arrayId то не нужно в цикле делать вот так :

foreach($arrayId AS $k => $v){
$select = mysql_query(“SELECT `active` FROM `articles` WHERE id=’$v’”);
$result = mysql_fetch_array($select);
if($result ['active']== 0){
mysql_query(“UPDATE `articles` SET active = 1 where id=’$v’”); // записываем в поле 1, то есть активируем запись
} else {
mysql_query(“UPDATE `articles` SET active = 0 where id=’$v’”); // записываем в поле 0, то есть деактивируем запись
}
}

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

foreach($arrayId AS $k => $v){
mysql_query(“UPDATE `articles` SET active = IF(active = 1, 0, 1) where id=’$v’”);
}

Вот правильный вариант, ну возможно не самый самый правильный, но более правильного я не знаю. Ну уж извините …

mysql_query(“UPDATE `articles` SET active = IF(active = 1, 0, 1) where id IN ($stringId)”);

Ясное дело что все переменные, которые участвуют в sql запросах нужно проверять, чтобы не оставлять лазейки для злоумышленников

Продолжение здесь Frontend vs Backend, часть 2

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

Оставить комментарий