Создаем сайт с помощью PHP, MySql и jQuery Mobile. Часть 1
В этом уроке мы напишем сайт, используя PHP, MySql и шаблон проектирования Model-View-Controller (MVC). С помощью фреймворка jQuery Mobile мы сделаем сайт мобильным, адаптирующимся под разные разрешения экранов.
В этой части урока мы разберем структуру базы данных и MVC. Во второй части мы напишем представления и интегрируем jQuery Mobile.
Файловая структура
Так как мы будем использовать шаблон MVC, для удобства хранения файлов, мы создадим папки: models, views и controllers, в которых будем хранить модели — классы для создания необходимых объектов, представления — шаблоны для отображения объектов и контроллеры — классы для управления объектами.
Структура базы данных
Для хранения информации о продуктах мы будем использовать две таблицы: jqm_categories, и jqm_products. Таблица jqm_categories будет иметь поля id, name и contains — в этом поле будет хранится количество продуктов данной категории. Таблица jqm_products будет иметь поля price, name, manufacturer и category. Код для создания и наполнения таблиц доступен в исходниках.
Модели
Наши модели будут связываться с базой с помощью метода find() и возвращать массив объектов. Нам понадобятся две модели products и categories. Для начала необходимо создать подключение к нашей базе:
/* Этот файл создаст новое MySQL соединение с помощью класса PDO. параметры для соединения хранятся в includes/config.php. */ try { $db = new PDO( "mysql:host=$db_host;dbname=$db_name;charset=UTF-8", $db_user, $db_pass ); $db->query("SET NAMES 'utf8'"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { error_log($e->getMessage()); die("A database error was encountered"); }
Модель category:
class Category{ /* Статический метод find() выбирает категории из базы и возвращает их в виде массива объектов Category */ public static function find($arr = array()){ global $db; if(empty($arr)){ $st = $db->prepare("SELECT * FROM jqm_categories"); } else if($arr['id']){ $st = $db->prepare("SELECT * FROM jqm_categories WHERE id=:id"); } else{ throw new Exception("Unsupported property!"); } // запрос к базе $st->execute($arr); return $st->fetchAll(PDO::FETCH_CLASS, "Category"); } }
При возврате объекта мы используем метод fetchAll передавая ему константу PDO::FETCH_CLASS. Этот метод пробежит по результату запроса к базе и создаст из него массив обектов класса Category. Колонки каждой строки результата будут добавлены к объектам как public поля.
Product model:
class Product{ public static function find($arr){ global $db; if($arr['id']){ $st = $db->prepare("SELECT * FROM jqm_products WHERE id=:id"); } else if($arr['category']){ $st = $db->prepare("SELECT * FROM jqm_products WHERE category = :category"); } else{ throw new Exception("Unsupported property!"); } $st->execute($arr); return $st->fetchAll(PDO::FETCH_CLASS, "Product"); } }
Контроллеры
Контроллеры будут использовать метод find() моделей для поиска и формирования представления. Мы создадим два контроллера: для главной страницы и для страницы категории. Контроллер главной страницы:
/* Этот контроллер отображает главную страницу */ class HomeController{ public function handleRequest(){ // Select all the categories: $content = Category::find(); render('home',array( 'title' => 'Welcome to our computer store', 'content' => $content )); } }
Каждый контроллер содержит метод handleRequest() он будет вызываться из index.php. В случае с главной страницей, мы будем просто отображать все доступные категории товаров, используя вспомогательную функцию render.
Контроллер категорий:
/* Этот контроллер отображает страницу категории */ class CategoryController{ public function handleRequest(){ $cat = Category::find(array('id'=>$_GET['category'])); if(empty($cat)){ throw new Exception("There is no such category!"); } $categories = Category::find(); $products = Product::find(array('category'=>$_GET['category'])); render('category',array( 'title' => 'Browsing '.$cat[0]->name, 'categories' => $categories, 'products' => $products )); } }
Пришло время собрать все вместе, рассмотрим файл index.php.
require_once "includes/main.php"; try { if($_GET['category']){ $c = new CategoryController(); } else if(empty($_GET)){ $c = new HomeController(); } else throw new Exception('Wrong page!'); $c->handleRequest(); } catch(Exception $e) { // выводим сообщение об ошибке: render('error',array('message'=>$e->getMessage())); }
В зависимости от запроса, index.php создаст контроллер, который отобразит необходимую страницу. Если в процессе обработки запроса произойдет ошибка, будет возбуждено исключение и отображена соответствующая страница.
И еще один файл, в котором будут хранится все подключаемые файлы. Мы подключили этот файл в index.php.
require_once "includes/config.php"; require_once "includes/connect.php"; require_once "includes/helpers.php"; require_once "includes/models/product.model.php"; require_once "includes/models/category.model.php"; require_once "includes/controllers/home.controller.php"; require_once "includes/controllers/category.controller.php"; // задаем параметры кеширования страниц header('Cache-Control: max-age=3600, public'); header('Pragma: cache'); header("Last-Modified: ".gmdate("D, d M Y H:i:s",time())." GMT"); header("Expires: ".gmdate("D, d M Y H:i:s",time()+3600)." GMT");
На этом все 🙂 Вторая часть урока.
Нет комментариев