Переход к официальным ресурсам:      Codeigniter4 / Документация / Github / Форум / CodeIgniter3
Привет! В настоящий момент я временно прекратил перевод документации по причине того, что она она содержит целый ряд неточностей, а также еще дорабатывается со стороны разработчиков. Если ты заинтересован в изучении фреймворка CodeIgniter 4, то приглашаю тебя на свой канал на YouTube (Перейти на канал), где я более подробно выкладываю занятия по данному фреймворку.


Работа с базой данных

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

Создаем рабочую базу данных

Данный урок предполагает, что ты имеешь в своем распоряжении любой клиент по работе с СУБД (например PhpMyAdmin или Adminer), умеешь им пользоваться, а также ты уже знаешь, в каких конфигурационных файлах фреймворка указываются параметры для подключения к БД и работе с ней. Итак, используя свой клиент, создай новую базу данных, назвав её ci4tutorial или как-то иначе, по своему желанию. Выбери её и после этого, в клиенте, выполни следующий SQL-запрос, который создаст новую таблицу с названием news:

    CREATE TABLE news (
        id int(11) NOT NULL AUTO_INCREMENT,
        title varchar(128) NOT NULL,
        slug varchar(128) NOT NULL,
        body text NOT NULL,
        PRIMARY KEY (id),
        KEY slug (slug)
    );

Пока просто выполняй запросы, с деталями разберемся позже. После того, как ты создал таблицу, давай наполним её несколькими записями. Выполни в клиенте следующий SQL-запрос:

    INSERT INTO news VALUES
    (1,'Скоро релиз Codeigniter','skoro-release','Рады сообщить о том, что скоро состоится релиз Codeigniter 4!'),
    (2,'Добавлен новый раздел документации','dobavlen-noviy-razdel','Сообщаем, что сегодня был добавлен новый раздел на нашем сайте!'),
    (3,'Прошу оставлять комментарии','proshu-ostavlyat-kommentarii','Пожалуйста, оставляйте свои комментарии на сайте. Мне это очень важно!');

 

Параметры фреймворка для соединения с базой данных

После начальной подготовки БД, укажи в конфигурационных файлах фреймворка необходимые параметры, чтобы начать взаимодействие с БД. В моем случае я использую файл .env и настройки выглядят так:

    database.default.hostname = localhost
    database.default.database = ci4tutorial
    database.default.username = root
    database.default.password = root
    database.default.DBDriver = MySQLi

 

Твои первые Модели

Напоминаю, что Модели - это обычные php-классы, предназначенные исключительно для взаимодействия с БД. В них ты будешь описывать все свои запросы к БД на создание, получение, изменение и удаление любой информации. Их еще называют CRUD-операции, от слов Create, Read, Update, Delete.

Перейди в директорию app/Models, создай там новый файл NewsModel.php и добавь в него следующий код:

    <?php namespace App\Models;
    
    use CodeIgniter\Model;
    
    class NewsModel extends Model
    {
        protected $table = 'news';
        
        public function getNews($slug = false)
        {
            if ($slug === false)
            {
                return $this->findAll(); // Равносильно запросу SELECT * FROM news;
            }

            return $this->asArray()
                         ->where(['slug' => $slug])
                         ->first();
        
            // Равносильно запросу SELECT * FROM news WHERE slug = 'адрес из запроса';
        }
    }

Наверное ты уже заметил, что этот код очень похож на тот, что мы прописывали в Контроллере. Он создает новую Модель и автоматически подключает библиотеку по работе с БД. В строке кода #1 ты указал пространство имён, к которому относится твой новый класс. В строке #3 ты подключил базовый класс (из ядра фреймворка), отвечающий за работу Моделей. Обращаю внимание, что эти 2 строки будут присутствовать практически в каждом файле, реализующем ту или иную Модель. Далее, в строке #5 ты создал класс NewsModel, который расширяет базовый класс ядра. Все Модели, которые ты создаешь самостоятельно, всегда должны расширять базовую Модель. Имена классов, которые ты создаешь, должны в точности соответствовать имени файла, который содержит этот класс. И наоборот, имя файла Модели должно быть в точности таким же, как имя класса, которое ты придумал. В нашем случае имя класса NewsModel, соответственно имя файла также должно быть NewsModel.php.

