•   Новости. Советы. Уроки.
Блог / Советы и уроки / Первое приложение на Laravel. Пошаговое руководство (Часть 1)

Первое приложение на Laravel. Пошаговое руководство (Часть 1)

Eric L. Barnes
Виталий Николенко
07.03.2016

Cо дня своего релиза в 2011 популярность фреймворка Laravel выросла на порядок. В 2015 году он стал самым популярным (starred) PHP фреймворком на GitHub. Сегодня Laravel выбирают в качестве основного инструмента разработчики по всему миру.

Laravel сфокусирован на вас, конечных пользователях, что в первую очередь означает нацеленность на простоту, ясность и результат. Крупные компании и разработчики-одиночки используют его для проектов любого рода: от хобби до корпоративных порталов крупнейших компаний мира.

Цель этой статьи - создать руководство для тех, кто только начал изучать Laravel. Начать с идеи и построить реальное приложение.

Это не полное руководство по фреймворку, мы не охватим все детали Laravel и для начала необходимо выполнить ряд условий. Вот, что потребуется:

  • Локальная PHP среда (Homestead, Vagrant, MAMP и т.д.)
  • База данных. Я буду использовать MySQL.
  • PHPUnit
  • Node.js

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

Планирование

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

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

В качестве проекта для этого руководства мы будем делать каталог ссылок. Вот список основных целей для этого приложения:

  • Показать простой список ссылок
  • Создать форму для добавления новых ссылок
  • Проверить данные формы
  • Вставить данные в базу данных.

Давайте начнем.

Первые шаги

Пришло время ринуться в бой и развернуть пустой проект. Я люблю хранить все свои рабочие проекты в директории ~ /Code и везде далее буду использовать этот путь. Вы можете изменить его на более привычный вам.

Откройте терминал и создайте новый каталог для кода проекта.

cd ~/Code
mkdir links
cd links

Затем установите программу установки Laravel :

composer global require "laravel/installer"

После завершения процесса , можно создать новый проект, выполнив:

laravel new links

Эта команда создаст новый каталог и установит пустой проект Laravel.

Теперь нужно создать виртуальный хост, ссылающийся на ~/Code/links/public, чтобы можно было загрузить сайт в браузере. В качестве домена я использовал links.dev.

Если все работает, вы должны увидеть страницу-заглушку Laravel:

Теперь сгенерируем систему аутентификации использую следующую команду:

php artisan make:auth

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

Создаем список ссылок

Если держать в голове весь проект можно сойти с ума. Лучше разбить все на более мелкие задачи. Так что давайте начнем со списка ссылок.

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

Первым шагом будет создание миграции. В этом нам поможет консольный инструмент artisan.

php artisan make:migration create_links_table --create=links

Теперь откройте файл, который создала команда. Он находится по следующему пути database/migrations/{{ДатаВремя}}_create_links_table.php

Внутри метода up добавьте столбцы таблицы

Schema::create('links', function (Blueprint $table) {
      $table->increments('id');
      $table->string('title');
      $table->string('url’)->unique();
      $table->text('description');
      $table->timestamps();
});

Сохраните файл и запустите миграцию

php artisan migrate

Теперь надо добавить данные. В Laravel для этой цели есть две функции: заполнение начальными данными (seeding) и фабрики моделей.

Перед тем как продолжить процесс, самое время написать первый юнит-тест. Я предпочитаю делить тесты на две категории: функционал (features) и юниты (unit). Этот тест будет юнит-тестом, поэтому создаем файл ./tests/unit/SeederTest.php и добавляем тестирующий метод :

public function testLinksTable()
{
  $this->seeInDatabase('links', ['title' => 'dotdev.co']);
}

Этот метод должен выдать ошибку. Запускаем - так и есть

… matches PCRE pattern "/dotdev.co/i" …

Стоп, мы не это вообще-то тестируем. При установке в Laravel уже есть один тестовый файл ExampleTest.php . Удалите его и запустите phpunit снова.

Теперь мы видим нашу настоящую ошибку

There was 1 failure:

1) SeederTest::testLinksTable Unable to find row in database table [links] that matched attributes [{"ti-tle":"dotdev.co"}]. Failed asserting that 0 is greater than 0.

Для того, чтобы этот тест прошел удачно, необходимо создать файл, заполняющий базу данных.

php artisan make:seeder LinksTableSeeder

Откройте DatabaseSeeder.php и добавьте следующее в метод run:

$this->call(LinksTableSeeder::class);

Чтобы тест прошел удачно мы могли бы просто добавить новую запись в LinksTableSeeder. Но, мы создадим фабрику модели сейчас, чтобы сэкономить время будущем, тк наши будущие тесты будут на нее завязаны. До того как создать фабрику, необходимо добавить саму модель.

php artisan make:model Link

Отредактируем созданную модель app/Link.php добавив имя таблицы в бд:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Link extends Model
{
    protected $table = 'links';
}

Теперь вернемся к ModelFactory.php и добавим наши ссылки:

$factory->define(App\Link::class, function (Faker\Generator $faker) {
    return [
        'title' => $faker->name,
        'url' => $faker->url,
        'description' => $faker->paragraph,
    ];
});

Если мы снова запустим сейчас phpunit, ошибка все еще будет, т.к. ссылки с названием “dotdev.co” в базе еще нет. В нашем SeederTest мы можем создать эту запись в бд с помощью той же фабрики моделей:

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class SeederTest extends TestCase
{
    public function testLinksTable()
    {
        factory(App\Link::class)->create([
            'title' => 'dotdev.co',
        ]);
        $this->seeInDatabase('links', ['title' => 'dotdev.co']);
    }
}

Теперь, если выполнить phpunit все должно завершиться успешно.

Следующий шаг – собственно вывод самого списка ссылок. И само время написать новый тест.

Создаем новый файл ./tests/features/LinkTest.php. Спросим себя: что мы ожидаем увидеть? На странице списка ссылок мы можем найти известную нам ссылку, как мы делали выше, и подтвердить, что мы реально ее видим. Вот код такой проверки:

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class LinkTest extends TestCase
{
    public function testWeSeeAListOfLinks()
    {
        factory(App\Link::class)->create([
            'title' => 'dotdev.co',
        ]);
        $this->visit('/')
             ->see('dotdev.co');
    }
}

Phpunit снова выдает ошибку, что искомая строка не найдена. Откроем карту машрутов ./app/Http/routes.php и посмотрим куда указывает маршрут «/» .

Route::get('/', function () {
    return view('welcome');
});

Давайте сделаем выборку наших ссылок и отправим их в представление.

Route::get('/', function () {
    $links = \App\Link::all();
    return view('welcome', compact('links'));
});

Отредактируем welcome.blade.php добавив простой цикл foreach:

@foreach ($links as $link) 
  <li>{{ $link->title }}</li>
@endforeach

Теперь phpunit позеленел. Тесты прошли успешно.

Мои поздравления! Первая функция реализована и покрыта тестами. Ничего не ломайте ;)

Продолжение