HTML Diff
1 added 1 removed
Original 2026-01-01
Modified 2026-02-21
1 <p>PHP - крутой и надёжный язык для бэкендеров. Его любят компании и ценят разработчики. Но вся его мощь раскрывается благодаря фреймворкам.</p>
1 <p>PHP - крутой и надёжный язык для бэкендеров. Его любят компании и ценят разработчики. Но вся его мощь раскрывается благодаря фреймворкам.</p>
2 <p>В этой статье мы узнаем, что такое Laravel, чем он удобен и почему многие программисты предпочитают его другим PHP-фреймворкам. А чтобы закрепить знания, напишем игру "Камень, ножницы, бумага".</p>
2 <p>В этой статье мы узнаем, что такое Laravel, чем он удобен и почему многие программисты предпочитают его другим PHP-фреймворкам. А чтобы закрепить знания, напишем игру "Камень, ножницы, бумага".</p>
3 <p>Всё, что нужно знать про Laravel:</p>
3 <p>Всё, что нужно знать про Laravel:</p>
4 <ul><li><a>что это такое</a>;</li>
4 <ul><li><a>что это такое</a>;</li>
5 <li><a>чем этот PHP-фреймворк лучше других</a>;</li>
5 <li><a>чем этот PHP-фреймворк лучше других</a>;</li>
6 <li><a>что можно делать на Laravel</a>;</li>
6 <li><a>что можно делать на Laravel</a>;</li>
7 <li><a>с чего начать работу</a>;</li>
7 <li><a>с чего начать работу</a>;</li>
8 <li><a>как создать веб-приложение</a>;</li>
8 <li><a>как создать веб-приложение</a>;</li>
9 <li><a>что запомнить</a>.</li>
9 <li><a>что запомнить</a>.</li>
10 </ul><p>Laravel - это бесплатный фреймворк для быстрой разработки веб-приложений на PHP. Это значит, что все инструменты уже под капотом и ничего не нужно придумывать самому - просто брать и делать. Вот что в Laravel доступно "из коробки":</p>
10 </ul><p>Laravel - это бесплатный фреймворк для быстрой разработки веб-приложений на PHP. Это значит, что все инструменты уже под капотом и ничего не нужно придумывать самому - просто брать и делать. Вот что в Laravel доступно "из коробки":</p>
11 <ul><li><strong>Интерактивная документация.</strong>Для каждой функции есть отдельная статья с примерами. Очень удобно как для начинающих, так и для опытных разработчиков.</li>
11 <ul><li><strong>Интерактивная документация.</strong>Для каждой функции есть отдельная статья с примерами. Очень удобно как для начинающих, так и для опытных разработчиков.</li>
12 <li><strong>Миграции баз данных.</strong>Laravel предоставляет удобный способ для работы с базами данных с помощью миграций. Миграции позволяют изменять структуру базы данных без необходимости писать SQL-запросы.</li>
12 <li><strong>Миграции баз данных.</strong>Laravel предоставляет удобный способ для работы с базами данных с помощью миграций. Миграции позволяют изменять структуру базы данных без необходимости писать SQL-запросы.</li>
13 <li><strong>Artisan.</strong>Консоль для разработчиков, которая упрощает взаимодействие с Laravel, позволяет проводить миграции баз данных, настраивать авторизацию и взаимодействовать с компонентами фреймворка.</li>
13 <li><strong>Artisan.</strong>Консоль для разработчиков, которая упрощает взаимодействие с Laravel, позволяет проводить миграции баз данных, настраивать авторизацию и взаимодействовать с компонентами фреймворка.</li>
14 <li><strong>ORM (object-relational mapping).</strong>Eloquent ORM позволяет работать с базами данных в объектно-ориентированном стиле, то есть выстраивать взаимодействие с полноценными объектами, которыми можно манипулировать.</li>
14 <li><strong>ORM (object-relational mapping).</strong>Eloquent ORM позволяет работать с базами данных в объектно-ориентированном стиле, то есть выстраивать взаимодействие с полноценными объектами, которыми можно манипулировать.</li>
15 <li><strong>Шаблоны.</strong>У Laravel куча шаблонов для создания пользовательского интерфейса. Это значительно упрощает процесс разработки.</li>
15 <li><strong>Шаблоны.</strong>У Laravel куча шаблонов для создания пользовательского интерфейса. Это значительно упрощает процесс разработки.</li>
16 <li><strong>Регистрация и авторизация.</strong>Фреймворк предоставляет готовые шаблоны для аутентификации пользователей, чтобы разработчикам не приходилось изобретать колесо.</li>
16 <li><strong>Регистрация и авторизация.</strong>Фреймворк предоставляет готовые шаблоны для аутентификации пользователей, чтобы разработчикам не приходилось изобретать колесо.</li>
17 <li><strong>Удобный дебаггинг и тестирование приложений.</strong>Обычно в веб-разработке не очень удобно реализована проверка кода на надёжность, поэтому создатели Laravel решили упростить этот процесс.</li>
17 <li><strong>Удобный дебаггинг и тестирование приложений.</strong>Обычно в веб-разработке не очень удобно реализована проверка кода на надёжность, поэтому создатели Laravel решили упростить этот процесс.</li>
18 </ul><p>На этом список возможностей Laravel не заканчивается. Ещё есть более специфические штуки: кэширование, маршрутизация, MVC и много других полезных фич. Но главное, что стоит знать о Laravel, - на нём можно быстро и удобно создавать сайты.</p>
18 </ul><p>На этом список возможностей Laravel не заканчивается. Ещё есть более специфические штуки: кэширование, маршрутизация, MVC и много других полезных фич. Но главное, что стоит знать о Laravel, - на нём можно быстро и удобно создавать сайты.</p>
19 <p>В PHP-мире постоянно идёт борьба между четырьмя популярными фреймворками:<a>Laravel</a>,<a>Symfony</a>,<a>Yii</a>и <a>CodeIgniter</a>. Каждый из них хорош, но, естественно, у каждого есть свои особенности.</p>
19 <p>В PHP-мире постоянно идёт борьба между четырьмя популярными фреймворками:<a>Laravel</a>,<a>Symfony</a>,<a>Yii</a>и <a>CodeIgniter</a>. Каждый из них хорош, но, естественно, у каждого есть свои особенности.</p>
20 <p>Если сравнивать Laravel с другими популярными фреймворками, то различия следующие:</p>
20 <p>Если сравнивать Laravel с другими популярными фреймворками, то различия следующие:</p>
21 <ul><li><strong>Меньшая сложность.</strong>Laravel проще изучить и использовать, чем, например, Symfony. Однако такая простота никак не ограничивает его функциональность.</li>
21 <ul><li><strong>Меньшая сложность.</strong>Laravel проще изучить и использовать, чем, например, Symfony. Однако такая простота никак не ограничивает его функциональность.</li>
22 <li><strong>Удобная маршрутизация.</strong>Laravel предлагает удобную маршрутизацию, например позволяя группировать, кэшировать и давать собственные названия маршрутам, а также определять действия на разные HTTP-запросы.</li>
22 <li><strong>Удобная маршрутизация.</strong>Laravel предлагает удобную маршрутизацию, например позволяя группировать, кэшировать и давать собственные названия маршрутам, а также определять действия на разные HTTP-запросы.</li>
23 <li><strong>Интеграция с библиотеками.</strong>Laravel использует пакетный менеджер Composer, который позволяет быстро подключать сторонние библиотеки в проект без лишних проблем.</li>
23 <li><strong>Интеграция с библиотеками.</strong>Laravel использует пакетный менеджер Composer, который позволяет быстро подключать сторонние библиотеки в проект без лишних проблем.</li>
24 <li><strong>Современная архитектура.</strong>В Laravel встроена современная архитектура, включая шаблон<a>MVC</a>(Model-View-Controller).</li>
24 <li><strong>Современная архитектура.</strong>В Laravel встроена современная архитектура, включая шаблон<a>MVC</a>(Model-View-Controller).</li>
25 </ul><p>В целом Laravel соблюдает отличный баланс между функциональностью, гибкостью и простотой в использовании. Правда, и у него есть свои особенности и границы применения. Поэтому его нельзя назвать "самым лучшим PHP-фреймворком". Однако создатели Laravel пытались сделать всё, чтобы он был комфортным для разработки:</p>
25 </ul><p>В целом Laravel соблюдает отличный баланс между функциональностью, гибкостью и простотой в использовании. Правда, и у него есть свои особенности и границы применения. Поэтому его нельзя назвать "самым лучшим PHP-фреймворком". Однако создатели Laravel пытались сделать всё, чтобы он был комфортным для разработки:</p>
26 <p>"Laravel предназначен, чтобы убрать боли в разработке путём упрощения привычных задач, которые часто встречаются в веб-проектах… Laravel нужен, чтобы сделать процесс разработки приятным для программистов без ухудшения функциональности приложений. Как говорится, счастливые разработчики пишут самый лучший код".</p>
26 <p>"Laravel предназначен, чтобы убрать боли в разработке путём упрощения привычных задач, которые часто встречаются в веб-проектах… Laravel нужен, чтобы сделать процесс разработки приятным для программистов без ухудшения функциональности приложений. Как говорится, счастливые разработчики пишут самый лучший код".</p>
27 <p><a><strong>Создатели Laravel</strong></a></p>
27 <p><a><strong>Создатели Laravel</strong></a></p>
28 <p>Раз Laravel - это популярный фреймворк для разработки веб-приложений, то на нём пишут различные веб-приложения (спасибо за очевидность):</p>
28 <p>Раз Laravel - это популярный фреймворк для разработки веб-приложений, то на нём пишут различные веб-приложения (спасибо за очевидность):</p>
29 <ul><li><strong>Лендинги, или посадочные страницы.</strong>На Laravel можно с минимальными затратами написать как простую страничку, так и мультистраничный сайт для компании. Конечно, это будет сложнее, чем использовать Tilda, но при этом можно масштабировать сайт и добавлять любые собственные фичи. Пример: лендинг<a>Canva</a>.</li>
29 <ul><li><strong>Лендинги, или посадочные страницы.</strong>На Laravel можно с минимальными затратами написать как простую страничку, так и мультистраничный сайт для компании. Конечно, это будет сложнее, чем использовать Tilda, но при этом можно масштабировать сайт и добавлять любые собственные фичи. Пример: лендинг<a>Canva</a>.</li>
30 <li><strong>API.</strong>Это прослойка для обмена данными между клиентской и серверной сторонами веб-приложения. Пример:<a>Laravel Passport</a>, API для безопасной авторизации пользователей в веб-приложении.</li>
30 <li><strong>API.</strong>Это прослойка для обмена данными между клиентской и серверной сторонами веб-приложения. Пример:<a>Laravel Passport</a>, API для безопасной авторизации пользователей в веб-приложении.</li>
31 <li><strong>CMS.</strong>Системы управления контентом (content management system, или CMS) - они нужны, чтобы управлять содержимым веб-сайта. Пример:<a>October CMS</a>.</li>
31 <li><strong>CMS.</strong>Системы управления контентом (content management system, или CMS) - они нужны, чтобы управлять содержимым веб-сайта. Пример:<a>October CMS</a>.</li>
32 <li><strong>Онлайн-магазины.</strong>На<strong></strong>Laravel также создают электронные коммерческие платформы, на которых можно продавать товары и услуги. Пример:<a>Bagisto</a>.</li>
32 <li><strong>Онлайн-магазины.</strong>На<strong></strong>Laravel также создают электронные коммерческие платформы, на которых можно продавать товары и услуги. Пример:<a>Bagisto</a>.</li>
33 </ul><p>Вот ещё несколько крупных проектов, которые написаны на Laravel:</p>
33 </ul><p>Вот ещё несколько крупных проектов, которые написаны на Laravel:</p>
34 <ul><li><a>laravel.com</a> - официальный сайт Laravel создан на Laravel;</li>
34 <ul><li><a>laravel.com</a> - официальный сайт Laravel создан на Laravel;</li>
35 <li><a>Neighbourly</a> - социальная сеть для общения с соседями;</li>
35 <li><a>Neighbourly</a> - социальная сеть для общения с соседями;</li>
36 <li><a>World Walking</a> - приложение для мотивации людей ходить больше;</li>
36 <li><a>World Walking</a> - приложение для мотивации людей ходить больше;</li>
37 <li><a>Ko-fi</a> - платформа для поддержки творчества;</li>
37 <li><a>Ko-fi</a> - платформа для поддержки творчества;</li>
38 <li><a>The Invoice Machine</a> - онлайн-сервис для выставления счетов;</li>
38 <li><a>The Invoice Machine</a> - онлайн-сервис для выставления счетов;</li>
39 <li><a>Startups.com</a> - платформа для запуска и развития стартапов;</li>
39 <li><a>Startups.com</a> - платформа для запуска и развития стартапов;</li>
40 <li><a>Larametrics</a> - это инструмент для мониторинга и анализа производительности приложений на Laravel.</li>
40 <li><a>Larametrics</a> - это инструмент для мониторинга и анализа производительности приложений на Laravel.</li>
41 </ul><p>А вот так выглядят сайты на Laravel:</p>
41 </ul><p>А вот так выглядят сайты на Laravel:</p>
42 Официальный сайт Laravel<em>Скриншот: Laravel / Skillbox Media</em>Социальная сеть Neighbourly<em>Скриншот: Neighbourly / Skillbox Media</em>Платформа для запуска и развития стартапов - Startups.com<em>Скриншот: Startups.com / Skillbox Media</em><p>Это лишь часть сайтов, написанных на Laravel. Некоторые платформы могут использовать фреймворк как один из компонентов сложного веб-приложения, но обычно об этом не говорят - особенно часто отмалчиваются крупные компании.</p>
42 Официальный сайт Laravel<em>Скриншот: Laravel / Skillbox Media</em>Социальная сеть Neighbourly<em>Скриншот: Neighbourly / Skillbox Media</em>Платформа для запуска и развития стартапов - Startups.com<em>Скриншот: Startups.com / Skillbox Media</em><p>Это лишь часть сайтов, написанных на Laravel. Некоторые платформы могут использовать фреймворк как один из компонентов сложного веб-приложения, но обычно об этом не говорят - особенно часто отмалчиваются крупные компании.</p>
43 <p>Чтобы освоить фреймворк, теории всегда мало, обязательно нужна практика. Поэтому дальше мы займёмся именно этим - напишем простое приложение, чтобы играть с компьютером в игру "Камень, ножницы, бумага". Но для начала нам надо будет установить<a>Laravel</a>и <a>MySQL</a>.</p>
43 <p>Чтобы освоить фреймворк, теории всегда мало, обязательно нужна практика. Поэтому дальше мы займёмся именно этим - напишем простое приложение, чтобы играть с компьютером в игру "Камень, ножницы, бумага". Но для начала нам надо будет установить<a>Laravel</a>и <a>MySQL</a>.</p>
44 <p>Если у вас ещё не установлен PHP, можете прочитать, как это сделать, в <a>нашей статье</a>.</p>
44 <p>Если у вас ещё не установлен PHP, можете прочитать, как это сделать, в <a>нашей статье</a>.</p>
45 <p>Composer - это пакетный менеджер для PHP. С помощью него можно устанавливать сторонние библиотеки и фреймворки, как это нужно в нашем случае. Рассмотрим установку для операционных систем Windows, macOS и Linux.</p>
45 <p>Composer - это пакетный менеджер для PHP. С помощью него можно устанавливать сторонние библиотеки и фреймворки, как это нужно в нашем случае. Рассмотрим установку для операционных систем Windows, macOS и Linux.</p>
46 <p><strong>Windows.</strong>На этой ОС процесс установки самый простой:</p>
46 <p><strong>Windows.</strong>На этой ОС процесс установки самый простой:</p>
47 <ul><li>переходим на <a>официальный сайт Composer</a>и скачиваем установочный файл Composer-Setup.exe;</li>
47 <ul><li>переходим на <a>официальный сайт Composer</a>и скачиваем установочный файл Composer-Setup.exe;</li>
48 <li>запускаем его и проходим привычные шаги установки.</li>
48 <li>запускаем его и проходим привычные шаги установки.</li>
49 </ul><p><strong>macOS.</strong>Установить Composer напрямую не получится, сначала нужно скачать менеджер пакетов<a>Homebrew</a> - о нём мы рассказывали в <a>статье про PHP</a>. Открываем терминал и вводим команду:</p>
49 </ul><p><strong>macOS.</strong>Установить Composer напрямую не получится, сначала нужно скачать менеджер пакетов<a>Homebrew</a> - о нём мы рассказывали в <a>статье про PHP</a>. Открываем терминал и вводим команду:</p>
50 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"<p>После установки Homebrew вводим команду:</p>
50 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"<p>После установки Homebrew вводим команду:</p>
51 brew install composer<p><strong>Linux.</strong>Здесь установить Composer проще, чем на macOS. Для разных Linux-систем команды могут различаться (из-за особенностей системы управления пакетами), но сам процесс установки, по сути, будет идентичным. Вот как выглядит процесс установки в Debian-подобных дистрибутивах:</p>
51 brew install composer<p><strong>Linux.</strong>Здесь установить Composer проще, чем на macOS. Для разных Linux-систем команды могут различаться (из-за особенностей системы управления пакетами), но сам процесс установки, по сути, будет идентичным. Вот как выглядит процесс установки в Debian-подобных дистрибутивах:</p>
52 $ sudo apt-get update $ sudo apt-get install composer<p>Если возникли трудности с установкой, можно обратиться к документации на <a>официальном сайте</a>. А если всё получилось - переходим дальше.</p>
52 $ sudo apt-get update $ sudo apt-get install composer<p>Если возникли трудности с установкой, можно обратиться к документации на <a>официальном сайте</a>. А если всё получилось - переходим дальше.</p>
53 <p>Мы будем сохранять статистику игр в базе данных, а для неё нужен собственный сервер. Поэтому скачиваем MySQL с <a>официального сайта</a>.</p>
53 <p>Мы будем сохранять статистику игр в базе данных, а для неё нужен собственный сервер. Поэтому скачиваем MySQL с <a>официального сайта</a>.</p>
54 <p>Далее надо выбрать операционную систему и пройти стандартный процесс установки. Обратите внимание: на этапе конфигурирования обязательно запомните введённый пароль, потому что с его помощью вы будете подключаться к базе данных.</p>
54 <p>Далее надо выбрать операционную систему и пройти стандартный процесс установки. Обратите внимание: на этапе конфигурирования обязательно запомните введённый пароль, потому что с его помощью вы будете подключаться к базе данных.</p>
55 Первичная настройка MySQL<em>Скриншот: Skillbox Media</em><p>Оставьте галочку, где говорят, что MySQL Server запустится сразу после установки. И теперь всё готово.</p>
55 Первичная настройка MySQL<em>Скриншот: Skillbox Media</em><p>Оставьте галочку, где говорят, что MySQL Server запустится сразу после установки. И теперь всё готово.</p>
56 <p><strong>Альтернативная установка для Linux.</strong>Если вы используете Linux, то скачивать установщик не обязательно - можно опять-таки воспользоваться пакетным менеджером. Делается это примерно так (с поправкой на ваш дистрибутив):</p>
56 <p><strong>Альтернативная установка для Linux.</strong>Если вы используете Linux, то скачивать установщик не обязательно - можно опять-таки воспользоваться пакетным менеджером. Делается это примерно так (с поправкой на ваш дистрибутив):</p>
57 sudo apt-get install mysql-server<p>После установки нужно запустить сам сервер:</p>
57 sudo apt-get install mysql-server<p>После установки нужно запустить сам сервер:</p>
58 sudo service mysql status<p>Готово - сервер запущен!</p>
58 sudo service mysql status<p>Готово - сервер запущен!</p>
59 <p>Теперь нам необходимо установить Laravel. Это можно сделать через Composer, который автоматически умеет скачивать Laravel и все зависимости.</p>
59 <p>Теперь нам необходимо установить Laravel. Это можно сделать через Composer, который автоматически умеет скачивать Laravel и все зависимости.</p>
60 <p>Откройте командную строку и введите следующую команду:</p>
60 <p>Откройте командную строку и введите следующую команду:</p>
61 composer create-project --prefer-dist laravel/laravel myapp<p>Здесь myapp - это имя вашего проекта. Эта команда создаст новый проект Laravel в папке myapp.</p>
61 composer create-project --prefer-dist laravel/laravel myapp<p>Здесь myapp - это имя вашего проекта. Эта команда создаст новый проект Laravel в папке myapp.</p>
62 Создание нового Laravel-проекта<em>Скриншот: Skillbox Media</em><p>Мы установили Laravel последней версии, 10.0.4. На скриншоте выше показан успешный процесс установки. Если возникли проблемы - смотрите документацию по установке на <a>официальном сайте</a>.</p>
62 Создание нового Laravel-проекта<em>Скриншот: Skillbox Media</em><p>Мы установили Laravel последней версии, 10.0.4. На скриншоте выше показан успешный процесс установки. Если возникли проблемы - смотрите документацию по установке на <a>официальном сайте</a>.</p>
63 <p>Чтобы проверить правильность установки Laravel, нам достаточно только запустить встроенный веб-сервер. Кстати, не рекомендуем использовать встроенный веб-сервер в продакшене - для реального проекта лучше выбрать<a>Apache</a>или<a>Nginx</a>.</p>
63 <p>Чтобы проверить правильность установки Laravel, нам достаточно только запустить встроенный веб-сервер. Кстати, не рекомендуем использовать встроенный веб-сервер в продакшене - для реального проекта лучше выбрать<a>Apache</a>или<a>Nginx</a>.</p>
64 <p>Запустить веб-сервер просто: переходим в папку с проектом и открываем командную строку. Вводим команду:</p>
64 <p>Запустить веб-сервер просто: переходим в папку с проектом и открываем командную строку. Вводим команду:</p>
65 php artisan serve<p>Должно появиться такое сообщение:</p>
65 php artisan serve<p>Должно появиться такое сообщение:</p>
66 Веб-сервер успешно запущен<em>Скриншот: Skillbox Media</em><p>Открываем браузер и переходим по указанному адресу: http://127.0.0.1:8000/. Если всё хорошо, должен открыться примерно такой экран:</p>
66 Веб-сервер успешно запущен<em>Скриншот: Skillbox Media</em><p>Открываем браузер и переходим по указанному адресу: http://127.0.0.1:8000/. Если всё хорошо, должен открыться примерно такой экран:</p>
67 Страница по умолчанию<em>Скриншот: Skillbox Media</em><p>Это страница Laravel по умолчанию. Её, конечно же, можно менять - этим мы и будем заниматься дальше. Ну а пока будет полезно перейти по ссылкам - почитать документацию и свежие новости о фреймворке.</p>
67 Страница по умолчанию<em>Скриншот: Skillbox Media</em><p>Это страница Laravel по умолчанию. Её, конечно же, можно менять - этим мы и будем заниматься дальше. Ну а пока будет полезно перейти по ссылкам - почитать документацию и свежие новости о фреймворке.</p>
68 <p>Теперь, когда у нас установлен Laravel, можно приступать к написанию кода. Как уже упоминалось выше, мы создадим игру "Камень, ножницы, бумага" и будем играть в неё с компьютером.</p>
68 <p>Теперь, когда у нас установлен Laravel, можно приступать к написанию кода. Как уже упоминалось выше, мы создадим игру "Камень, ножницы, бумага" и будем играть в неё с компьютером.</p>
69 <p>План такой:</p>
69 <p>План такой:</p>
70 <ul><li><strong>Создать новый проект</strong>и выбрать название.</li>
70 <ul><li><strong>Создать новый проект</strong>и выбрать название.</li>
71 <li><strong>Организовать базу данных</strong>, чтобы сохранять статистику игр.</li>
71 <li><strong>Организовать базу данных</strong>, чтобы сохранять статистику игр.</li>
72 <li><strong>Сделать миграцию базы данных</strong>, чтобы все таблицы были на своём месте.</li>
72 <li><strong>Сделать миграцию базы данных</strong>, чтобы все таблицы были на своём месте.</li>
73 <li><strong>Добавить маршрут</strong>и разобраться, что это такое.</li>
73 <li><strong>Добавить маршрут</strong>и разобраться, что это такое.</li>
74 <li><strong>Создать контроллер</strong>и тоже понять, зачем он нужен.</li>
74 <li><strong>Создать контроллер</strong>и тоже понять, зачем он нужен.</li>
75 <li><strong>Создать кнопки для игры</strong>.</li>
75 <li><strong>Создать кнопки для игры</strong>.</li>
76 <li><strong>Украсить всё с помощью CSS-стилей</strong>.</li>
76 <li><strong>Украсить всё с помощью CSS-стилей</strong>.</li>
77 </ul><p>План здоровский - приступим!</p>
77 </ul><p>План здоровский - приступим!</p>
78 <p>Идём уже знакомым путём: запускаем командную строку и вводим команду для Composer:</p>
78 <p>Идём уже знакомым путём: запускаем командную строку и вводим команду для Composer:</p>
79 composer create-project --prefer-dist laravel/laravel rock-paper-scissors<p>Проект создали - файлы не поменялись:</p>
79 composer create-project --prefer-dist laravel/laravel rock-paper-scissors<p>Проект создали - файлы не поменялись:</p>
80 Структура проекта<em>Скриншот: Skillbox Media</em><p>Оставьте командную строку открытой - она нам ещё пригодится, а сами перейдите в папку с проектом с помощью следующей команды:</p>
80 Структура проекта<em>Скриншот: Skillbox Media</em><p>Оставьте командную строку открытой - она нам ещё пригодится, а сами перейдите в папку с проектом с помощью следующей команды:</p>
81 cd rock-paper-scissors<p><a>Команда</a>cd позволяет двигаться вверх и вниз по папкам. Ну а раз мы уже в нужном месте, переходим дальше.</p>
81 cd rock-paper-scissors<p><a>Команда</a>cd позволяет двигаться вверх и вниз по папкам. Ну а раз мы уже в нужном месте, переходим дальше.</p>
82 <p>Чтобы сохранять результаты игр, нам нужна база данных. Она представляет собой обычный файл, в котором данные хранятся в удобном для использования виде.</p>
82 <p>Чтобы сохранять результаты игр, нам нужна база данных. Она представляет собой обычный файл, в котором данные хранятся в удобном для использования виде.</p>
83 <p>Перейдём в файл .env, который находится в папке нашего проекта. Он может быть скрыт, потому что его название начинается с точки. Если он у вас не отображается, поменяйте<a>настройки</a>отображения файлов в своей системе.</p>
83 <p>Перейдём в файл .env, который находится в папке нашего проекта. Он может быть скрыт, потому что его название начинается с точки. Если он у вас не отображается, поменяйте<a>настройки</a>отображения файлов в своей системе.</p>
84 <p>В файле нам нужно поправить следующие строки:</p>
84 <p>В файле нам нужно поправить следующие строки:</p>
85 <em>Скриншот: Skillbox Media</em><p>Нам нужны последние три опции:</p>
85 <em>Скриншот: Skillbox Media</em><p>Нам нужны последние три опции:</p>
86 DB_DATABASE=rock_paper_scissors DB_USERNAME=root DB_PASSWORD=password<p>В первой строке мы задаём название базы данных, а во второй и третьей - данные для входа в неё. Сейчас мы сделаем их простыми, но помните, что, если вы собираетесь выкладывать сайт в интернет, очень важно, чтобы пароль и логин были надёжными.</p>
86 DB_DATABASE=rock_paper_scissors DB_USERNAME=root DB_PASSWORD=password<p>В первой строке мы задаём название базы данных, а во второй и третьей - данные для входа в неё. Сейчас мы сделаем их простыми, но помните, что, если вы собираетесь выкладывать сайт в интернет, очень важно, чтобы пароль и логин были надёжными.</p>
87 <p>Сохраняем файл и закрываем его - база данных предварительно настроена.</p>
87 <p>Сохраняем файл и закрываем его - база данных предварительно настроена.</p>
88 <p>Мы создали базу данных, настало время создать нужные таблицы. Открываем командную строку и убеждаемся, что находимся в папке с проектом. Вводим следующую команду:</p>
88 <p>Мы создали базу данных, настало время создать нужные таблицы. Открываем командную строку и убеждаемся, что находимся в папке с проектом. Вводим следующую команду:</p>
89 php artisan make:migration create_game_statistics_table --create=game_statistics<p>Эта команда сделает миграцию базы данных, то есть изменит её содержимое и создаст файл с таблицей. В нашем случае - добавит таблицу game_statistics, а также файл с датой создания таблицы и припиской _create_game_statistics_table:</p>
89 php artisan make:migration create_game_statistics_table --create=game_statistics<p>Эта команда сделает миграцию базы данных, то есть изменит её содержимое и создаст файл с таблицей. В нашем случае - добавит таблицу game_statistics, а также файл с датой создания таблицы и припиской _create_game_statistics_table:</p>
90 Создаём новую таблицу в БД<em>Скриншот: Skillbox Media</em><p>Появился PHP-файл миграции, который находится в папке database/migrations:</p>
90 Создаём новую таблицу в БД<em>Скриншот: Skillbox Media</em><p>Появился PHP-файл миграции, который находится в папке database/migrations:</p>
91 Миграции в структуре Laravel-проекта<em>Скриншот: Skillbox Media</em><p>Открываем его и добавляем следующий код - он поможет задать структуру нашей таблицы:</p>
91 Миграции в структуре Laravel-проекта<em>Скриншот: Skillbox Media</em><p>Открываем его и добавляем следующий код - он поможет задать структуру нашей таблицы:</p>
92 &lt;?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateGameStatisticsTable extends Migration { public function up() { Schema::create('game_statistics', function (Blueprint $table) { $table-&gt;id(); $table-&gt;string('player_name'); $table-&gt;string('computer_choice'); $table-&gt;string('player_choice'); $table-&gt;string('result'); $table-&gt;timestamps(); }); } public function down() { Schema::dropIfExists('game_statistics'); } }<p>Эта миграция создаст таблицы с шестью колонками: уникальным идентификатором игры (id), именем игрока (player_name), ходом компьютера (computer_choice), ходом игрока (player_choice), результатом игры (result) и временной отметкой (timestamps) - указанием времени, когда проходила игра.</p>
92 &lt;?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateGameStatisticsTable extends Migration { public function up() { Schema::create('game_statistics', function (Blueprint $table) { $table-&gt;id(); $table-&gt;string('player_name'); $table-&gt;string('computer_choice'); $table-&gt;string('player_choice'); $table-&gt;string('result'); $table-&gt;timestamps(); }); } public function down() { Schema::dropIfExists('game_statistics'); } }<p>Эта миграция создаст таблицы с шестью колонками: уникальным идентификатором игры (id), именем игрока (player_name), ходом компьютера (computer_choice), ходом игрока (player_choice), результатом игры (result) и временной отметкой (timestamps) - указанием времени, когда проходила игра.</p>
93 <p>Обратите внимание на типы данных в нашей таблице. У нас есть четыре колонки с типом "строка" (player_name, computer_choice, player_choice и result), а также два уникальных типа данных: id и timestamps. Первый - это айдишник строки в таблице, и он представляет собой обычное число, но с дополнительными фичами. А второй представляет собой дату в формате YYYY-MM-DD HH:MM:SS.</p>
93 <p>Обратите внимание на типы данных в нашей таблице. У нас есть четыре колонки с типом "строка" (player_name, computer_choice, player_choice и result), а также два уникальных типа данных: id и timestamps. Первый - это айдишник строки в таблице, и он представляет собой обычное число, но с дополнительными фичами. А второй представляет собой дату в формате YYYY-MM-DD HH:MM:SS.</p>
94 <p>Сохраняем файл и закрываем его. Теперь нам нужно запустить миграцию - терминал нам поможет:</p>
94 <p>Сохраняем файл и закрываем его. Теперь нам нужно запустить миграцию - терминал нам поможет:</p>
95 php artisan migrate<p>У нас спросят, хотим ли мы создать новую таблицу в базе данных. Соглашаемся:</p>
95 php artisan migrate<p>У нас спросят, хотим ли мы создать новую таблицу в базе данных. Соглашаемся:</p>
96 База данных настроена и готова к работе<em>Скриншот: Skillbox Media</em><p>Готово - теперь у нас есть работающая база данных с нужной таблицей.</p>
96 База данных настроена и готова к работе<em>Скриншот: Skillbox Media</em><p>Готово - теперь у нас есть работающая база данных с нужной таблицей.</p>
97 <p>Весь бэкенд строится на маршрутах - или URL-адресах. Они помогают задавать удобную структуру и понятное поведение веб-приложениям.</p>
97 <p>Весь бэкенд строится на маршрутах - или URL-адресах. Они помогают задавать удобную структуру и понятное поведение веб-приложениям.</p>
98 <p>Для пользователя маршруты - это отдельные "вкладки" на сайте. Например, если зайти на сайт Skillbox, откроется его главная страница<a>www.skillbox.ru</a>. А если кликнуть на любой курс, мы перейдём на другую страницу сайта с другим URL-адресом, например<a>www.skillbox.ru/course/profession-python/</a>. Мы увидим, что к адресу нашего сайта добавился текст: /course/profession-python/. Эта "приписка" и перенесла нас на другую страницу с другим содержимым. Но не просто перенесла, а запустила определённый код, который и отрисовал эту страницу.</p>
98 <p>Для пользователя маршруты - это отдельные "вкладки" на сайте. Например, если зайти на сайт Skillbox, откроется его главная страница<a>www.skillbox.ru</a>. А если кликнуть на любой курс, мы перейдём на другую страницу сайта с другим URL-адресом, например<a>www.skillbox.ru/course/profession-python/</a>. Мы увидим, что к адресу нашего сайта добавился текст: /course/profession-python/. Эта "приписка" и перенесла нас на другую страницу с другим содержимым. Но не просто перенесла, а запустила определённый код, который и отрисовал эту страницу.</p>
99 <p>Нам понадобятся два маршрута: корневой / и игровой /play. Чтобы их добавить, нужно перейти в папку routes, открыть файл web.php и вписать туда следующий код:</p>
99 <p>Нам понадобятся два маршрута: корневой / и игровой /play. Чтобы их добавить, нужно перейти в папку routes, открыть файл web.php и вписать туда следующий код:</p>
100 Route::get('/', [GameController::class,'index'])-&gt;name('game.index'); Route::post('/play', [GameController::class,'play'])-&gt;name('game.play');<p>На корневом маршруте мы будем отображать статистику и предлагать пользователю сыграть в игру, а на игровом маршруте будем собственно играть.</p>
100 Route::get('/', [GameController::class,'index'])-&gt;name('game.index'); Route::post('/play', [GameController::class,'play'])-&gt;name('game.play');<p>На корневом маршруте мы будем отображать статистику и предлагать пользователю сыграть в игру, а на игровом маршруте будем собственно играть.</p>
101 <p>Этот код будет работать так: если мы заходим по корневому маршруту /, то PHP отрисует страницу game.index, а если зайдём по игровому маршруту /play, то он создаст страницу game.play. Поведение этих страниц мы опишем дальше.</p>
101 <p>Этот код будет работать так: если мы заходим по корневому маршруту /, то PHP отрисует страницу game.index, а если зайдём по игровому маршруту /play, то он создаст страницу game.play. Поведение этих страниц мы опишем дальше.</p>
102 <p>В начале нужно прописать ещё одну строку:</p>
102 <p>В начале нужно прописать ещё одну строку:</p>
103 namespace App\Http\Controllers;<p>Итоговый файл должен выглядеть так:</p>
103 namespace App\Http\Controllers;<p>Итоговый файл должен выглядеть так:</p>
104 Содержимое файла web.php<em>Скриншот: Skillbox Media</em><p>Готово! Не забываем сохранить файл.</p>
104 Содержимое файла web.php<em>Скриншот: Skillbox Media</em><p>Готово! Не забываем сохранить файл.</p>
105 <p>Контроллер - это понятие из шаблона проектирования MVC. О нём у нас есть отдельная<a>статья</a>.</p>
105 <p>Контроллер - это понятие из шаблона проектирования MVC. О нём у нас есть отдельная<a>статья</a>.</p>
106 <p><strong>О контроллерах простыми словами</strong></p>
106 <p><strong>О контроллерах простыми словами</strong></p>
107 <p>Чтобы не вдаваться в подробности, скажем, что контроллер - это часть приложения, которая отвечает за обработку запросов от пользователя и взаимодействие с моделью (данными) и представлением (отображением).</p>
107 <p>Чтобы не вдаваться в подробности, скажем, что контроллер - это часть приложения, которая отвечает за обработку запросов от пользователя и взаимодействие с моделью (данными) и представлением (отображением).</p>
108 <p>Простыми словами, контроллер - это связующее звено между пользовательским интерфейсом и базой данных. Когда пользователь отправляет запрос на сервер, контроллер получает этот запрос, обрабатывает его и взаимодействует с базой данных, чтобы получить необходимые данные. Затем контроллер передаёт эти данные в представление, которое отображает их на экране для пользователя.</p>
108 <p>Простыми словами, контроллер - это связующее звено между пользовательским интерфейсом и базой данных. Когда пользователь отправляет запрос на сервер, контроллер получает этот запрос, обрабатывает его и взаимодействует с базой данных, чтобы получить необходимые данные. Затем контроллер передаёт эти данные в представление, которое отображает их на экране для пользователя.</p>
109 <p>Контроллер отделяет бизнес-логику приложения от пользовательского интерфейса, что позволяет более эффективно управлять приложением и обеспечивает более гибкую архитектуру. Он также даёт возможность программистам работать с приложением по отдельности, без необходимости знать о других компонентах приложения.</p>
109 <p>Контроллер отделяет бизнес-логику приложения от пользовательского интерфейса, что позволяет более эффективно управлять приложением и обеспечивает более гибкую архитектуру. Он также даёт возможность программистам работать с приложением по отдельности, без необходимости знать о других компонентах приложения.</p>
110 <p>Нам нужно создать контроллер для всей игры. Называться он будет GameController. Чтобы создать его, нужно запустить в терминале следующую команду:</p>
110 <p>Нам нужно создать контроллер для всей игры. Называться он будет GameController. Чтобы создать его, нужно запустить в терминале следующую команду:</p>
111 php artisan make:controller GameController<em>Скриншот: Skillbox Media</em><p>Эта команда создаст новый файл с контроллером в папке app/Http/Controllers. Перейдём туда, откроем файл GameController.php и впишем следующий код:</p>
111 php artisan make:controller GameController<em>Скриншот: Skillbox Media</em><p>Эта команда создаст новый файл с контроллером в папке app/Http/Controllers. Перейдём туда, откроем файл GameController.php и впишем следующий код:</p>
112 &lt;?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class GameController extends Controller { public function index() { return view('game'); } }<p>Этот код определяет метод index(), который будет возвращать игровое представление, чтобы отображать элементы на сайте. Мы опишем его на следующем шаге.</p>
112 &lt;?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class GameController extends Controller { public function index() { return view('game'); } }<p>Этот код определяет метод index(), который будет возвращать игровое представление, чтобы отображать элементы на сайте. Мы опишем его на следующем шаге.</p>
113 <p>А пока добавим в этот же файл ещё одну функцию - play():</p>
113 <p>А пока добавим в этот же файл ещё одну функцию - play():</p>
114 public function play(Request $request) { $playerChoice = $request-&gt;input('choice'); // Генерируем случайный ход для компьютера $computerChoice = rand(1, 3); if ($computerChoice == 1) { $computerChoice = 'rock'; } elseif ($computerChoice == 2) { $computerChoice = 'paper'; } else { $computerChoice = 'scissors'; } // Получаем результат игры if ($playerChoice == $computerChoice) { $result = 'tie'; } elseif (($playerChoice == 'rock' &amp;&amp; $computerChoice == 'scissors') || ($playerChoice == 'paper' &amp;&amp; $computerChoice == 'rock') || ($playerChoice == 'scissors' &amp;&amp; $computerChoice == 'paper')) { $result = 'win'; } else { $result = 'lose'; } // Сохраняем статистику в базу данных DB::table('game_statistics')-&gt;insert([ 'player_name' =&gt; 'Player 1', 'computer_choice' =&gt; $computerChoice, 'player_choice' =&gt; $playerChoice, 'result' =&gt; $result, 'created_at' =&gt; now(), 'updated_at' =&gt; now(), ]); // Возвращаем результат игры в представление return view('game', ['result' =&gt; $result]); }<p>Здесь мы прописали основную логику игры. На вход функция принимает объект Request, который содержит ход игрока. Экземпляр этого объекта будет приходить, когда мы нажмём на одну из кнопок в игре ("Камень", "Ножницы" или "Бумага"), а потом отправим наш выбор методом POST.</p>
114 public function play(Request $request) { $playerChoice = $request-&gt;input('choice'); // Генерируем случайный ход для компьютера $computerChoice = rand(1, 3); if ($computerChoice == 1) { $computerChoice = 'rock'; } elseif ($computerChoice == 2) { $computerChoice = 'paper'; } else { $computerChoice = 'scissors'; } // Получаем результат игры if ($playerChoice == $computerChoice) { $result = 'tie'; } elseif (($playerChoice == 'rock' &amp;&amp; $computerChoice == 'scissors') || ($playerChoice == 'paper' &amp;&amp; $computerChoice == 'rock') || ($playerChoice == 'scissors' &amp;&amp; $computerChoice == 'paper')) { $result = 'win'; } else { $result = 'lose'; } // Сохраняем статистику в базу данных DB::table('game_statistics')-&gt;insert([ 'player_name' =&gt; 'Player 1', 'computer_choice' =&gt; $computerChoice, 'player_choice' =&gt; $playerChoice, 'result' =&gt; $result, 'created_at' =&gt; now(), 'updated_at' =&gt; now(), ]); // Возвращаем результат игры в представление return view('game', ['result' =&gt; $result]); }<p>Здесь мы прописали основную логику игры. На вход функция принимает объект Request, который содержит ход игрока. Экземпляр этого объекта будет приходить, когда мы нажмём на одну из кнопок в игре ("Камень", "Ножницы" или "Бумага"), а потом отправим наш выбор методом POST.</p>
115 <p>Подробнее об HTTP-запросах вы можете прочитать в нашей статье о<a>протоколе HTTP</a>.</p>
115 <p>Подробнее об HTTP-запросах вы можете прочитать в нашей статье о<a>протоколе HTTP</a>.</p>
116 <p>После того как мы обработали запрос, нам нужно сгенерировать ответ компьютера - с помощью генератора случайных чисел. И в конце мы определяем победителя и записываем результат в базу данных методом insert().</p>
116 <p>После того как мы обработали запрос, нам нужно сгенерировать ответ компьютера - с помощью генератора случайных чисел. И в конце мы определяем победителя и записываем результат в базу данных методом insert().</p>
117 <p>Логика игры готова! Опять же, не забываем сохранить файл.</p>
117 <p>Логика игры готова! Опять же, не забываем сохранить файл.</p>
118 <p>Метод index() из файла GameController.php отображает страницу с игрой, но пока на ней ничего нет, поэтому давайте создадим пару кнопок.</p>
118 <p>Метод index() из файла GameController.php отображает страницу с игрой, но пока на ней ничего нет, поэтому давайте создадим пару кнопок.</p>
119 <p>Открываем папку resources/views и создаём там файл с названием game.blade.php. Добавляем туда следующий код, чтобы создать игровой интерфейс:</p>
119 <p>Открываем папку resources/views и создаём там файл с названием game.blade.php. Добавляем туда следующий код, чтобы создать игровой интерфейс:</p>
120 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Rock Paper Scissors&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;Rock Paper Scissors&lt;/h1&gt; @if(isset($result)) &lt;p&gt;You {{ $result }}!&lt;/p&gt; @endif &lt;form method="POST" action="{{ route('game.play') }}"&gt; @csrf &lt;label for="rock"&gt;Rock&lt;/label&gt; &lt;input type="radio" name="choice" id="rock" value="rock"&gt; &lt;label for="paper"&gt;Paper&lt;/label&gt; &lt;input type="radio" name="choice" id="paper" value="paper"&gt; &lt;label for="scissors"&gt;Scissors&lt;/label&gt; &lt;input type="radio" name="choice" id="scissors" value="scissors"&gt; &lt;button type="submit"&gt;Play&lt;/button&gt; &lt;/form&gt; &lt;/body&gt; &lt;/html&gt;<p>Не удивляйтесь, что мы вставили HTML-код в PHP-файл, - это нормально. PHP умеет работать с HTML.</p>
120 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Rock Paper Scissors&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;Rock Paper Scissors&lt;/h1&gt; @if(isset($result)) &lt;p&gt;You {{ $result }}!&lt;/p&gt; @endif &lt;form method="POST" action="{{ route('game.play') }}"&gt; @csrf &lt;label for="rock"&gt;Rock&lt;/label&gt; &lt;input type="radio" name="choice" id="rock" value="rock"&gt; &lt;label for="paper"&gt;Paper&lt;/label&gt; &lt;input type="radio" name="choice" id="paper" value="paper"&gt; &lt;label for="scissors"&gt;Scissors&lt;/label&gt; &lt;input type="radio" name="choice" id="scissors" value="scissors"&gt; &lt;button type="submit"&gt;Play&lt;/button&gt; &lt;/form&gt; &lt;/body&gt; &lt;/html&gt;<p>Не удивляйтесь, что мы вставили HTML-код в PHP-файл, - это нормально. PHP умеет работать с HTML.</p>
121 <p>Но вернёмся к коду: мы создали простой игровой интерфейс, который состоит из трёх кнопок с выбором вариантов. Также мы добавили кнопку, чтобы отправлять данные в GameController и получать результат игры $result, если она уже была сыграна.</p>
121 <p>Но вернёмся к коду: мы создали простой игровой интерфейс, который состоит из трёх кнопок с выбором вариантов. Также мы добавили кнопку, чтобы отправлять данные в GameController и получать результат игры $result, если она уже была сыграна.</p>
122 <p>Результат игры нужен, чтобы мы могли видеть, кто победил в прошлой игре. А чтобы постоянно не выводить этот текст, мы сперва проверяем, была ли переменная $result объявлена через GameController.</p>
122 <p>Результат игры нужен, чтобы мы могли видеть, кто победил в прошлой игре. А чтобы постоянно не выводить этот текст, мы сперва проверяем, была ли переменная $result объявлена через GameController.</p>
123 <p>Теперь мы можем запустить наш сервер и посмотреть на результат:</p>
123 <p>Теперь мы можем запустить наш сервер и посмотреть на результат:</p>
124 php artisan serve<p>Видим то, что и хотели увидеть:</p>
124 php artisan serve<p>Видим то, что и хотели увидеть:</p>
125 <em>Скриншот: Skillbox Media</em><p>Если нажать на одну из кнопок, можно узнать, кто победил:</p>
125 <em>Скриншот: Skillbox Media</em><p>Если нажать на одну из кнопок, можно узнать, кто победил:</p>
126 <em>Скриншот: Skillbox Media</em><p>Но сразу проявляется одна проблема: мы не знаем, какие ходы сделал компьютер, а какие - мы. Давайте это исправим.</p>
126 <em>Скриншот: Skillbox Media</em><p>Но сразу проявляется одна проблема: мы не знаем, какие ходы сделал компьютер, а какие - мы. Давайте это исправим.</p>
127 <p>Заходим обратно в файл GameController.php и изменяем всего одну строку:</p>
127 <p>Заходим обратно в файл GameController.php и изменяем всего одну строку:</p>
128 return view('game', ['result' =&gt; $result, 'player_choice' =&gt; $playerChoice, 'computer_choice' =&gt; $computerChoice]);<p>Теперь мы будем возвращать в наше представление дополнительные переменные. Внесём изменения и в файл game.blade.php:</p>
128 return view('game', ['result' =&gt; $result, 'player_choice' =&gt; $playerChoice, 'computer_choice' =&gt; $computerChoice]);<p>Теперь мы будем возвращать в наше представление дополнительные переменные. Внесём изменения и в файл game.blade.php:</p>
129 @if(isset($result)) &lt;p&gt;You played {{ $player_choice }}&lt;/p&gt; &lt;p&gt;Computer played {{ $computer_choice }}&lt;/p&gt; &lt;p&gt;You {{ $result }}!&lt;/p&gt; @endif<p>Перезапускаем сервер и видим, что теперь всё работает корректно:</p>
129 @if(isset($result)) &lt;p&gt;You played {{ $player_choice }}&lt;/p&gt; &lt;p&gt;Computer played {{ $computer_choice }}&lt;/p&gt; &lt;p&gt;You {{ $result }}!&lt;/p&gt; @endif<p>Перезапускаем сервер и видим, что теперь всё работает корректно:</p>
130 <em>Скриншот: Skillbox Media</em><p>Осталось вывести результаты последних игр, и наше приложение будет готово. Для простоты будем учитывать статистику последних десяти игр.</p>
130 <em>Скриншот: Skillbox Media</em><p>Осталось вывести результаты последних игр, и наше приложение будет готово. Для простоты будем учитывать статистику последних десяти игр.</p>
131 <p>Для этого необходимо изменить файл GameController.php, а вернее функции index() и play():</p>
131 <p>Для этого необходимо изменить файл GameController.php, а вернее функции index() и play():</p>
132 public function index() { $last_games = DB::table('game_statistics') -&gt;orderBy('created_at', 'desc') -&gt;limit(10) -&gt;get(); return view('game', ['last_games' =&gt; $last_games]); } public function play(Request $request) { $last_games = DB::table('game_statistics') -&gt;orderBy('created_at', 'desc') -&gt;limit(10) -&gt;get(); $playerChoice = $request-&gt;input('choice'); ... // Возвращаем результат игры в представление return view('game', ['result' =&gt; $result, 'player_choice' =&gt; $playerChoice, 'computer_choice' =&gt; $computerChoice, 'last_games' =&gt; $last_games]); }<p>Мы опустили несколько строк, чтобы показать лишь самые важные фрагменты. Как видите, у нас появилась новая переменная $last_games, в которую помещаются 10 последних строк базы данных. Делается это с помощью двух методов: orderBy(), который используется, чтобы доставать только самые свежие игры, и limit(10), который помогает ограничить их количество десятью.</p>
132 public function index() { $last_games = DB::table('game_statistics') -&gt;orderBy('created_at', 'desc') -&gt;limit(10) -&gt;get(); return view('game', ['last_games' =&gt; $last_games]); } public function play(Request $request) { $last_games = DB::table('game_statistics') -&gt;orderBy('created_at', 'desc') -&gt;limit(10) -&gt;get(); $playerChoice = $request-&gt;input('choice'); ... // Возвращаем результат игры в представление return view('game', ['result' =&gt; $result, 'player_choice' =&gt; $playerChoice, 'computer_choice' =&gt; $computerChoice, 'last_games' =&gt; $last_games]); }<p>Мы опустили несколько строк, чтобы показать лишь самые важные фрагменты. Как видите, у нас появилась новая переменная $last_games, в которую помещаются 10 последних строк базы данных. Делается это с помощью двух методов: orderBy(), который используется, чтобы доставать только самые свежие игры, и limit(10), который помогает ограничить их количество десятью.</p>
133 <p>В каждом представлении мы также добавляем этот список в качестве возвращаемого значения.</p>
133 <p>В каждом представлении мы также добавляем этот список в качестве возвращаемого значения.</p>
134 <p>Теперь нужно поправить файл game.blade.php и отобразить эти игры:</p>
134 <p>Теперь нужно поправить файл game.blade.php и отобразить эти игры:</p>
135 &lt;ul&gt; @foreach ($last_games as $last_game) &lt;li&gt; &lt;p&gt;You {{ $last_game-&gt;result }}&lt;/p&gt; &lt;p&gt;You played {{ $last_game-&gt;player_choice }}&lt;/p&gt; &lt;p&gt;Computer played {{ $last_game-&gt;computer_choice }}&lt;/p&gt; &lt;/li&gt; @endforeach &lt;/ul&gt;<p>Этот код просто создаёт ненумерованный список, который располагается после формы. Внутри списка мы добавляем элементы &lt;li&gt; через цикл @foreach. В нём мы проходим по всем нашим играм и выводим для каждой игры результат, ход игрока и компьютера.</p>
135 &lt;ul&gt; @foreach ($last_games as $last_game) &lt;li&gt; &lt;p&gt;You {{ $last_game-&gt;result }}&lt;/p&gt; &lt;p&gt;You played {{ $last_game-&gt;player_choice }}&lt;/p&gt; &lt;p&gt;Computer played {{ $last_game-&gt;computer_choice }}&lt;/p&gt; &lt;/li&gt; @endforeach &lt;/ul&gt;<p>Этот код просто создаёт ненумерованный список, который располагается после формы. Внутри списка мы добавляем элементы &lt;li&gt; через цикл @foreach. В нём мы проходим по всем нашим играм и выводим для каждой игры результат, ход игрока и компьютера.</p>
136 <p>Сохраним файлы и перезапустим сервер:</p>
136 <p>Сохраним файлы и перезапустим сервер:</p>
137 <em>Скриншот: Skillbox Media</em><p>Ура! У нас выводятся результаты завершённых игр, а новые игры успешно сохраняются.</p>
137 <em>Скриншот: Skillbox Media</em><p>Ура! У нас выводятся результаты завершённых игр, а новые игры успешно сохраняются.</p>
138 <p>Осталось немного украсить сайт с помощью CSS, а затем насладиться его красотой.</p>
138 <p>Осталось немного украсить сайт с помощью CSS, а затем насладиться его красотой.</p>
139 <p>Откроем папку public и создадим файл styles.css. Добавим в него следующий код:</p>
139 <p>Откроем папку public и создадим файл styles.css. Добавим в него следующий код:</p>
140 body { font-family: Arial, sans-serif; background-color: #f5f5f5; } h1 { text-align: center; margin-top: 50px; } form { display: flex; flex-direction: column; align-items: center; margin-top: 30px; } label { margin-right: 70px; margin-top: 20px; font-size: 20px; } input[type="radio"] { margin-left: 10px; padding-bottom: 50px; } button[type="submit"] { margin-top: 20px; background-color: #008CBA; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } button[type="submit"]:hover { background-color: #006B9F; } p { text-align: center; margin-top: 20px; font-size: 24px; font-weight: bold; } ul { list-style-type: none; } li { background: #dadada; }<p>Здесь мы немного причесали все элементы страницы, чтобы они отображались чуть симпатичнее. Например, в теге body мы задали шрифт и цвет фона, а для всех параграфов p задали размер шрифта, сделали его жирным и выровняли текст по центру.</p>
140 body { font-family: Arial, sans-serif; background-color: #f5f5f5; } h1 { text-align: center; margin-top: 50px; } form { display: flex; flex-direction: column; align-items: center; margin-top: 30px; } label { margin-right: 70px; margin-top: 20px; font-size: 20px; } input[type="radio"] { margin-left: 10px; padding-bottom: 50px; } button[type="submit"] { margin-top: 20px; background-color: #008CBA; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } button[type="submit"]:hover { background-color: #006B9F; } p { text-align: center; margin-top: 20px; font-size: 24px; font-weight: bold; } ul { list-style-type: none; } li { background: #dadada; }<p>Здесь мы немного причесали все элементы страницы, чтобы они отображались чуть симпатичнее. Например, в теге body мы задали шрифт и цвет фона, а для всех параграфов p задали размер шрифта, сделали его жирным и выровняли текст по центру.</p>
141 <p>Теперь сохраним CSS-файл и откроем файл game.blade.php, чтобы подключить в него новые стили:</p>
141 <p>Теперь сохраним CSS-файл и откроем файл game.blade.php, чтобы подключить в него новые стили:</p>
142 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Rock Paper Scissors&lt;/title&gt; &lt;link rel="stylesheet" href="{{ asset('styles.css') }}"&gt; &lt;/head&gt; &lt;body&gt; ... &lt;/body&gt; &lt;/html&gt;<p>Получилось примерно так:</p>
142 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Rock Paper Scissors&lt;/title&gt; &lt;link rel="stylesheet" href="{{ asset('styles.css') }}"&gt; &lt;/head&gt; &lt;body&gt; ... &lt;/body&gt; &lt;/html&gt;<p>Получилось примерно так:</p>
143 <em>Скриншот: Skillbox Media</em><p>Не лучший дизайн, но концепцию вы, надеюсь, поняли. Можете попробовать самостоятельно довести стили до совершенства и отправить игру на какую-нибудь премию в области веб-дизайна.</p>
143 <em>Скриншот: Skillbox Media</em><p>Не лучший дизайн, но концепцию вы, надеюсь, поняли. Можете попробовать самостоятельно довести стили до совершенства и отправить игру на какую-нибудь премию в области веб-дизайна.</p>
144 <p>А вот и полный код всех файлов, которые мы создавали:</p>
144 <p>А вот и полный код всех файлов, которые мы создавали:</p>
145 <p><strong>web.php:</strong></p>
145 <p><strong>web.php:</strong></p>
146 &lt;?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Route; Route::get('/', [GameController::class, 'index'])-&gt;name('game.index'); Route::post('/play', [GameController::class, 'play'])-&gt;name('game.play');<p><strong>GameController.php:</strong></p>
146 &lt;?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Route; Route::get('/', [GameController::class, 'index'])-&gt;name('game.index'); Route::post('/play', [GameController::class, 'play'])-&gt;name('game.play');<p><strong>GameController.php:</strong></p>
147 &lt;?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class GameController extends Controller { public function index() { $last_games = DB::table('game_statistics') -&gt;orderBy('created_at', 'desc') -&gt;limit(10) -&gt;get(); return view('game', ['last_games' =&gt; $last_games]); } public function play(Request $request) { $last_games = DB::table('game_statistics') -&gt;orderBy('created_at', 'desc') -&gt;limit(10) -&gt;get(); $playerChoice = $request-&gt;input('choice'); // Генерируем случайный ход для компьютера $computerChoice = rand(1, 3); if ($computerChoice == 1) { $computerChoice = 'rock'; } elseif ($computerChoice == 2) { $computerChoice = 'paper'; } else { $computerChoice = 'scissors'; } // Получаем результат игры if ($playerChoice == $computerChoice) { $result = 'tie'; } elseif (($playerChoice == 'rock' &amp;&amp; $computerChoice == 'scissors') || ($playerChoice == 'paper' &amp;&amp; $computerChoice == 'rock') || ($playerChoice == 'scissors' &amp;&amp; $computerChoice == 'paper')) { $result = 'win'; } else { $result = 'lose'; } // Сохраняем статистику в базу данных DB::table('game_statistics')-&gt;insert([ 'player_name' =&gt; 'Player 1', 'computer_choice' =&gt; $computerChoice, 'player_choice' =&gt; $playerChoice, 'result' =&gt; $result, 'created_at' =&gt; now(), 'updated_at' =&gt; now(), ]); // Возвращаем результат игры в представление return view('game', ['result' =&gt; $result, 'player_choice' =&gt; $playerChoice, 'computer_choice' =&gt; $computerChoice, 'last_games' =&gt; $last_games]); } }<p><strong>game.blade.php:</strong></p>
147 &lt;?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class GameController extends Controller { public function index() { $last_games = DB::table('game_statistics') -&gt;orderBy('created_at', 'desc') -&gt;limit(10) -&gt;get(); return view('game', ['last_games' =&gt; $last_games]); } public function play(Request $request) { $last_games = DB::table('game_statistics') -&gt;orderBy('created_at', 'desc') -&gt;limit(10) -&gt;get(); $playerChoice = $request-&gt;input('choice'); // Генерируем случайный ход для компьютера $computerChoice = rand(1, 3); if ($computerChoice == 1) { $computerChoice = 'rock'; } elseif ($computerChoice == 2) { $computerChoice = 'paper'; } else { $computerChoice = 'scissors'; } // Получаем результат игры if ($playerChoice == $computerChoice) { $result = 'tie'; } elseif (($playerChoice == 'rock' &amp;&amp; $computerChoice == 'scissors') || ($playerChoice == 'paper' &amp;&amp; $computerChoice == 'rock') || ($playerChoice == 'scissors' &amp;&amp; $computerChoice == 'paper')) { $result = 'win'; } else { $result = 'lose'; } // Сохраняем статистику в базу данных DB::table('game_statistics')-&gt;insert([ 'player_name' =&gt; 'Player 1', 'computer_choice' =&gt; $computerChoice, 'player_choice' =&gt; $playerChoice, 'result' =&gt; $result, 'created_at' =&gt; now(), 'updated_at' =&gt; now(), ]); // Возвращаем результат игры в представление return view('game', ['result' =&gt; $result, 'player_choice' =&gt; $playerChoice, 'computer_choice' =&gt; $computerChoice, 'last_games' =&gt; $last_games]); } }<p><strong>game.blade.php:</strong></p>
148 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Rock Paper Scissors&lt;/title&gt; &lt;link rel="stylesheet" href="{{ asset('styles.css') }}"&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;Rock Paper Scissors&lt;/h1&gt; @if(isset($result)) &lt;p&gt;You played {{ $player_choice }}&lt;/p&gt; &lt;p&gt;Computer played {{ $computer_choice }}&lt;/p&gt; &lt;p&gt;You {{ $result }}!&lt;/p&gt; @endif &lt;form method="POST" action="{{ route('game.play') }}"&gt; @csrf &lt;label for="rock"&gt;Rock&lt;/label&gt; &lt;input type="radio" name="choice" id="rock" value="rock"&gt; &lt;label for="paper"&gt;Paper&lt;/label&gt; &lt;input type="radio" name="choice" id="paper" value="paper"&gt; &lt;label for="scissors"&gt;Scissors&lt;/label&gt; &lt;input type="radio" name="choice" id="scissors" value="scissors"&gt; &lt;button type="submit"&gt;Play&lt;/button&gt; &lt;/form&gt; &lt;ul&gt; @foreach ($last_games as $last_game) &lt;li&gt; &lt;p&gt;You {{ $last_game-&gt;result }}&lt;/p&gt; &lt;p&gt;You played {{ $last_game-&gt;player_choice }}&lt;/p&gt; &lt;p&gt;Computer played {{ $last_game-&gt;computer_choice }}&lt;/p&gt; &lt;/li&gt; @endforeach &lt;/ul&gt; &lt;/body&gt; &lt;/html&gt;<p><strong>styles.css:</strong></p>
148 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Rock Paper Scissors&lt;/title&gt; &lt;link rel="stylesheet" href="{{ asset('styles.css') }}"&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;Rock Paper Scissors&lt;/h1&gt; @if(isset($result)) &lt;p&gt;You played {{ $player_choice }}&lt;/p&gt; &lt;p&gt;Computer played {{ $computer_choice }}&lt;/p&gt; &lt;p&gt;You {{ $result }}!&lt;/p&gt; @endif &lt;form method="POST" action="{{ route('game.play') }}"&gt; @csrf &lt;label for="rock"&gt;Rock&lt;/label&gt; &lt;input type="radio" name="choice" id="rock" value="rock"&gt; &lt;label for="paper"&gt;Paper&lt;/label&gt; &lt;input type="radio" name="choice" id="paper" value="paper"&gt; &lt;label for="scissors"&gt;Scissors&lt;/label&gt; &lt;input type="radio" name="choice" id="scissors" value="scissors"&gt; &lt;button type="submit"&gt;Play&lt;/button&gt; &lt;/form&gt; &lt;ul&gt; @foreach ($last_games as $last_game) &lt;li&gt; &lt;p&gt;You {{ $last_game-&gt;result }}&lt;/p&gt; &lt;p&gt;You played {{ $last_game-&gt;player_choice }}&lt;/p&gt; &lt;p&gt;Computer played {{ $last_game-&gt;computer_choice }}&lt;/p&gt; &lt;/li&gt; @endforeach &lt;/ul&gt; &lt;/body&gt; &lt;/html&gt;<p><strong>styles.css:</strong></p>
149 body { font-family: Arial, sans-serif; background-color: #f5f5f5; } h1 { text-align: center; margin-top: 50px; } form { display: flex; flex-direction: column; align-items: center; margin-top: 30px; } label { margin-right: 70px; margin-top: 20px; font-size: 20px; } input[type="radio"] { margin-left: 10px; padding-bottom: 50px; } button[type="submit"] { margin-top: 20px; background-color: #008CBA; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } button[type="submit"]:hover { background-color: #006B9F; } p { text-align: center; margin-top: 20px; font-size: 24px; font-weight: bold; } ul { list-style-type: none; } li { background: #dadada; }<p><strong>_create_game_statistics_table.php:</strong></p>
149 body { font-family: Arial, sans-serif; background-color: #f5f5f5; } h1 { text-align: center; margin-top: 50px; } form { display: flex; flex-direction: column; align-items: center; margin-top: 30px; } label { margin-right: 70px; margin-top: 20px; font-size: 20px; } input[type="radio"] { margin-left: 10px; padding-bottom: 50px; } button[type="submit"] { margin-top: 20px; background-color: #008CBA; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } button[type="submit"]:hover { background-color: #006B9F; } p { text-align: center; margin-top: 20px; font-size: 24px; font-weight: bold; } ul { list-style-type: none; } li { background: #dadada; }<p><strong>_create_game_statistics_table.php:</strong></p>
150 &lt;?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::create('game_statistics', function (Blueprint $table) { $table-&gt;id(); $table-&gt;string('player_name'); $table-&gt;string('computer_choice'); $table-&gt;string('player_choice'); $table-&gt;string('result'); $table-&gt;timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('game_statistics'); } };<p>Мы узнали, что Laravel - это мощный и довольно простой фреймворк для создания веб-приложений. Освоить его можно за пару месяцев, а начать писать на нём - уже сегодня.</p>
150 &lt;?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::create('game_statistics', function (Blueprint $table) { $table-&gt;id(); $table-&gt;string('player_name'); $table-&gt;string('computer_choice'); $table-&gt;string('player_choice'); $table-&gt;string('result'); $table-&gt;timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('game_statistics'); } };<p>Мы узнали, что Laravel - это мощный и довольно простой фреймворк для создания веб-приложений. Освоить его можно за пару месяцев, а начать писать на нём - уже сегодня.</p>
151 <p>Чтобы лучше понять Laravel, советуем написать собственное приложение или попробовать доработать наше, например:</p>
151 <p>Чтобы лучше понять Laravel, советуем написать собственное приложение или попробовать доработать наше, например:</p>
152 <ul><li><a>добавить авторизацию</a>;</li>
152 <ul><li><a>добавить авторизацию</a>;</li>
153 <li><a>протестировать приложение</a>;</li>
153 <li><a>протестировать приложение</a>;</li>
154 - <li><a>встрить ORM</a>.</li>
154 + <li><a>встроить ORM</a>.</li>
155 </ul><p>Читайте<a>документацию</a>и набирайтесь опыта. Успехов!</p>
155 </ul><p>Читайте<a>документацию</a>и набирайтесь опыта. Успехов!</p>