Далее, в строке #7 ты указал таблицу в базе данных, с которой планируешь работать. Зачем? Узнаешь чуть ниже. После этого, в строках с #9 по #21 ты написал новый метод с названием getNews, который имеет один аргумент с именем $slug, значение которого по умолчанию false. Что такое slug? Как ты уже наверное догадался - это "красивый" URL-адрес, по которому будет доступна конкретная новость из БД. Их еще называют ЧПУ-адреса. В этом методе, в строках с #11 по #14, ты создал проверку, которая будет определять, пришел ли из строки запроса браузера параметр $slug или нет? Если нет, тогда в строке #13 ты обращаешься через объект $this-> к методу findAll(), который и запросит у БД выбрать все имеющиеся записи из таблицы news. Обрати внимание, что метод findAll() мы нигде не прописывали, но можем использовать. Для этого мы используем слой абстракции БД, который входит в состав Codeigniter 4 и называется Query Builder (Конструктор запросов). Он хорош тем, что имеет единый и универсальный интерфейс и позволяет создавать запросы, которые будут работать с любым типом баз данных. Таким образом получается, что это встроенный метод фреймворка, реализованный в классе Конструктора запросов. Более подробно о всех встроенных методах ты можешь узнать из раздела документации по Query Builder.

Двигаемся дальше. Если в запросе все-таки пришел параметр $slug, тогда обращаемся к БД через объект $this->, говорим, что хотим получить данные в виде ассоциативного массива asArray() и выбираем запись из таблицы, у которой поле slug равно запрашиваемой странице. В конце мы используем метод first(), который вернет данные в виде строки (а не объекта) или NULL, если такая запись не найдена. Обрати внимание, что мы напрямую в запросе использовали переменную $slug никак не экранировав её в целях безопасности. Тебе этого делать и не нужно! Все средства защиты уже встроены в Конструктор запросов "из коробки". Помимо этого, если ты был внимателен, наверняка ты обратил внимание, что мы нигде не указывали из какой именно таблицы выбирать данные! Ведь таблиц может быть множество, верно? Так вот, класс Модели знал заранее с какой таблицей мы работаем, на основе свойства protected $table = 'news';, которое ты добавил ранее. Удобно? Не то слово!

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

Отображаем полученные данные

Ну что, с Моделью разобрались. Теперь, когда запросы написаны, пришло время привязать эту Модель к нашему Контроллеру, чтобы он мог получить данные ОТ Модели и передать их В Представления. Конечно, мы могли бы переписать наш имеющийся Контроллер Pages, но мы создадим новый контроллер. Перейди в директорию app/Controllers и создай там новый файл с именем News.php. После этого добавь туда следующий код:

    <?php namespace App\Controllers;
    
    use CodeIgniter\Controller;
    use App\Models\NewsModel;
    

    class News extends Controller
    {
        public function index()
        {
            $model = new NewsModel();

            $data = [
                'news'  => $model->getNews(),
                'title' => 'Архив новостей',
        ];

        echo view('templates/header');
        echo view('news/news-list', $data);
        echo view('templates/footer');
        }

        public function showNews($slug = null)
        {
            $model = new NewsModel();

            $data['news'] = $model->getNews($slug);

            if (empty($data['news']))
            {
                throw new \CodeIgniter\Exceptions\PageNotFoundException('Не могу найти новость по URL-адресу: '. $slug);
            }

            $data['title'] = $data['news']['title'];

            echo view('templates/header');
            echo view('news/news-item', $data);
            echo view('templates/footer');
        }
    }

Давай взглянем на этот код более детально и посмотрим, что он делает. Строки #1 и #3 тебе уже знакомы по предыдущему уроку. В строке #4 мы как раз таки и подключаем наш класс Модели, который мы только что реализовали. Далее, мы объявляем новый класс Контроллера, который расширяет базовый Контроллер. Тебе тоже уже это знакомо. После этого, мы создаем метод index(), в котором объявляем переменную $model, которая будет являться экземпляром (объектом) класса NewsModel. Далее, в строке #13 мы объявляем ассоциативный массив, в который будет записана вся полученная информация из БД об имеющихся новостях. Здесь ты тоже должен вспомнить предыдущий урок, в котором мы говорили о том, что в Представления информация может быть передана только через массив, помнишь? Вот мы и передаем в ключе массива news массив новостей, а в ключе title будет просто заголовок страницы. В строках #18, #19, #20 мы последовательно выводим Представления в окно браузера, передавая в них массив с информацией. Таким образом наш метод index() может выводить только полный список новостей.

