Опубликован: 22.10.2016 | Доступ: свободный | Студентов: 828 / 84 | Длительность: 04:02:00
Лекция 1:

Обзор технологий. Начало кодирования

Лекция 1: 1234 || Лекция 2 >

Кодировка UTF-8

До сих пор мы неявно исходили из того, что и файлы php, и данные в Mysql, и обмен данными между Php и Mysql используют одну и ту же кодировку символов – utf-8. Вряд ли на самом деле это так (особенно если вы работаете под Windows). Поэтому вы вполне можете видеть в своих файлах вопросики вместо русских букв (или "кракозябры").

Мы указали в мета-тэге html-страницы кодировку UTF-8 явно. То же самое надо сделать ещё в трёх местах:

  1. Сразу после соединения с Mysql ($link = mysqli_connect("localhost", "admin", "adminadmin@", "unsinn");): $sql = 'set names utf8'; mysqli_query($link, $sql); (для Mysql надо писать именно так, без дефиса: 'utf8');
  2. Кодировка, используемая при обработке текстов в Php: setlocale(LC_ALL, 'ru_RU.UTF-8', 'ru_RU'); (надо указать в начале файла php);
  3. Кодировка http-ответа сервера для браузера: header('Content-Type: text/html; charset=UTF-8');

И ещё одна деталь: вы пишете php-код в текстовом редакторе, и надо сохранять ваши файлы тоже с использованием кодировки utf-8.

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

Примерно так: index2.php?code http://nichtig.ru/index2.php?code.

Тогда вместо вопросиков вы сможете увидеть русские буквы: index2.php http://nichtig.ru/index2.php

Пока Mysql не начал работать

Мы пытаемся создать универсальный фрагмент кода (для будущей CMS), который можно было бы использовать для создания новых сайтов. Это значит, достаточно типична будет ситуация, когда нужной нам таблицы Mysql ещё не существует (или она пуста). Создателю нового сайта (кто бы он ни был – программист или астролог) будет не очень приятно видеть малопонятное сообщение mysqli_connect_error или вовсе пустую страницу. Мы должны обработать эту ситуацию и либо сообщить пользователям, что это новый сайт, либо (в режиме debug) дать подсказку программисту.

1. Мы берём данные из массива $row, который получаем из БД путём сложных манипуляций. Значит, нам нужно заполнить этот массив значениями по умолчанию и последовательно проверять все манипуляции с mysql, чтобы в случае любой неудачи массив так и оставался бы с первоначальными значениями. Результат – в файле http://nichtig.ru/index3.php?code:

<?php
//...
$row = !$debug
? array(
	'title' => 'Новый сайт',
	'html1' => 'Это новый сайт',
	'html2' => 'Его содержание coming soon',
	'img1' => 'img1.jpg',
	'img2' => 'img2.jpg',
)
: array(
	'title' => 'Новый сайт',
	'html1' => 'Если вы видите эту надпись, значит, вам нужно 
	а) ввести правильные значения для Пользователя (вместо unsinn), 
	Пароля (вместо go68dbs) 	и БД (вместо второго unsinn) для подключения mysql 
	в строке 	кода mysqli_connect("localhost", "unsinn", "go68dbs", "unsinn");',
	'html2' => 'б) в выбранной базе данных вам нужно создать таблицу 
	и наполнить её данными, выполнив sql-запрос из файла 
	<a href="source1.sql">source1.sql</a>,
	'img1' => 'img1.jpg',
	'img2' => 'img2.jpg',
);
$link = mysqli_connect("localhost", "my_user", "my_password", "my_bd");
if (mysqli_connect_errno()) {
	if ($debug) print('Соединение не удалось: ' . mysqli_connect_error());
}
else {
	$sql = "SELECT * FROM `mypages` where id = " . (int) $id;
	if ($result = mysqli_query($link, $sql)) {
		$row = mysqli_fetch_assoc($result);
	}
}
//...
?>

Не забудьте убедиться, что в папке вашего сайта есть файл source1.sql http://nichtig.ru/08/source1.sql.

Выше мы привели код запроса Mysql для создания нужной нам базы данных ("unsinn"). Но мы живём в реальном мире; для веб-программиста это означает: мы зависим от особенностей конкретного хостинга – не всегда можем создать БД с нужным нам именем, и иногда должны использовать то, что есть. Поэтому мы даём рекомендацию программисту ввести другие имя пользователя mysql и пароль (предполагая, что он не смог выполнить приведённую выше инструкцию по созданию собственной БД).

