День пятый. 6-ое сентября.

День пятый. 6-ое сентября.

junsenioradmin

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

Если ты арендовал VDS с Ubuntu 16.04 и выполнил тот ман, который я писал во вторник, тогда этот подраздел для тебя. Если же ты арендовал сервер с Ubuntu 18.04 или ставил Symfony локально - пропускай и начинай читать с фразы “Я немного подумал и решил...”.

Есть небольшая проблема у тех, кто арендует VDS, где стоит Ubuntu 16.04, а не 18.04. Проблема с версией PHP. На 16-ой убунте она из репозиториев ставится 7-ая, а нам для Symfony 4.1 нужна как минимум 7.1. Т.е. в прошлый раз я на своей VDS поставил Symfony 3.4, а не 4.1. Но, благо, это решается так, как будто цель у нас не обновить php, а обоссать 2 пальца - легко.

Удали папку testproject (rm -rf /var/www/testproject), затем выполни последовательно следующие команды:

apt-get remove php php-cli php-curl php-xml && apt-get autoremove

apt-get update && apt-get upgrade
apt-get install python-software-properties software-properties-common
add-apt-repository ppa:ondrej/php
apt-get update
apt-get install php7.2 php7.2-cli php7.2-curl php7.2-xml php7.2-zip

a2dismod php7.0
a2enmod php7.2
service apache2 restart

И, после этого, повтори действия, начиная с третьего шага в главе “Настройка удалённого сервера и установка на него Symfony” из мана, который был во вторник. Кажется, что много всего делать? Не-а, копируй - вставляй, 5 минут от силы. После чего у тебя будет вкусная и свежая symfony 4.1. В том мане, что был во вторник - я уже всё исправил и сказал новоприбывшим, что надо сразу обновлять убунту до 18-ой. Так что этот раздел актуален только для старичков канала.

Я немного подумал и решил, что делать мы будем блог. В блоге у нас будет система пользователей (админы и обычные юзеры), будет лента постов админа, будет возможность комментировать и ставить лайки на записи. У админа будет админка, где он сможет добавлять новые посты, сможет их редактировать и удалять. Помимо этого сможет полностью управлять всеми данными на сайте. Он сможет банить пользователей, которые оставили, например, спам в комментариях. Таким образом мы познакомимся с огромным количеством тем и технологий, очень глубоко копнём в backend, неплохо копнём во фронт и перелопатим большУю часть документации. Весь проект будет в git, и, помимо этого, тебя я тоже буду приучать к git'у. Мы попробуем черпнуть максимально много технологий и поработать с большим количеством инструментов, помимо Symfony. Но перед этим великим проектом придётся почитать ещё немного теории. Потому что без теории никуда, братан.

Во вторник мы закончили с настройкой, в четверг я познакомил тебя с тем, что такое MVC (в общем виде), а так же со структурой Symfony-приложения.

Сегодня мы разберёмся, что такое сущности и поймём, как данных хранятся в Symfony-приложении (и научимся работать с базой данных).

Это очень важная и очень полезная тема. Вот правда, чувак, очень. Поэтому ты постарайся её понять, а я постараюсь её хорошо объяснить.

Что такое сущности и причём тут буква “М”.

В предыдущей статье я рассказывал тебе (и даже оторвал от сердца ссылочки с детальным описанием) о том, что такое MVC или Model-View-Controller. Так вот, сущности - это то, что напрямую связано с моделью (Model или буковка M в аббревиатуре MVC).

Как ты уже знаешь, модель - это слой, который отвечает за данные. Слово “данные” ассоциируется с базой данных. Во вторник мы настраивали систему управления базами данных (СУБД) MySQL - это такая система, которая позволяет хранить, изменять, создавать и удалять самые различные данные. Помимо прочего, эта система имеет свой язык - язык SQL, с помощью которого ты можешь данными управлять.

Как он (язык) работает - я пока не буду объяснять, сейчас тебе достаточно знать, что все данные с помощью языка SQL и с помощью MySQL записываются, изменяются и удаляются в эту или из этой базы данных. Таким образом у нас есть 3 основных объекта - СУБД, сама БД и язык запросов SQL.

