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

Редактирование на странице и CSS

< Лекция 2 || Лекция 3: 1234 || Лекция 4 >

Перенос сайта и подключение к mysql

Обычно код сайта меняется на "домашней" машине, а потом изменения переносятся на сервер. И несколько неудобно каждый раз при копировании файла index7.php (например) потом руками менять в нём данные для подключения к mysql (на сервере ведь один пользователь, а дома – другой).

Поэтому мы всё дальше уходим от мечты – сделать сайт "в одном файле php". Выносим данные для подключения в файл dns.php. Это будет маленький файл с массивом настроек внутри (mysql пользователь, пароль, бд...), его надо будет исключить из синхронизации при автоматическом обновлении файлов сайта из внешнего источника.

Заодно в этом файле будет метка, указывающая на доступ к командной оболочке shell (не на всех хостингах это возможно – ну, или вдруг где-то у нас проскользнёт сервер под windows, например). Если метка положительная, мы будем обрабатывать (например) картинки сразу convert'ом, без использования "изобразительных" функций php.

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

1. В функции response в массив $valid мы должны добавить новые функции: dump, load_sql, rm_page, create_page. Последние две – это долг за прошлую версию (05): там уже были сделаны кнопочки на javascript "Удалить страницу" и "Добавить страницу", но они не будут работать, пока мы не создадим и не разрешим соответствующие функции в php-коде.

2. Все эти "пишущие" функции будут или менять содержимое сайта или выдавать его полностью пользователю (выгрузка sql). Это значит, в начале каждой такой функции мы должны проверять авторизацию пользователя и отказываться выполнять функции, если пользователь не авторизован. Пользователь у нас пока один, а позже нужно будет ещё и разделить права на выполнение этих функций для пользователей с разными статусами. Создадим для этого функцию _us().

3. Часть функций потребует достаточно сложной работы с mysql, поэтому придётся добавить соответствующие функции внутри нашего класса Mysql: во-первых функцию insert_id, которая будет возвращать id последней вставленной в таблицу записи (чтобы можно было перенаправить пользователя на вновь созданную страницу – по её идентификатору).

Затем нужна будет функция dump_table, выгружающая таблицу в sql-файл (точнее в файл sql.gz). Это будет целая группа функций, обеспечивающая выполнение следующих задач: основная функция проверяет всякие входящие параметры (например, можно выгружать не целую таблицу, а часть), создаёт sql для выборки данных, добавляет с помощью дополнительной функции add_create_table текст запроса на создание таблицы и, наконец, вызывает основную функцию выгрузки sqldump_long_sql. Вставка "_long_" в названии функции говорит о том, что можно выгружать таблицы очень большого размера (больше, чем php может удержать в оперативной памяти): php выбирает из БД данные небольшими фрагментами (около 300 килобайт) и дописывает их в файл sql.gz, каждый раз подставляя в начало фрагмента заголовок запроса вида "insert into mypages (id, title, html1...) values ".

Затем нужны будут две функции для загрузки в БД из созданного нами файла sql.gz: основная – handle2bd (читает sql из файла и копит его в памяти), и дополнительная – flush_sql (вызывается каждый раз, когда основная функция обнаруживает в строке sql разделитель запросов – точку с запятой и перенос строки \n).

4. Функция "Добавить страницу" должна не просто выполнить sql-запрос на вставку строки (insert into mypages...) с какими-то дефолтными значениями; желательно обеспечить какую-то минимальную защиту от вставки большого количества пустых (полупустых) страниц. Для этого мы добавляем в таблицу mypages поле mark – "метка" со значением по умолчанию "-8". А отображать в меню будем только страницы с меткой "1" и больше (положительными числами).

Если редактор попытается второй раз нажать кнопку "Добавить страницу", мы ищем в таблице страницу с меткой "-8", и если находим, не добавляем второй раз новую страницу, а пересылаем редактора на уже созданную.

Метка "-8" заменяется на метку "1" при любом обновлении строки таблицы с помощью функции write (при успешном обновлении там вызывается функция onwrite_mypages). То есть если редактор изменил вручную какое-либо поле на странице, мы считаем, что страница перестала быть "новой".

5. Функция rm_page, конечно, намного проще – просто выполняем запрос на удаление. Удаление безвозвратное, поэтому javascript перед вызовом php-функции переспрашивает редактора, уверен ли он в своём желании удалить страницу (защита от случайного нажатия кнопки).

6. Чем сложнее становится код, тем больше ему (точнее, программисту) требуется "обслуживающих" функций. Сейчас, при отладке функции dump, нам понадобилось посмотреть, как передаётся массив параметров от dump к Mysql::dump_table. Но функция перенаправляет нас на загрузку файла, и браузер не отображает страницу с ошибкой работы функции – мы не можем воспользоваться обычным print>_r. Поэтому мы создаём лог-файл и туда выгружаем искомый массив:

log_w(var_export($param, true))

Лог-файл создаётся функцией log_w, которую мы специально для этого же и написали.

7. Ещё нам понадобилось написать функцию для создания директории. Функция, собственно, уже есть в Phpmkdir. Но нам а) не надо создавать директорию, если она уже есть (надо проверять существование файла), б) если есть файл (а не папка) с таким именем (вдруг, случайно), его надо удалить. И только потом создавать папку вместо одноимённого файла. Заодно подправляем права (на 0755). То есть несколько более сложная логика, чем просто создать папку:

function mkdir_safe( $dir, $force ) {
	$ret = false;
	if (file_exists($dir)) {
		if (is_dir($dir)) $ret = $dir;
		else if ($force) unlink($dir);
	}
	if (!$ret && (mkdir($dir, 0755, true))) $ret = $dir;
	if ($ret) chmod($dir, 0755);
	return  $ret;
}

Вот 4 файла очередной версии (06): index.php, core.php, site.js, site.css – код вырос до ~43 килобайт (в предыдущей версии было ~36).

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

Этот курс ( Практикум по разработке 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.  И не пойму как исправить ситуацию.