В этом руководстве мы собираемся создать и запустить простое приложение CRUD с нуля, используя Laravel 5.
Установка и настройка
Если вы уже глубоко разбираетесь в PHP, то некоторые вещи из этого раздела станут для вас общеизвестными. В любом случае, давайте пройдемся по этому. Мы создаем новую версию Laravel 5 с помощью Composer. Сначала cd
в выбранный вами каталог. Теперь запустите следующую команду:
composer create-project laravel/laravel MYPROJECT
Если у вас не установлен Composer, вам, естественно , сначала нужно это сделать , но я рекомендую использовать среду, такую как Homestead Improved, для запуска процесса разработки в любом случае — он поставляется с Composer, предварительно установленным глобально.
Имя «MYPROJECT» будет именем вашего каталога приложений. Для этого урока я просто назвал мой «crud».
Первый запуск и настройка базы данных
Давайте разберем базу данных.
Если вы не знакомы с файлами окружения, я предлагаю вам прочитать их здесь . Это поможет вам в будущем, когда вы будете готовы выпустить приложение производственного уровня, которое требует более мощной базы данных. Пока же мы будем использовать SQLite — механизм баз данных с нулевой конфигурацией на основе файлов. Из коробки не нужно ничего настраивать, что облегчает тестирование таких приложений, как это.
Перейдите в каталог config
и откройте файл database.php
. Измените настройку подключения к базе данных по умолчанию на sqlite
, и мы почти готовы к рок-н-роллу. Прокрутите немного вниз в этом файле, и вы увидите фактические соединения с базой данных. Вы заметите, что SQLite использует файл database.sqlite
который хранится в корневом каталоге storage
(доступно для storage_path()
). У нас пока нет этого файла, поэтому давайте быстро создадим его в командной строке:
touch storage/database.sqlite
Убедитесь, что папка хранения доступна для записи веб-сервером. Если вы используете нашу коробку Homestead Improved , об этом позаботятся за вас.
Наша база данных настроена, и мы готовы запустить некоторые операции CRUD. Но сначала давайте взглянем на маршрутизацию в Laravel, а также на некоторый синтаксис Blade и настройку базового шаблона.
Краткое примечание по Artisan CLI
Artisan — это встроенный интерфейс командной строки Laravel. Это позволяет нам очень хорошо взаимодействовать с нашим приложением во время разработки. Он поставляется с множеством команд, которые позволяют нам создавать модели, контроллеры, переносить базы данных и даже выполнять ручные операции CRUD. Чтобы увидеть список команд, запустите php artisan
в командной строке. С этого момента я буду довольно часто использовать команду artisan
, так что читайте документы, чтобы ознакомиться с ними.
Находчивая маршрутизация
Внутри каталога app/Http
вы найдете там файл с именем routes.php
. Файл маршрутов определяет большинство маршрутов в вашем приложении. По умолчанию некоторые маршруты уже определены. Давайте удалим их все и начнем с нуля. Для этого урока давайте запустим наши операции CRUD в простом списке задач. Нам понадобятся два основных маршрута для нашего приложения:
- Маршрут домашней страницы — тот, который просто отображает общую домашнюю страницу
- Наш маршрут задачи, который будет основой для структуры RESTful для операций CRUD, которые будут выполнены.
На этом этапе я предлагаю вам ознакомиться с маршрутизацией в Laravel 5. Я буду использовать именованные маршруты , а также действия контроллера для управления выводом. Для нашей домашней страницы мы просто используем базовый маршрут GET:
Route::get('/', [ 'as' => 'home', 'uses' => 'PagesController@home' ]);
Обратите внимание, что я использую PagesController
которого у нас еще нет. Не волнуйтесь, мы скоро создадим это, используя artisan
. Прежде чем мы продолжим, пришло время ознакомиться с контроллерами ресурсов RESTful и их безболезненным генерированием через интерфейс командной строки artisan
. Мы можем зарегистрировать ресурсный маршрут к контроллеру следующим образом:
Route::resource('tasks', 'TasksController');
По словам Ларавела:
Это объявление одного маршрута создает несколько маршрутов для обработки различных действий RESTful с ресурсом.
Имея все это в виду, теперь мы можем создать два наших контроллера через командную строку:
php artisan make:controller PagesController php artisan make:controller TasksController
Давайте сначала откроем PagesController
. Перейдите в app/Http/Controllers/PagesController
и посмотрите на файл. Вы заметите, что artisan
создал для нас кучу методов, которые были бы полезны для действий RESTful. Мы сохраним их для нашего TasksController
, но для нашего PagesController
нам понадобится только один метод — home
. Удалите все методы и создайте домашний метод:
public function home() { return 'Welcome home!'; }
Обновите домашнюю страницу в вашем браузере, и мы дома! К настоящему времени вы, вероятно, взволнованы, чтобы заняться хорошими вещами, но давайте сначала поговорим о представлениях, добавим пару ресурсов и создадим базовый шаблон, чтобы наше приложение выглядело симпатично.
Вкратце, если вы хотите создать контроллер с помощью ремесленного интерфейса командной строки и хотите, чтобы у него не было методов по умолчанию, вы можете добавить в команду флаг --plain
например:
php artisan make:controller YourController --plain
Хорошо, двигаясь дальше.
Виды и основные шаблоны с лезвием
Пока что мы настроили несколько маршрутов и вернули бессмысленную строку на экран. Это не так много, но это начало. Вместо того чтобы возвращать строку, давайте вернем представление. Представления служат интерфейсом вашего приложения. Думайте о них как о чисто презентационных. Мы хотим, чтобы наши представления только когда-либо обслуживали данные, которые уже были переданы им, и мы увидим, как передать данные в представление чуть позже. Внутри каталога /resources
вы увидите каталог под названием «views». Здесь мы сохраняем наши взгляды, а также здесь мы можем ссылаться на них. Давайте сделаем пару вещей здесь:
- Давайте создадим подкаталог с именем
pages
, и в нем создадим новый файл с именемhome.blade.php
. - Давайте создадим еще один подкаталог с названием
layouts
и в нем создадим новый файл с именемmaster.blade.php
.
Как и следовало ожидать, мы хотим иметь какой-то мастер-макет, чтобы нам не пришлось повторять большие фрагменты HTML. Различные страницы в нашем приложении будут ссылаться на основной макет и вставлять контент в отдельные разделы. Мы добавим загрузчик для удобства CSS и нарисуем основной файл HTML:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Tasks</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> </head> <body> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="#">Tasks</a> </div> <div class="nav navbar-nav navbar-right"> <li><a href="#">Home</a></li> <li><a href="#">Tasks</a></li> </div> </div> </nav> <main> <div class="container"> @yield('content') </div> </main> </body> </html>
В частности, обратите внимание на часть @yield('content')
этого файла. Это позволит нам ссылаться на раздел контента на страницах любого шаблона и вставлять туда любой контент, который вы хотите. В нашем файле home.blade.php
у нас теперь может быть что-то вроде этого:
@extends('layouts.master') @section('content') <h1>Welcome Home</h1> <p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maiores, possimus, ullam? Deleniti dicta eaque facere, facilis in inventore mollitia officiis porro totam voluptatibus! Adipisci autem cumque enim explicabo, iusto sequi.</p> <hr> <a href="{{ route('tasks.index') }}" class="btn btn-info">View Tasks</a> <a href="{{ route('tasks.create') }}" class="btn btn-primary">Add New Task</a> @stop
Мы расширяем мастер-макет и вставляем в раздел контента . Как вы можете видеть, синтаксис лезвия делает это легким делом. Мы собираемся двигаться дальше, но вы можете прочитать больше о синтаксисе блейдов и шаблонах здесь .
Вернувшись в наш PagesController
, мы теперь можем вернуть представление на домашнюю страницу. Если вы прочтете документацию по представлениям, вы поймете, что это так просто:
public function home() { return view('pages.home'); }
Обновите свой браузер, и все!
Теперь TasksController
к нашему TasksController
. На этот раз мы сохраним методы, которые были автоматически сгенерированы с помощью командной строки artisan
, и вот почему:
- Они уже названы в RESTful для нас.
- Маршруты уже связаны с соответствующими методами из-за изобретательной маршрутизации Laravel.
Если мы перейдем к /tasks
, мы увидим пустую страницу. Это потому, что наше приложение использует метод index
, и у нас пока ничего нет. Простым логическим выводом мы можем выяснить, за что должен отвечать каждый из других методов, чтобы соответствовать структуре RESTful:
-
create
будет метод, который мы используем для создания страницы, где мы можем создавать новые задачи -
store
— это метод, который мы используем для обработки POST-данных при создании задачи и сохранения их в базе данных. -
show
будет метод, используемый для показа одной задачи -
edit
будет метод, который позволяет нам редактировать существующую задачу -
update
будет вызывать метод обновления существующей задачи. -
destroy
будет метод, используемый для уничтожения или удаления задачи
А сейчас давайте сосредоточимся на нашем методе index
. В каталоге views я собираюсь создать новый файл в tasks/index.blade.php
и вытащить макет, как в прошлый раз. Вот шаблон, который у меня есть:
@extends('layouts.master') @section('content') <h1>Task List</h1> <p class="lead">Here's a list of all your tasks. <a href="/tasks/create">Add a new one?</a></p> <hr> @stop
Вот скриншот прогресса.
Сейчас я хочу, чтобы вы заметили, что я жестко запрограммировал ссылку для создания задачи. Если вы читали ссылки на документацию, о которых я упоминал ранее, вы уже знакомы с именованными маршрутами. Ресурсная маршрутизация автоматически называет наши маршруты для нас, и вы можете увидеть их все в командной строке artisan
:
php artisan route:list
Теперь мы можем ссылаться на маршрут создания в наших шаблонах блэйдов следующим образом:
<a href="{{ route('tasks.create') }}">Add a new one?</a>
Давайте также обновим нашу навигацию, чтобы мы могли легко нажимать:
<nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="{{ route('home') }}">Tasks</a> </div> <div class="nav navbar-nav navbar-right"> <li><a href="{{ route('home') }}">Home</a></li> <li><a href="{{ route('tasks.index') }}">Tasks</a></li> </div> </div> </nav>
Хорошо, наше приложение собирается вместе. Мы готовы начать добавление задач и создание нашего метода и представления create
, но мы еще не дошли до конца. Мы хотим, чтобы наши задачи сохранялись в базе данных, но мы еще не создали таблицу. К счастью, Laravel упрощает создание и обслуживание таблиц. Давайте копаться в.
Миграция базы данных
Давайте перейдем к документации по миграции и прочитаем ее.
Миграции — это тип контроля версий для вашей базы данных. Они позволяют команде изменять схему базы данных и оставаться в курсе текущего состояния схемы.
Создание миграции легко с artisan
. Вот что мы сделаем, чтобы создать нашу таблицу миграции задач:
php artisan make:migration create_tasks_table
Есть две дополнительные опции, которые мы можем использовать в нашей команде миграции:
-
--create
—--create
ремесленнику, что мы хотим, чтобы наша миграция фактически создала таблицу -
--table
— позволяет ремесленнику знать, к какой таблице мы хотим--table
нашу миграцию
В нашем случае мы создаем таблицу в первый раз, поэтому наша команда должна выглядеть так:
php artisan make:migration create_tasks_table --create=tasks
Перейдите к новой сгенерированной миграции — она будет в каталоге /database/migrations
. Выполнение команды migrate
заставит Laravel заглянуть в этот каталог и проследить любые миграции баз данных, которые еще не произошли. Каждая миграция имеет две функции:
-
up
— запускается при вызове команды migrate -
down
— запускается при откате миграции
В нашем случае наша функция up
создаст таблицу задач с необходимыми полями, а команда down
удалит ее. Мы, вероятно, захотим, чтобы наши задачи тоже имели заголовок и описание, поэтому давайте добавим их. Вот как должна выглядеть наша функция up
:
public function up() { Schema::create('tasks', function(Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('description'); $table->timestamps(); }); }
Теперь давайте запустим нашу миграцию, чтобы настроить нашу базу данных:
php artisan migrate
Теперь у нас есть таблица задач. Мы используем SQLite, поэтому давайте убедимся в этом с помощью командной строки. Запустите следующие две команды:
sqlite3 storage/database.sqlite .tables
Первый запускает интерфейс командной строки SQLite, а второй выводит наши таблицы. Если ваша миграция прошла успешно, вы должны увидеть список tasks
. Теперь мы готовы выполнить наши операции CRUD.
Модели и красноречивые ORM
Теперь, когда наша база данных настроена, пришло время поговорить об Eloquent Models и Eloquent ORM от Laravel. Перейдите к документации и, в частности, обратите внимание на это:
Eloquent ORM, включенный в Laravel, обеспечивает красивую и простую реализацию ActiveRecord для работы с вашей базой данных. Каждая таблица базы данных имеет соответствующую «Модель», которая используется для взаимодействия с этой таблицей.
По сути, представьте модель как представление таблицы базы данных, с помощью которой мы можем выполнять операции с базой данных. Давайте создадим нашу модель задач:
php artisan make:model Task
По умолчанию нам не нужно указывать, с какой таблицей мы хотим взаимодействовать. Laravel прочитает Task
и автоматически загрузит таблицу tasks
. Чтобы использовать пользовательскую таблицу, просто укажите ее в классе Model следующим образом:
protected $table = 'custom_tasks';
Теперь, ссылаясь на модель внутри нашего контроллера, мы можем использовать Eloquent для взаимодействия с базой данных.
Вывод
В этой части мы загрузили наше приложение Laravel CRUD, создав базу данных, некоторые контроллеры, базовые маршруты и простые представления. Во второй части мы реализуем все функции CRUD, для которых мы подготовили основы в этом посте.