С методом showNews($slug = null) ситуация интереснее. В строке #27 мы пытаемся получить новость по конкретному URL-адресу из строки браузера. Если такая новость не найдена, тогда выводим сообщение с ошибкой. За это отвечают строки с #29 по #32. Если же информация по конкретной новости получена, тогда снова последовательно выводим Представления в окно браузера, заранее передавая в них всю информацию из массива $data в качестве второго параметра.

Не пропусти важный момент! Посмотри внимательно на строки #19 и #37. В них мы указываем два совершенно разных Представления! Не ошибись!

Готовим Представления

Перейди в директорию app/Views/ и создай там новую директорию с названием news, в которую добавь новый файл с названием news-list.php. Добавь в этот файл следующий код:

    <h2> <?= $title ?> </h2>

    <?php if (! empty($news) && is_array($news)) : ?>

        <?php foreach ($news as $news_item): ?>

                <h3><?= $news_item['title'] ?></h3>

                <div class="main">
                        <?= $news_item['body'] ?>
                </div>
                <p><a href="<?= '/news/'.$news_item['slug'].'.html' ?>">Подробнее...</a></p>

        <?php endforeach; ?>

     <?php else : ?>

        <h3>Новостей нет</h3>

        <p>К сожалению, пока новостей не добавлено!.</p>

    <?php endif ?>

Тут всё просто. Выводим заголовок страницы (в коде мы его указали как "Архив новостей"). Далее запускаем проверку и проверяем, является ли наша переменная $news массивом и не пустой ли он. Если нет, тогда мы с помощью PHP-конструкции foreach пробегаемся по всему массиву и циклически выводим все новости. Если переменная $news пустая (из БД ничего не выбрано), тогда выводим текст о том, что новостей не найдено. Самое интересное происходит в строке #12. Здесь как раз и формируется наша "красивая" ссылка с параметром $slug.

Мы подготовили Представление для вывода всего списка новостей. Осталось добавить еще одно Представление для вывода информации по конкретной новости. В той же директории app/Views/news/ добавь еще один файл с именем news-item.php и добавь туда такой код:

    <?php
    echo '<h2>'.$news['title'].'</h2>';
    echo $news['body'].'<br /><br />';
    echo 'Вернуться  <a href="/news/">к списку новостей</a><br /><br />';

Всё! Осталось настроить маршрутизацию!

Формируем маршрутизацию

Открывай уже знакомый тебе файл app/Config/Routes.php. Ищи строку:

    $routes->get('(:any)', 'Pages::showme/$1');

и перед ней добавь два новых маршрута для наших новостей:

    $routes->get('news/(:segment).html', 'News::shownews/$1');
    $routes->get('news', 'News::index');

Перейди в своем браузере по адресу http://твой-домен/news и, если ты все сделал правильно, тогда ты должен будешь увидеть список всех трёх новостей из БД, которые мы добавляли в начале урока. К тому же, каждая новость имеет собственную ссылку, нажав на которую, ты сможешь увидеть новость отдельно и оттуда снова вернуться к списку новостей. Обрати внимание на "красивые" URL-адреса, которые появляются, когды ты просматриваешь какую-либо новость отдельно.

На этом данный урок завершен. Согласен, информации много, но не торопись. Постарайся вдумчиво разобраться в том, что и как мы здесь реализовали. В качестве домашнего задания, попробуй изменить имя класса Модели на своё, и переименуй один из файлов Представлений на свой вариант. Всё это потребует от тебя внесения изменений в код Контроллеров и не только. Пусть это будет небольшим тестом для тебя :)

В следующем уроке ты научишся добавлять новости в базу данных через форму в окне браузера!


Комментарии к разделу:

Пока ещё никто не оставил своего комментария. Оставить свой!

Добавить комментарий к статье:


Ваше имя:
Ваша почта:

  Закрыть