Чтобы примерно представить, что такое база данных, я приведу аналогию с excel'евскими таблицами. Да-да, обычный Microsoft Excel. Что есть в excel'е? Таблицы. Что ещё? Есть сам документ, в котором на разных страницах у тебя могут быть разные таблицы. Представь, что ты уже начал разрабатывать блог. В блоге у тебя есть люди, которые могут писать комментарии. Есть и сами комментарии.

Так вот люди и комментарии - это объекты, которые тебе нужно сохранять в excel. Для людей ты выделяешь свою таблицу, а для комментариев - свою. У людей ты, допустим, сохраняешь логин почту и аватар. У комментариев - текст и автора.

Таблица людей будет выглядеть как-то так:


Так вот в базе данных (сейчас я говорю про те базы данных, которые относятся к MySQL), данных хранятся тоже в таблицах и их можно представить в голове так, как будто это таблица excel.

В одной базе данных могут быть несколько таблиц (пользователи, комментарии, ...), так же как и в одном excel-документе.

Если бы мы программировали на чистом php, без Symfony, то мы бы подключались к базе данных (не через файл .env, а через код), а затем с помощью языка SQL создавали бы запросы. Эти запросы создавали бы таблицы, вносили бы в таблицы записи (запись - это одна строка в таблице), изменяли бы их и удаляли. Связь твоих запросов на SQL и БД производилась бы посредством СУБД MySQL.

Если тебе интересно, как это сделать на чистом php, можешь посмотреть, например, данный ман - https://metanit.com/web/php/7.3.php.

Но теперь представь себе ситуацию, что у тебя 20 таблиц (пользователи, комментарии, заблокированные пользователи, администраторы, ...). Для каждой таблицы тебе нужен запрос на добавление, удаление, поиск, изменение, ... Уже представляешь масштабы, сколько бы функций на php, внутри которых были бы запросы на SQL, тебе пришлось бы создать? Очень и очень много. Но на наше счастье мы используем framework Symfony, где к чистому SQL тебе (за редким исключением) притрагиваться не приходится.

В Symfony ввели такой термин, как сущность. Сущность - это обычный ООП-класс, который является обёрткой над таблицей. Переменные в классе - это столбцы в таблице (логин, айди, email, etc). Функции в классе (обычно гетеры и сетеры) - позволяют устанавливать и возвращать тебе переменные. Иначе говоря, сущность с пользователями в очень абстрактном виде выглядела бы так:

class User 
{
 $userID;
 $login;

 вернутьUserID(){
  return $this->userId;
 }

 установитьUserID($newUserID)
 {
  $this→userID = $newUserID;
 }

 вернутьLogin(){
  return $this->login;
 }

 установитьLogin($newLogin)
 {
  $this→login = $newLogin;
 }
}


Вместо создания таблицы, кучи запросов и неприятных действий с SQL тебе достаточно написать класс, создать в нём переменные и функции, который будут устанавливать и возвращать переменные. Это очень круто, потому что это очень облегчает жизнь. Так вот теперь раз и навсегда решим, что такие классы мы называем сущностями.

ORM

Чтобы теоретическая картинка перестала быть квадратом Малевича и раскрасилась красками, я не могу не сказать тебе о технологии, которая позволяет так сильно упростить нам жизнь. Тот инструмент, который переводит классы в таблицы, которые понимает MySQL. Этот инструмент называется ORM.

ORM - это технология, которая умеет связывать реляционную (новое страшное слово? Не пугайся, в первом приближении ты можешь понимать под термином “реляционная БД” такую БД, которая работает с таблицами, как в excel, то есть всё то, что я объяснил выше) базу данных с классами. Чтобы лучше понять, что такое ORM - прочти определение на wiki - https://ru.wikipedia.org/wiki/ORM.

ORM - это просто технология. Реализует эту технологию для языка PHP такая библиотека, как Doctrine. Её мы скоро установим, можешь не беспокоиться.

Теперь, зная такой фундамент модели, как сущности, ты можешь создать класс (тем самым получится таблица), а затем в любом месте кода создать объект этого класса, тем самым получится запись в таблице (строка в excel). Круто, да?

Где хранятся сущности? В PhpStorm, на удалённом сервере (или же, если ты ставил Symfony локально, то на локальной машине во вкладке Project) открой папку src, где можно будет увидеть папку Entity:

Именно в этой дирректории хранятся сущности

Теперь открываем консоль (я буду показывать на удалённом VDS), а затем открываем прекрасный мануал из официальной документации - https://symfony.com/doc/current/doctrine.html.

