Раздел новостей
В предыдущем разделе мы изучили основные концепции фреймворка, написав класс, который ссылается на статические страницы. Мы оптимизировали URI, добавив пользовательские правила маршрутизации. Теперь пришло время добавить динамическое содержимое и начать использовать базу данных.
Создание базы данных для работы
Установка CodeIgniter предполагает, что у вас настроена соответствующая база данных, как описано в требованиях. В этом учебнике мы предоставляем SQL-код для базы данных MySQL, а также предполагаем, что у вас есть подходящий клиент для выполнения команд базы данных (mysql, MySQL Workbench или phpMyAdmin).
Вам необходимо создать базу данных, которая будет использоваться в этом учебнике, а затем настроить CodeIgniter для ее использования.
Используя ваш клиент базы данных, подключитесь к вашей базе данных и выполните приведенную ниже SQL-команду (MySQL). Также добавьте некоторые исходные записи. Пока мы просто покажем вам SQL-запросы, необходимые для создания таблицы, но вы должны понимать, что это можно сделать программно, когда вы более знакомы с CodeIgniter; вы можете узнать о Миграциях и Загрузчиках для создания более полезных настроек базы данных в будущем.
CREATE TABLE news (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(128) NOT NULL,
slug VARCHAR(128) NOT NULL,
body TEXT NOT NULL,
PRIMARY KEY (id),
KEY slug (slug)
);
Отметим, что «slug» в контексте веб-публикации — это короткий текст, удобный для пользователя и SEO, используемый в URL для идентификации и описания ресурса.
Исходные записи могут быть следующими:
INSERT INTO news VALUES (1,'Elvis sighted','elvis-sighted','Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app.'), (2,'Say it isn\'t so!','say-it-isnt-so','Scientists conclude that some programmers have a sense of humor.'), (3,'Caffeination, Yes!','caffeination-yes','World\'s largest coffee shop open onsite nested coffee shop for staff only.');
Подключение к базе данных
В файле локальной конфигурации, .env, который вы создали при установке CodeIgniter, настройки базы данных должны быть разкомментированы и правильно настроены для базы данных, которую вы хотите использовать. Убедитесь, что вы правильно настроили свою базу данных, как описано здесь.
database.default.hostname = localhost database.default.database = ci4tutorial database.default.username = root database.default.password = root database.default.DBDriver = MySQLi
Настройка вашей модели
Вместо того, чтобы писать операции с базой данных непосредственно в контроллере, запросы следует размещать в модели, чтобы их можно было легко повторно использовать позже. Модели — это место, где вы извлекаете, вставляете и обновляете информацию в вашей базе данных или других хранилищах данных. Они обеспечивают доступ к вашим данным. Вы можете узнать больше об этом здесь.
Откройте директорию app/Models/ и создайте новый файл под названием NewsModel.php и добавьте следующий код.
<?php
namespace App\Models;
use CodeIgniter\Model;
class NewsModel extends Model
{
protected $table = 'news';
}
Этот код похож на код контроллера, который использовался ранее. Он создает новую модель, расширяя CodeIgniter\Model и загружает библиотеку базы данных. Это сделает класс базы данных доступным через объект $this->db.
Теперь, когда база данных и модель настроены, вам понадобится метод для получения всех наших записей о постах из нашей базы данных. Для этого используется слой абстракции базы данных, включенный в CodeIgniter — Query Builder — Это позволяет писать «запросы» один раз и заставляет их работать на всех поддерживаемых системах баз данных. Класс модели также позволяет легко работать с Query Builder и предоставляет некоторые дополнительные инструменты для упрощения работы с данными. Добавьте следующий код в вашу модель.
public function getNews($slug = false)
{
if ($slug === false) {
return $this->findAll();
}
return $this->where(['slug' => $slug])->first();
}
С помощью этого кода вы можете выполнить два разных запроса. Вы можете получить все записи новостей или получить новость по ее slug. Вы могли заметить, что переменная $slug не была экранирована перед выполнением запроса; Query Builder делает это за вас.
Два метода, используемых здесь, findAll() и first(), предоставляются классом CodeIgniter\Model. Они уже знают, какую таблицу использовать на основе свойства $table, которое мы установили в классе NewsModel ранее. Это вспомогательные методы, которые используют Query Builder для выполнения команд над текущей таблицей и возвращают массив результатов в формате по вашему выбору. В этом примере findAll() возвращает массив массивов.
Отображение новостей
Теперь, когда запросы написаны, модель должна быть связана с представлениями, которые будут отображать пользователю элементы новостей. Это можно сделать в нашем контроллере Pages, созданном ранее, но для ясности определяется новый контроллер News. Создайте новый контроллер в app/Controllers/News.php.
<?php
namespace App\Controllers;
use App\Models\NewsModel;
use CodeIgniter\Controller;
class News extends Controller
{
public function index()
{
$model = model(NewsModel::class);
$data['news'] = $model->getNews();
}
public function view($slug = null)
{
$model = model(NewsModel::class);
$data['news'] = $model->getNews($slug);
}
}
Рассматривая код, вы можете увидеть некоторое сходство с файлами, которые мы создавали ранее. Во-первых, он расширяет базовый класс CodeIgniter, Controller, который предоставляет несколько вспомогательных методов и гарантирует, что у вас есть доступ к текущим объектам Request и Response, а также к классу Logger, для сохранения информации на диск.
Далее, есть два метода: один для просмотра всех элементов новостей и один для конкретного элемента новостей.
Далее, используется функция model() для создания экземпляра NewsModel. Это вспомогательная функция. Вы можете узнать больше об этом здесь. Вы также можете написать $model = new NewsModel();, если не используете её.
Вы можете видеть, что переменная $slug передаётся в метод модели во втором методе. Модель использует этот slug для идентификации возвращаемого элемента новости.
Теперь данные извлекаются контроллером через нашу модель, но ничего ещё не отображается. Следующим шагом является передача этих данных в представления. Измените метод index() так, чтобы он выглядел так:
public function index()
{
$model = model(NewsModel::class);
$data = [
'news' => $model->getNews(),
'title' => 'News archive',
];
echo view('templates/header', $data);
echo view('news/overview', $data);
echo view('templates/footer', $data);
}
Код выше получает все записи новостей из модели и присваивает их переменной. Значение для заголовка также присваивается элементу $data['title'] и все данные передаются в представления. Теперь вам нужно создать представление для отображения элементов новостей. Создайте app/Views/news/overview.php и добавьте следующий фрагмент кода.
<h2><?= esc($title) ?></h2>
<?php if (! empty($news) && is_array($news)): ?>
<?php foreach ($news as $news_item): ?>
<h3><?= esc($news_item['title']) ?></h3>
<div class="main">
<?= esc($news_item['body']) ?>
</div>
<p><a href="/news/<?= esc($news_item['slug'], 'url') ?>">View article</a></p>
<?php endforeach; ?>
<?php else: ?>
<h3>No News</h3>
<p>Unable to find any news for you.</p>
<?php endif ?>
Примечание
Мы снова используем esc() для предотвращения атак XSS. Но на этот раз мы также передали «url» в качестве второго параметра. Это потому, что типы атак различаются в зависимости от контекста, в котором используется вывод. Вы можете узнать больше об этом здесь.
Здесь каждый элемент новости циклируется и отображается пользователю. Вы можете видеть, что мы написали нашу шаблонную разметку на PHP, смешанную с HTML. Если вы предпочитаете использовать язык шаблонов, вы можете использовать Обработчик представлений CodeIgniter или сторонний обработчик.
Страница обзора новостей теперь завершена, но страница для отображения отдельных элементов новостей все еще отсутствует. Модель, созданная ранее, разработана таким образом, чтобы её легко использовать для этой функциональности. Вам нужно только добавить немного кода в контроллер и создать новое представление. Вернитесь в контроллер News и обновите метод view() следующим образом:
public function view($slug = null)
{
$model = model(NewsModel::class);
$data['news'] = $model->getNews($slug);
if (empty($data['news'])) {
throw new \CodeIgniter\Exceptions\PageNotFoundException('Cannot find the news item: ' . $slug);
}
$data['title'] = $data['news']['title'];
echo view('templates/header', $data);
echo view('news/view', $data);
echo view('templates/footer', $data);
}
Вместо вызова метода getNews() без параметра передается переменная $slug, поэтому он вернет конкретный элемент новости. Единственное, что осталось сделать, это создать соответствующее представление в app/Views/news/view.php. Поместите следующий код в этот файл.
<h2><?= esc($news['title']) ?></h2> <p><?= esc($news['body']) ?></p>
Маршрутизация
Из-за правила маршрутизации с подстановкой, созданного ранее, вам нужен дополнительный маршрут для просмотра только что созданного контроллера. Измените свой файл маршрутизации (app/Config/Routes.php) следующим образом. Это гарантирует, что запросы попадают в контроллер News, а не напрямую в контроллер Pages. Первая строка маршрутизирует URI со slug к методу view() в контроллере News.
$routes->get('news/(:segment)', 'News::view/$1');
$routes->get('news', 'News::index');
$routes->get('(:any)', 'Pages::view/$1');
Перейдите в браузере на вашу страницу «новости», например, localhost:8080/news, вы должны увидеть список элементов новостей, каждый из которых имеет ссылку для отображения только одной статьи.
© 2014–2020 British Columbia Institute of Technology
Licensed under the MIT License.
https://codeigniter.com/user_guide/tutorial/news_section.html