Отправляет email-рассылки с помощью сервиса Sendsay

Еженедельник сайтостроителя

  Все выпуски  

Пишем первую CMS


Подшивка рассылки (chm)

№58 25.02.10

Определимся с задачами. По запросу «пишем CMS» я не обнаружил блогов, которые были бы мне интересны, как правило, это либо один пост с простым примером, либо раздел с довольно громоздкими классами без пояснений. Моя цель, конечно, не написание CMS, а приобретение навыков, опыта, а написать движок – это неплохой способ достичь этих целей. Соответственно, я постараюсь писать так, чтобы это было понятно не только мне.

Для начала нам нужен план. Что мы хотим получить в конечном итоге? Напишем движок простенького каталога статей. Обозначим цели на ближайшую пару постов. В самом первом приближении первая CMS должна иметь всего два типа страниц:

  • Простой шаблон вывода контента  из базы данных на страницу
  • Панель для добавления этого самого контента в бд

Итак, упростим свою задачу, взяв за основу, как просил читатель, вот этот пост, где подробно описано создание простой CMS на файлах. Конечно, впоследствии, от исходного кода, наверно, ничего не останется, кроме структуры файлов, но пока, на мой взгляд, все будет вполне наглядно. А через пару постов на таком движке уже спокойно можно будет начинать клепать сателлиты)

Ну да шутки в сторону, приступаем. Скачайте вышеупомянутый пример, посмотрите как он работает, поковыряйте код, там все просто и понятно, будут вопросы – задавайте. Предложенный в статье шаблон я немного видоизменил.
В первую очередь давайте вместо вывода статичных страничек подключимся к базе данных и возьмем статью оттуда. Это уже будет отдаленно напоминать CMS.

Раз уж мы учимся, то по пути можно разобрать основы работы с системой управления базами данных MySQL в PHP.
Для подключения к БД напишем отдельный файл config.php.

<?php
$dblocation = "localhost"; //хост бд
$dbuser = "root";  //пользователь бд

$dbpasswd = "";  //пароль пользователя
$dbname="tractor";  //название бд
 
//Подключение к базе данных

$dbcnx = mysql_connect($dblocation,$dbuser,$dbpasswd)
  or die("Ошибка бд: ".mysql_error());

 
//выбираем бд
mysql_select_db($dbname, $dbcnx)
  or die("Ошибка бд: ".mysql_error());

 
//Кодировочка
mysql_query ("set character_set_client='cp1251'");
mysql_query ("set character_set_results='cp1251'");
mysql_query ("set collation_connection='cp1251_general_ci'");

?>

Ха-ха, чуть не забыл, рабочее название нашей CMS – «Tractor Engine» (чем агрегат проще, тем он надежнее), и название БД соответствующее. Ну и раз уж мы заговорили о БД, возможно, стоит пояснить, почему мы пишем первую CMS с использованием СУБД MySQL.

Во-первых, Content Management System подразумевает систему управления контентом более-менее сложной структуры. В противном случае можно обойтись набором html-страничек, и PHP вовсе не нужен. Условно можно разделить движки для сайтов на те, которые для хранения контента используют базу данных, и на те, которые хранят всю информацию в файлах (хотя, возможно и сочетание этих вариантов). Конечно, БД в конечном итоге тоже набор файлов, но система работы с базами данных полностью автоматизирована и уже заточена на максимально быструю работу.

Часть I. Запись в базу данных.

С подключением к MySQL разобрались, теперь давайте попробуем сделать в нее пару записей, чтобы потом было что выводить на страницу. Панель добавления записей:

Admin.php

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=win-1251" />

<title>Tractor Engine: Администрирование</title>
</head>
<? 
include ('config.php');
if (isset($_REQUEST['sub'])) //Если нажата кнопка (name="sub")

 {
//Создаем таблицу, если ее еще не существует
 mysql_query ('CREATE TABLE IF NOT EXISTS te_article(
 id INT AUTO_INCREMENT PRIMARY KEY,
 stamp  TIMESTAMP,
 title varchar (100),
 content TEXT
 )')  or die(mysql_error());
//Делаем запись в таблицу
 $sql = mysql_query("INSERT  into te_article (title, content)
 values ('".$_REQUEST['my_title']."', '".$_REQUEST['my_text']."');");

 }
?>
<body>
<form action="admin.php" method="post">
<p>Заголовок:<br><input name="my_title" type="text" size="50" /></p>

<p>Текст:<br><textarea name="my_text" cols="80" rows="15" ></textarea></p>
<input name="sub" type="submit" value="Отправить" />

</form>
</body>
</html>

Что тут можно пояснить [почесав затылок]. Разве что, извлекая записи из БД, мы будем сортировать их по времени создания, соответственно это время мы указываем в поле stamp. И еще, пожалуй, то, что ни о какой защите мы пока не помышляем (два килобайта кода весь движок:) )

