Этот урок связан с проектом Строим свою CMS на PHP и MySQL

Строим свою CMS на PHP и MySQL. Часть 1

Задача построения системы управления содержанием (CMS) может привести в замешательство новичка разработчика PHP. Но не так страшен черт, как его малюют! В данной серии уроков мы построим простую, но полностью работоспособную систему с нуля.

В ходе процесса вы научитесь создавать базы и таблицы MySQL, работать с объектами, константами, включениями, сессиями и прочими инструментами PHP. Кроме того мы покажем, как отделять логику приложения от презентации и сделать код PHP более безопасным. А также вам откроется многое другое, полезное в деле создания собственной системы мечты.

Вы можете посмотреть работу готового приложения на странице демонстрации (с целью безопасности включен режим "только чтение", так что добавлять, изменять и удалять статьи не получится). Также можно скачать полный код PHP нашей меленькой CMS с переведенными комментариями.

Примечание: для изучения материалов уроков потребуется веб сервер Apache с установленным модулем PHP и сервер MySQL. Для работы на локальном компьютере можно воспользоваться одним из инструментов веб разработчика: XAMPP (на английском языке), Denwer, Open server или другим.

 

demosourse

Функционал нашей CMS

Первым делом надо точно определиться, что будет делать наша CMS. Итак, вот список функций:

Клиентская часть:

  • Главная страница, на которой выводиться список последних 5 статей
  • Страница со списком всех статей
  • Страница просмотра отдельной статьи

Серверная часть:

  • Вход/выход для администратора
  • Список всех статей
  • Добавление новой статьи
  • Редактирование существующей статьи
  • Удаление существующей статьи

Каждая статья имеет собственный заголовок, резюме и дату публикации.

 

Планирование работ

Для создания нашей CMS нужно сделать следующие шаги

  1. Создать базу данных
  2. Создать таблицу articles
  3. Сделать файл конфигурации
  4. Построить класс Article
  5. Написать скрипт клиентской части index.php
  6. Написать скрипт серверной части admin.php
  7. Создать шаблон клиентской части
  8. Создать шаблон серверной части
  9. Создать таблицу стилей и логотип системы

Примечание: на страницах уроков приводится код для нашей CMS готовый к копированию в ваши текстовые файлы. Если у вас нет желания создавать файлы самостоятельно, то можно скачать архив с исходниками, в котором содержатся все нужные папки и файлы.

 

Шаг 1. Создаем базу данных

На первом шаге нужно создать базу данных MySQL для хранения содержания. Можно сделать так:

  1. Запускаем программу клиент  mysql Открываем окно терминала и набираем команду

    mysql -u username -p

    После запроса введите пароль для доступа к MySQL.

    username - имя пользователя, который имеет полномочия для создания баз данных. В случае работы на локальном компьютере можно использовать root, хотя для безопасности всегда следует создавать пользователя с другим именем для решения задач администрирования.

  2. Создаем базу данных После метки mysql> вводим:

    create database cms;

    И нажимаем Enter.

  3. Выходим из программы клиента mysql После метки mysql> вводим:

    exit

    И нажимаем Enter.

Теперь у нас есть пустая база данных, в которой можно размещать таблицы и содержание.

Для решения такой задачи также можно воспользоваться инструментами для администрирования баз данных, таким как phpMyAdmin, cPanel или Plesk (если они установлены на вашем сервере). В некоторых случаях использование подобных инструментов является единственным доступным для пользователя инструментом для работы с базами данных (ситуация зависит от правил, установленных на вашем хостинге).

 

Шаг 2. Создаем таблицу articles

Наша простая CMS имеет единственную таблицу в базе данных: articles. В ней содержатся все статьи в нашей системе.

Создадим схему таблицы. Схема таблицы описывает типы данных, которые могут содержаться в таблице и информацию о ней.

 

Создаем текстовой файл tables.sql на жестком диске и добавляем в него следующий код:

DROP TABLE IF EXISTS articles;
CREATE TABLE articles
(
  id              smallint unsigned NOT NULL auto_increment,
  publicationDate date NOT NULL,                              # Когда статья опубликована
  title           varchar(255) NOT NULL,                      # Полный заголовок статьи
  summary         text NOT NULL,                              # Резюме статьи
  content         mediumtext NOT NULL,                        # HTML содержание статьи

  PRIMARY KEY     (id)
);