2. Мы добрались до ошибки (п. 4 "" : в коде всё корректно, mysql работает, таблица mypages есть, но в ней нет записи с номером 21. Что в этом случае выдаст наш код? Пустую страницу. Казалось бы, ничего страшного. Откуда вообще пользователь возьмёт число 21 (или 221)?

В вебе как нигде действует принцип Мэрфи: если неприятность может случиться, она случается. Вы глазом моргнуть не успеете, как анализатор сайта webmaster.yandex.ru покажет, что у вас на сайте не 20, а 20000 страниц с одинаковым содержанием. Потому что вы нарушили протокол. Это тоже не вопрос программиста, а совершенно уже непонятно чей вопрос, поэтому протокол HTTP нарушается на сайтах сплошь и рядом.

В самом начале рассуждений о "фрагменте общего кода" мы упустили из виду одну очень важную деталь – общими для большинства сайтов являются не только doctype, но и так называемые "заголовки HTTP". Вы легко можете увидеть их в отладчике любого современного браузера. Когда наш сайт состоял из файлов html, нам можно было не думать о заголовках, так как их автоматически отправляет веб-сервер Apache: если файл index.html существует, Apache вместе с содержимым этого файла отправляет заголовок "HTTP/1.1 200 OK", если файл не существует, Apache отправляет заголовок "HTTP/1.1 404 Not Found".

Наша ситуация с id > 20 как бы говорит нам, что "файл не существует", нет таких данных. Но реальный-то файл index1.php есть, и Apache всё равно отправляет заголовок "HTTP/1.1 200 OK" – и так для всех 20000 пустых страниц, которые поисковики исправно пытаются индексировать, а потом заносят ваш сайт в чёрный список.

Решение: мы должны проверить, существует ли запись с номером 21, не пуста ли она; и если существует, заполнить массив $row её значениями, а если она пуста, так и сказать об этом пользователю – дескать, 404 not found, извини:

<?php
//...
	if ($result = mysqli_query($link, $sql)) { //проверяем ошибки sql
		if ($result->num_rows)
			$row = mysqli_fetch_assoc($result);
		else {
			header('HTTP/1.1 404 Not Found'); //требуется протоколом
			exit('404 Not Found'); //чтоб пользователь тоже видел
		}
	}
//...
?>

У объекта $result (в нашем случае – Mysqli::$result) есть свойство num_rows, нам достаточно проверить это свойство (количество строк), чтобы знать, удастся ли получить запись. Всё вместе теперь будет выглядеть примерно так: http://nichtig.ru/index3.php?code. Перепишите код в Папку вашего сайта, назовите его index3.php и попробуйте открыть ссылку http://localhost/index3.php?id=22 (чтобы убедиться, что получите ответ 404 not found).

Конечно, и в этом случае ничто не помешает вашему конкуренту отправить на Яндекс кучу ссылок, ведущих на несуществующие страницы вашего сайта. Но разница будет в том, что ваш сайт теперь будет давать правильные ответы (404 – "Страница не существует"), и Яндекс не будет пытаться индексировать их содержание.

Наш фрагмент-шаблон вроде бы готов к размножению сайтов с невероятной скоростью. Осталась сущая мелочь – что делать, если владелец сайта всё-таки захочет поменять "гадание на кофейной гуще" на "гадание по картам Таро"? Предложить ему править ячейки таблиц в phpMyAdmin'е? или напрямую – писать sql-запросы? Вот с этого момента и начинается настоящая работа над CMS – создание редактора, в котором владелец сайта (неквалифицированный пользователь) мог бы редактировать тексты и добавлять и удалять страницы (т.е. строки в таблице mysql).

Лекция 1: 1234 || Лекция 2 >
Михаил Гутентог
Михаил Гутентог

Этот курс ( Практикум по разработке CMS ) создавался, когда у PHP была версия 5.3 или 5.4. Со временем какие-то функции PHP устаревают (mysql, each), какие-то начинают работать по-другому (empty). Пожалуйста, следите за изменениями в PHP по сайту php.net!

Александр Мельников
Александр Мельников

Изучаю курс "Практикум по созданию CMS" в листинге 4.3

$n = count($_GET); if ($n > 0) { $param = each($_GET); // самое простое: пропускаем только первый параметр if ($n > 1 || !isset($valid[$param['key']])) { _404(); }

При попытке просмотра в браузере получаю ошибку: Deprecated: The each() function is deprecated.  И не пойму как исправить ситуацию.