Данные из формы хранятся в глобальном массиве $_REQUEST, туда попадают как post-, так и get-данные, следовательно, отдельно массивы $_GET и $_POST использовать смысла никакого нет.

Выражение isset($_REQUEST['sub']) будет истинно, если в глобальном массиве $_REQUEST существует ключ «sub», создаваемый при нажатии кнопки «Отправить».

Часть II. Шаблон вывода.

Сделав пару записей в БД, можно приступать к выводу этих записей в шаблоне. В нашей CMS уже реализована система, предусматривающая подключение разных типов страниц, в зависимости от выбранной ссылки в горизонтальном меню. В файле index.php, запускающемся, как мы знаем, по умолчанию, вы можете видеть следующее:

iinclude 'config.php';
$page = !empty($_REQUEST['page'])?trim($_REQUEST['page']):$page = "main";   

if ($page) {
 if ((!strpos($page,".")) and (!strpos($page,"/"))) {

 $path = 'inc/'.$page.'/view.php';
 if (file_exists($path)) {

  include($path);
  } else {
  echo '
  <h1>Ошибка!</h1>

  <h1>Такой страницы не существует. </h1>';
  }  
 } else {
 echo '
 <h1>Ошибка!</h1>

 <h1>Доступ запрещен. </h1>';
 }
}

Другими словами, по умолчанию открывается страница, расположенная в папке «main», в ином случае – переданная движку в адресной строке, по средствам нажатия ссылки в меню.

Наша цель − создать страницу «article», которая для начала должна уметь:

  • Выбирать из БД список имеющихся статей
  • Выводить саму статью при нажатии на ссылку с заголовком

По спецификации текущей версии CMS нам нужно создать файл view.php по адресу /inc/article/view.php

View.php

<?php
if ((@$_REQUEST['page'] == "article") &&
(!isset($_REQUEST['id'])))

{
//Выбираем из бд все записи, начиная с последней
$result = mysql_query('
  SELECT *, UNIX_TIMESTAMP(stamp) AS stamp
  FROM te_article 
  ORDER BY stamp DESC
') or die(mysql_error());
for ($db=array(); $row=mysql_fetch_assoc($result); $db[]=$row);

foreach ($db as $rec)
 {
 echo '<a href="?page=article&amp;id='.$rec['id'].'">'.$rec['title'].'</a><br>';

 }
}
elseif ((isset($_REQUEST['id'])) &&
(@$_REQUEST['page'] == "article")) 

{
 
$sql = mysql_query("SELECT * FROM te_article WHERE id='".@$_REQUEST['id']."'");
$record = mysql_fetch_assoc($sql);

 
 if (isset($record['id']))
 {   
 echo '<br><strong>'.$record['title'].'</strong>';

 echo '<hr>';
 echo '<p>'.$record['content'].'</p>';

 }
 else echo "Ошибочка вышла. Статьи с таким id не обнаружено";
}
?>

Условия смотрятся страшновато, но, по крайней мере, работают как нам нужно. Функция UNIX_TIMESTAMP() преобразует значения поля stamp в привычное нам количество секунд, пошедших с начала эпохи Unix. Сортируя выборку по этому значению, получаем список записей, начиная с самых свежих.

В цикле foreach прокручиваем наш список статей, выводя ссылки вида

<a href=”index.php?page=article&id=уникальный_идентификатор_статьи”>Заголовок</a>

Если в ссылке параметр «page» равен «article», и задан id статьи, то получаем соответствующую запись из БД и выводим на экран. Ну и если в ссылке присутствует только тип страницы (article) и не задана статья, то выводим список всех статей, имеющихся в БД.

По-хорошему, нам нужно было отделить код вывода статей от дизайна. На главной странице должен подключаться какой-нибудь блок шаблона content.php, содержащий дизайн вывода основного контента. Этот блок, в свою очередь, подключал бы компонент view.php, содержащий программную часть определенного типа страниц. Но на данный момент весь дизайн составляют несколько html-тегов. Этим можно будет заняться позже.

На сегодня все. Если не знаете, как работает та или иная конструкция, открываем учебник и изучаем принцип ее работы. Затем, при наличии вопросов, излагаем их в комментариях.

Источник
Скачать Tractor Engine 0.01

Партнеры:


В избранное