Выше приведенный код определяет схему таблицы articles. Он написан на SQL, языке для создания и манипулирования базами данных в MySQL (и во многих других системах).

Разберем выше приведенный код

  1. Создаем таблицу articles Выражение DROP TABLE IF EXISTS articles удаляет любую существующую таблицу articles  (вместе с данным - осторожно!). Мы выполняем данную операцию чтобы в базе не было двух таблиц с одинаковыми именами. Выражение CREATE TABLE articles ( ) создает новую таблицу articles. Код, размещенный в скобках, определяет структуру данных в таблице...
  2. Определяем для каждой статьи уникальный ID Теперь можно определять структуру таблицы. Таблица состоит из набора полей (также их называют столбцами). Каждое поле содержит опредленный тип информации о статье. Сначала мы создаем поле id. Оно имеет тип smallint unsigned (без знаковое маленькое целое), то есть число от 0 до 65,535. Таким образом, наша CMS может содержать до 65,535 статей. Также для него определяется атрибут NOT NULL, который означает, что поле не может быть пустым (null). Данное свойство существенно облегчает труд разработчика. Добавляем атрибут auto_increment, который указывает MySQL назначать новое, уникальное значение для поля id при создании записи. Итак, первая статья будет иметь id  1, вторая - id  2, и так далее. Мы будем использовать уникальные значения как указатели на статью при выводе и редактировании в CMS.
  3. Добавляем поле publicationDate Следующая строка создает поле publicationDate, которое хранит дату публикации каждой статьи. Данное поле имеет тип date, соответствующий значениям дат.
  4. Добавляем поле title Теперь создаем поле title, в котором размещается заголовок. Оно имеет тип varchar(255), то есть может хранить строку длиной до 255 символов.
  5. Добавляем поля summary и content Последние два поля 2, summary и content, содержат резюме статьи (краткое описание материала) и HTML содержание соответственно. Резюме имеет тип text (то есть, может состоять из 65,535). А поле content имеет тип mediumtext (то есть может содержать до 16,777,215).
  6. Добавляем основной ключ Последняя строка в выражении CREATE TABLE определяет ключ для таблицы. Ключ также называют индексом, и он служит для быстрого поиска данных в таблице за счет некоторого увеличения требующегося пространства для хранения. Мы определяем поле id как PRIMARY KEY. Каждая таблица может содержать единственный PRIMARY KEY, так как данный ключ уникально определяет каждую запись в таблице. Кроме того, с помощью данного ключа MySQL очень быстро находит нужную запись.

Теперь у нас есть схема таблицы и ее нужно загрузить в MySQL для создания структуры. Самый простой способ - открыть окно терминала, перейти к папке с файлом tables.sql и запустить следующую команду:

mysql -u username -p cms < tables.sql

...где username - имя пользователя MySQL, а cms - имя базы данных, которую мы создали на шаге 1.

Вводите пароль пользователя после запроса, и MySQL загрузит и выполнит код из файла tables.sql, создав таблицу articles в базе данных cms.

Также можно воспользоваться инструментами для администрирования баз данных, таким как phpMyAdmin, cPanel или Plesk (если они установлены на вашем сервере).

 

Шаг 3. Создаем файл конфигурации

Теперь  у нас есть база данных и мы готовы разрабатывать код PHP. Начнем с создания файла конфигурации для хранения различных установок для нашей CMS. Данный файл будет использоваться остальными скриптами нашей системы.

Первым делом создаем папку cms в папке веб сервера. Она будет содержать все файлы нашей CMS.

В папке cms создаем файл config.php и копируем в него следующий код:

<?php
ini_set( "display_errors", true );
date_default_timezone_set( "Australia/Sydney" );  // http://www.php.net/manual/en/timezones.php
define( "DB_DSN", "mysql:host=localhost;dbname=cms" );
define( "DB_USERNAME", "username" );
define( "DB_PASSWORD", "password" );
define( "CLASS_PATH", "classes" );
define( "TEMPLATE_PATH", "templates" );
define( "HOMEPAGE_NUM_ARTICLES", 5 );
define( "ADMIN_USERNAME", "admin" );
define( "ADMIN_PASSWORD", "mypass" );
require( CLASS_PATH . "/Article.php" );