Сначала, как и показано в мануале, установим ORM Doctrine, посредством двух команд. Я не буду их дублировать, ибо это излишне. У меня, к слову, эти пакеты уже были (если ты выполнял урок вторника - то и у тебя будут. Насколько я понимаю, в полной версии Symfony они ставятся по умолчанию. Есть ещё урезанная (о ней поговорим попозже), вот там-то их, скорее всего, надо ставить ручками).

В разделе “Configuring the Database” пропускаем изменение параметров в .env и команду doctrine:schema:create, так как параметры в файл мы уже занесли, а создавать схему (а в частности базу данных) нам не нужно - мы это сделали из mysql-скрипта во вторник.

Переходим к самому интересному разделу - "Create Entity Class".

Выполняй команды из листинга, что приведён в мануале. Для примера тут создаётся класс Product, а для создания используется консольная команда make:entity. Эта команда максимально юзерфрендли, так как она просто задаёт тебе вопросы, а тебе нужно просто на них ответить. Как только ты выполнишь команды, обнови данные на сервере и можно будет увидеть, что новая сущность успешно создана. А чтобы вопросы, которые задаёт команда, стали тебе понятны, привожу перевод этих вопросов:

 php bin/console make:entity

Введите имя класса для создания или обновления сущности:
> Product

Введите имя нового свойства:
> name

Введите тип данных для свойства[по умолчанию string]:
> string

Введите максимальную длину строки [по умолчанию 255]:
> 255

Может ли значение в этом свойстве быть не заданным (может ли свойство быть пустым?) (yes/no) [no]:
> no

 Введите имя нового свойства:
> price

Введите тип данных для свойства[по умолчанию string]:
> integer

Может ли значение в этом свойстве быть не заданным? (yes/no) [no]:
> no

 Введите имя нового свойства (нажимаем Enter для завершения):

Тааак. Теперь обновим содержимое папки Entity на сервере и увидим:

Появился файл Product.php

А теперь откроем Product.php:

Только что мы создали класс - сущность, каждый объект которого будет записью в таблице (спасибо ORM Doctrine). Все таблицы будут составлять базу данных, управляет которой будет производиться при помощи СУБД MySQL.

Теперь немного скажу о комментариях, которые стоят над полями (переменными) и над классом. Эти комментарии называются ORM-аннотации, и они тоже упрощают жизнь. Давай по порядку.

Аннотация над class Product - @ORM\Entity(repositoryClass=”...”) задаёт класс, который называется репозиторий. Если ты создаёшь сущности посредством команды make:entity, то репозиторий создаётся автоматически. Его можно найти в папке src\Repository. Если коротко, то это класс, куда можно прописывать кастомные запросы (вот тут-то мы и столкнёмся с SQL, но это будет чуть позже). Зачем они нужны? Ну, например, ты хочешь искать информацию в таблице по какому-то определённому фильтру. Этот запрос как раз и прописывается в репозиторий, а затем мы сможем его использовать.

Теперь посмотрим на аннотацию над переменной $id - ORM\Id() - маркер, который говорит что данное поле - идентификатор записей в таблице.

ORM\GeneratedValue() - говорит о том, что этот столбец генерируется автоматически (id первой записи - 1, второй - 2, и так далее).

ORM\Column(type=”integer”) - указание типа для значений, которые будут храниться в этом столбце.

Все аннотации, а так же полнейшая документация по ORM Doctrine располагается тут - https://www.doctrine-project.org/. Сохрани сайт в закладки, мы часто будем сюда обращаться.

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

Теперь посмотри на иллюстрацию того, как интерпретируются данные с помощью Doctrine:

Поля со значениями из объекта класса интерпретируются в табличные записи - о чём я и говорил

На этом резюмирую: ты разобрался с тем, что находится на уровне модели. Понял, как создавать сущности и как настраивать поля в этих сущностях. Ты примерно понимаешь, как хранятся данные и что такое реляционная база данных.

Что дальше?

Во вторник мы рассмотрим букву “C” из MVC, и, смешав “C” и “M”, сполна применим свои знания из сегодняшней статьи. Мы поработает с репозиториями, узнаем, что такое связи между сущностями, узнаем что такое бандлы и даже создадим сущность пользователя - “User”. Помимо User мы продумаем и создадим все сущности, которые будут у нас в блоге. 


Report Page