Начал изучать веб программирование. Пишу в учебных целях сайт с регистрацией, авторизацией, личным кабинетом и т.д.
На практике, как я понимаю backend и frontend программисты пишут отдельно серверные и клиентские части. Потом все это магическим образом вместе работает.
У меня обработка БД, и вывод клиенту все в одном файле, что типо этого:
<?php
session_start();
header("Content-Type: text/html; charset=utf-8");
?>
<html>
<head></head>
<body>
<?php
if(isset($_COOKIE['id']))
{
$db = mysqli_connect("localhost","root","","usersbase");
mysqli_set_charset($db, 'utf8');
$id = $_COOKIE['id'];
$sql = "SELECT * FROM users WHERE id = '$id'";
$result = mysqli_query($db, $sql);
$row = mysqli_fetch_array($result);
$logo = $row['logo'];
$str_logo = "<div id=\"user_auth_logo\"><img src=\"http://cr.com/$logo\" width=\"25px\" heigth=\"25px\"></div>";
echo $str_logo;
}
?>
</body>
</html>
Там ещё много html кода..
Насколько правильно так писать? И как это реализуют на практике, если делать правельно?
Лучше так не писать. Смешивать разметку и код -- плохой тон. Потом, когда кода станет больше, будет очень сложно разобраться что к чему.
Для начала разделите разделите HTML-разметку и код. Создайте отдельный файл для общей разметки страницы layout.php
:
<html>
<head></head>
<body>
<?php echo $content ?>
</body>
</html>
Теперь вы можете подключить этот файл в вашем файле:
$content = "<div id=\"user_auth_logo\"><img src=\"http://cr.com/$logo\" width=\"25px\" heigth=\"25px\"></div>";
require 'layout.php';
Обратите внимание, что при подключении файла layout.php
, в нём стали доступны все переменные той области видимости, в которой он подключён.
С одной стороны это позволило использовать переменную $content
, но с другой нам приходится помнить о всех переменных, чтобы случайно не изменить их.
Кроме того, подключённый шаблон тут же отправится на вывод, что не всегда желательно. Что бы не беспокоится об этом, удобно использовать вот такую функцию:
/**
* Подключение файла с буферизацией вывода
* @param string $file
* @param array $params
* @return string
*/
function ob_include($file, array $params = []) {
extract($params);
ob_start();
require func_get_arg(0);
return ob_get_clean();
}
(почитайте на php.net, что делают фунции extract
, ob_start
и ob_get_clean
, это полезно и интересно)
Меняем require 'layout.php';
на $html = ob_include('layout.php', ['content' => $content]);
. Теперь весь HTML оказался в переменной $html
!
И вы можете решать, когда именно его выводить, например, только после отправки заголовков:
header("Content-Type: text/html; charset=utf-8");
echo $html;
Как видите, такой код становится более понятным. Сперва вы готовите данные и только затем занимаетесь их отправкой (вызывая header и echo). Всё на своих местах.
Теперь можно содать файл-шаблон для логотипа. Например logo.php
:
<div id="user_auth_logo"><img src="http://cr.com/<?php echo htmlspecialchars($logo) ?>" width="25px" heigth="25px"></div>
Обратите внимание на функцию htmlspecialchars
. Она нужна для того что бы ваша вёрстка не развалилась, если в имени логотипа случайно окажутся
символы, которые могут быть интепретированы как HTML-разметка. Кроме того, она предохраняет ваше приложение от возможных XSS-атак (https://ru.wikipedia.org/wiki/Межсайтовый_скриптинг).
Правим код, получается:
$content = ob_include('logo.php', ['logo' => $logo]);
$html = ob_include('layout.php', ['content' => $content]);
header("Content-Type: text/html; charset=utf-8");
echo $html;
И ещё один важный момент. Для безопасности вашего сайта и его пользователей, никогда не доверяйте данным, которые пришли извне. В Вашем случае это
массив $_COOKIE
, в которым находятся данные из HTTP-заголовка Cookie
. Злоумышленник может передать в этом заголовке данные, на которые вы не расчитывали! И тогда в вашу базу данных улетит не тот запрос, который вы написали (https://ru.wikipedia.org/wiki/Внедрение_SQL-кода).
Экранируйте переменные в запросе, используя mysqli_real_escape_string
или подготовленные выражения из библиотеки PDO
.
Вот что получается в итоге:
<?php
session_start();
$db = mysqli_connect("localhost","root","","usersbase");
mysqli_set_charset($db, 'utf8');
$id = isset($_COOKIE['id'])? $_COOKIE['id'] : null;
if ( ! $id) {
// обработка исключительных ситуаций очень важна, здесь упрощённый вариант для примера
throw new \Exception('Произошла неожиданная ошибка: id не задан');
}
$safeId = mysqli_real_escape_string($db, $id);
$sql = "SELECT * FROM users WHERE id = '$safeId'";
$result = mysqli_query($db, $sql);
$row = mysqli_fetch_array($result);
if ( ! $row) { // точно не известно, что именно было в $_COOKIE['id'], возможен пустой результат
throw new \Exception("Произошла ошибка: нет записей для id $id");
}
$content = ob_include('logo.php', ['logo' => $row['logo']);
$html = ob_include('layout.php', ['content' => $content]);
header("Content-Type: text/html; charset=utf-8");
echo $html;
Это для начала :-) Когда кода станет больше, вы обнаружите что удобно завести отдельный объект для работы с базой данных и инициировать только один раз; Захотите ограничить доступ к файлам шаблонов и поместите их в директорию недоступную из интернета; Определите единственную точку входа и напишите маршрутизатор. Двигайтесь от простого к сложному, изучайте документацию PHP и открытые php-проекты (возможно особенно вас заинтересуют фрэймворки https://ru.wikipedia.org/wiki/Категория:Каркасы_веб-приложений_на_PHP) и у вас всё получится.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
При формировании email-рассылки во многих инструкциях советуют вставлять List-UnsubscribeНе могу понять, куда именно вставлять? Пишут, что в заголовок
Прошу ввести в курс делаЕсть разные библиотеки для парсинга слышал о jquery слышал о simple_html_dom
Делаю авторизацию на учебном сайтеНадо, чтобы пользователь оставался в сети пока не нажмет на кнопку "выход"
Можно ли подключать css файлы внутри тела страницы, а не в его head?