function handleException( $exception ) {
  echo "Sorry, a problem occurred. Please try later.";
  error_log( $exception->getMessage() );
}

set_exception_handler( 'handleException' );
?>

Разберем код подробно:

  1. Выводим ошибки в браузере Строка ini_set() устанавливает режим вывода сообщений об ошибках в браузере. Отличная опция для отладки кода, но на готовом проекте данную опцию надо отключить ( установить значение false) для безопасности ресурса.
  2. Устанавливаем временную зону Так как наша CMS будет использовать функцию PHP date(), нужно указать временную зону сервера для PHP (иначе PHP будет генерировать предупреждение). В примере установлена зона "Australia/Sydney"поменяйте на свою.
  3. Устанавливаем детали доступа к базе данных Затем определяем константу DB_DSN, которая указывает PHP, где искать базу данных MySQL. Параметр dbname должен соответствовать имени базы данных нашей CMS (cms). Также мы будем хранить имя пользователя MySQL и пароль, которые используются для доступа к базе данных CMS в константах DB_USERNAME и DB_PASSWORD. Установите правильные значения в данных константах, которые соответствуют вашим настройкам.
  4. Устанавливаем пути Мы устанавливаем 2 пути в нашем файле конфигураций: CLASS_PATH, который указывает на место хранения файлов классов, и TEMPLATE_PATH, который указывает на место хранения шаблонов  HTML. Оба пути указываются относительно верхнего каталога cms.
  5. Устанавливаем количество статей, выводимых на главной странице HOMEPAGE_NUM_ARTICLES управляет максимальным количеством заголовков статей, которые выводятся на главной странице. Мы установили 5, но можно легко увеличить или уменьшить значение.
  6. Устанавливаем имя и пароль администратора Константы ADMIN_USERNAME и ADMIN_PASSWORD содержат данные регистрации для администратора нашей CMS.
  7. Включаем класс Article Так как файл класса Article (мы его создадим позже) требуется во всех скриптах нашего приложения, добавим его здесь.
  8. Создаем обработчик исключительных ситуаций В завершение определяем handleException() - простую функцию для обработки исключений PHP, которые могут генерироваться при выполнении кода. Данная функция выводит общее сообщение об ошибке и записывает данные об ошибке в журнал веб сервера. Такая функция способствует улучшению безопасности системы за счет обработки исключений PDO, которые могут выводить имя пользователя и пароль на странице. После определения функции handleException(), мы устанавливаем ее как обработчик исключений PHP, вызывая функцию set_exception_handler().

    Такой обработчик исключений сделан для упрощения материалов урока. "Правильный" способ для обработки исключений для перехвата всех вызовов PDO в  Article.php заключается в использовании блоков try ... catch.

  9. Замечание о безопасности

    В реальных проектах лучше помещать config.php где-нибудь за пределами корневого каталога веб сайта, так как в файле содержатся имена и пароли. Обычно код PHP невозможно просмотреть в браузере, но иногда из-за неправильной конфигурации веб сервера код становится доступным. Вы можете использовать функцию hash() для хэширования паролей и хранить в config.php хэши, вместо текстовых паролей. Затем при регистрации пользователя можно опять воспользоваться функцией hash() для кодирования введенного пароля и сравнения результата с сохраненным в  config.php хэшем.

В следующем уроке мы построим основной класс нашего приложения - Article.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: www.elated.com/articles/cms-in-an-afternoon-php-mysql/
Перевел: Сергей Фастунов
Урок создан: 22 Ноября 2012
Просмотров: 263772
Правила перепечатки


5 последних уроков рубрики "PHP"

  • Фильтрация данных с помощью zend-filter

    Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

    Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

  • Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

  • Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 30 Ноября 2012 11:22
    imya
    ураааа, то, что надо!!!
  • 30 Ноября 2012 13:03
    userseal
    >использовать функцию hash() для хэширования паролей< А почему сразу не md5()? Зачем такие "сложности"?
    • 2 Декабря 2012 12:38
      jonik_lowkick
      md5() более не рекомендуется к использованию...
  • 30 Ноября 2012 13:48
    konstahntin
    Когда следующий урок?
  • 30 Ноября 2012 15:21
    art_gur
    Клёвый мануал! Молодцы!
  • 30 Ноября 2012 16:12
    sv2109
    Полезность этой серии была бы в десятки раз больше если бы для создания этой CMS использовался какой-нить мини-фреймворк, например Silex. А так.. получается очередной непригодный для использования велосипед.
    • 30 Ноября 2012 17:21
      alcorn
      Согласен, намного было бы полезней если бы использовали какой-либо фреймворк.
      • 30 Ноября 2012 18:22
        malina95
        Согласен с предидущем оратором, был бы фреймворк было бы полезней
    • 30 Ноября 2012 20:39
      Magnum79
      Вот про велосипед - прям в десятку! Причем, как показала моя практика (в стремлении создать городской портал я в итоге пол джумлы забацал) это всё равно будет велосипед с квадратными колесами, сколько бы ты напильником не махал.
    • 2 Декабря 2012 12:37
      jonik_lowkick
      Я с Вами полностью согласен, но у этого велосипеда есть огромный "+" - это опыт, который вы приобретаете в процесе написания...
  • 30 Ноября 2012 18:07
    artamonov
    Тоже присоединюсь к уже высказавшимся по поводу фреймворка... понятно, что цель показать новичкам что к чему, но по моему скромному и конечно не авторитетному мнению для новичков контента хоть жопой жуй... В том числе и на этом сайте... А вот тем кто по-опытнее остается только выискавать что-то на буржуйских сайтах... Очень бы хотелось каких-то уроков по фреймворкам, хоть каким, ZF, CI, YII, Symfony etc. К тому же, не в обиду будет сказано автору, мы все очень ценим усилия, но урок получился какой-то уж больно неполноценный... Создали таблицу в БД и 10 переменных конфига... Мне кажется Первая часть должна была завершиться хотя бы созданием первого контроллера с выводом "Хело, ворлд"... А то если вы будете делить все на такие мелкие куски, вы закончите цикл уроков на 146 части... И еще вопрос: а почему ничего не сказано про управление менюхами из админки? Мне кажется Меню сайта и управление им - тоже должно быть раскрыто... Сори, если чем обидел, не хотел...
    • 1 Декабря 2012 13:45
      soprun.vladislav
      artamonov, Я с тобой согласен!. Для новичков (p.s я им и являюсь ) нужно рассусоливать и разжевывать. Как не печально, но мы тупы xD
  • 30 Ноября 2012 20:07
    creo_leader
    Да ладно вам. Все хорошо, автору респект. С нетерпением ждем следующего урока, хорошо бы рассмотреть по части безопасности сайта.
  • 4 Декабря 2012 13:52
    ssindi
    А зачем надо разрабатывать собственную cms? Почему бы не воспользоваться готовыми решениями? К ним и расширений полно.
  • 5 Декабря 2012 17:07
    molegx
    --- у Вас тут ошибочка :) "доступным для пользоавтеля"... --- В некоторых случаях использование подобных инструментов является единственным доступным для пользоавтеля инструментом для работы с базами данных (ситуация зависит от правил, установленных на вашем хостинге).
  • 8 Декабря 2012 17:47
    vlulukyan
    извинитье у меня проблем с кодировкой utf-8, Я в базе измениле на utf-8 но нечего не получилась
  • 18 Декабря 2012 12:26
    KennyDead
    Для новичков в самый раз, что бы понять "что к чему"...))) Респект автору...))) Еще бы урок про мини социалку написали бы...)))
  • 25 Декабря 2012 05:26
    revoss
    Что нужно сделать? чтобы можно было добавлять русскоязычные стати! кодировку пытался изменить но всё напрасно в место русского "?" или просто пустая строка, а в базу добавляет набор символов "????????? ? ?..."
  • 7 Января 2013 23:04
    kopilov3
    Мне тоже не понятно как быть с русским языком
    • 7 Февраля 2013 13:44
      Delin
      Выберите кодировку utf8_general_ci
    • 25 Февраля 2013 16:54
      Flex27
      Чтоб правильно понималась кодировка utf-8 нужно просто добавить запись:
      mysql_query("SET NAMES 'utf8'");
      mysql_query("SET CHARACTER SET 'utf8'");
      • 7 Мая 2013 10:47
        Ameon
        Flex27 тут же PDO!!! Вот что я сделал чтобы была русская кодировка 1. Добавить способ кодировки на загружаемые страницы.)) <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> 2. В функции public function __construct убрать ограничения на символы. 3. Добавить 4 параметр к подключения PDO. array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
        • 3 Октября 2013 02:58
          CAHEK007
          array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
          куда это писать?
    • 7 Мая 2013 09:15
      Ameon
      Flex27 тут же PDO!!! Я посмотрел насчет языка. Во первых нужно добавить кодировку на загружаемые страницы.)) <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> А во вторых в функции public function __construct стоят ограничения на символы.
  • 17 Февраля 2013 21:40
    sew810i9
    и опять про вывод статей сделано! ну неужели нельзя сделать что то более менее стоящее? например сайт для работы с различным контентом (список файлов - фильмы, игры, музыка) а не эти статьи. Про социалку поддерживаю, вот я например даже не представляю как это реализовать, вот бы кто объяснил, а то Дуров и Цукерберг вряд ли станут делиться опытом!
  • 19 Февраля 2013 16:56
    simplerss
    что такое окно терминала и как им пользоваться ?!
    • 24 Февраля 2013 21:12
      fabrigas201
      терминал это командная строка, в линуксе называется терминал или shell насколько я знаю.
  • 30 Марта 2013 10:43
    rammtw
    Скачал исходник, но он не запускается, пишет ошибку Sorry, a problem occurred. Please try later.
    • 6 Мая 2013 11:55
      Ameon
      При такой проблеме проверь версию php и подключены ли нужные модули в php.ini.
  • 18 Декабря 2013 15:09
    classic1698
    А вам не кажется, что выкладывать с ошибками "дурной тон"? Например админка: Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /home/elated/v3.elated.com/articles/development/php/cms-in-an-afternoon-php-mysql/config.php:21) in /home/elated/public_html/res/File/articles/development/php/cms-in-an-afternoon-php-mysql/demo/admin.php on line 4 Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /home/elated/v3.elated.com/articles/development/php/cms-in-an-afternoon-php-mysql/config.php:21) in /home/elated/public_html/res/File/articles/development/php/cms-in-an-afternoon-php-mysql/demo/admin.php on line 4 Warning: Cannot modify header information - headers already sent by (output started at /home/elated/v3.elated.com/articles/development/php/cms-in-an-afternoon-php-mysql/config.php:21) in /home/elated/public_html/res/File/articles/development/php/cms-in-an-afternoon-php-mysql/demo/admin.php on line 47
    • 9 Января 2015 21:15
      nik.gavrilovich
      перекодируй файлы в UTF-8 без BOM. Это ошибка сессий.
  • 5 Мая 2014 00:33
    Shade1234321
    А как сделать чтобы список всех категорий выводился в отдельной колонке?
  • 25 Июня 2014 12:02
    EuRo123
    Помогу с проектами любой сложности! mail -san4ob148@gmail.com skype - san4o123123
  • 28 Августа 2014 10:03
    Weppoz
    Блин подскажите что это за ошибка такая? <b>Sorry, a problem occurred. Please try later.</b> в первые такое вижу, тупа надпись об ошибке. а какую нид версию пхп?
    • 13 Ноября 2014 02:06
      zullbatol
      Недключена база данных, проверь данные!
  • 4 Сентября 2015 18:07
    uasd
    как с помощью пхп ми админ добавиь таблицу? вы так пишите, как будто я это каждый день делаю и сам всё знаю. но в таком бы случае мне эти уроки были не нужны. разжуйте пожалуйста всё по полочкам для человека который вообще ни бе ни ме
  • 21 Октября 2015 11:30
    Zamana
    Спасибо, очень интересная статья, особенно для таких новичков, как я. Скажите, а будет продолжение уроков, ну там, как категории статей сделать и тому подобное. Спасибо.
  • 23 Января 2016 03:48
    cev77
    Admin, а почему выбрал MODX, расскажешь какие преимущества?
  • 3 Февраля 2016 21:14
    tambu
    Кто опытный, добавьте пожалуйста людские пояснения по поводу "правильного" способа обработки исключений для перехвата всех вызовов PDO...в данном примере
  • 30 Июля 2016 15:57
    MrCaT
    Спасибо большое!
^ Наверх ^