FullStack Web Developer
0,0
рейтинг
24 сентября 2014 в 18:52

Разработка → Что нового в Laravel 5? из песочницы



Несколько месяцев назад в студии, где я работаю, было принято решение всей командой перебраться на Laravel. Последние пару лет популярность этого фреймворка неустанно росла, и, как оказалось, не напрасно!

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

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

Мне всегда казалось, что те же самые задачи можно решать более просто и элегантно. Хотелось найти фреймворк, на котором мне бы нравилось писать. Который я смог бы выучить как свои пять пальцев и заниматься тем, чем мне и нравится заниматься – программированием, созданием чего-то нового. Я думаю, у каждого плотника есть любимый молоток, и такое желание для программиста вполне естественно. Кто из нас, тех кто пишет на php, не поглядывал с завистью на Rails в Ruby или Django в Python?

Последней каплей стал пост от JetBrains о расширенной поддержке в новой версии PhpStorm 8 шаблонов Blade и Source & Test directories. В этой IDE мы и создали первый проект на Laravel.

Поработав с Laravel, я понял, что нашел то, что искал. Наверное, именно поэтому символом Laravel стал слоган «You have arrived».

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

Но моя статья не об этом. О плюсах Laravel написано уже достаточно.

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

Изначально версия должна была называться 4.3, но новая структура директорий и некоторые существенные изменения в коде подтолкнули создателей к решению анонсировать версию 5.0.

Насколько серьезными были эти изменения судить вам. Итак, давайте на деле разберемся, что нам готовит Laravel 5.

Установка


Установка новой версии по сути ничем не отличается от старой. Для начала скачайте Laravel 5, добавив в файл composer.json строку

"require": {
    //...
    "laravel/framework": "5.0.*@dev"
    //...
}


После этого запустите composer update, и по окончании операции у вас будет установлена последняя версия.



Структура


Если посмотреть на структуру Laravel 4 и Laravel 5 то сразу можно заметить разницу. Прежде всего, папки Config, Tests, Storage и Database были вынесены из папки App в корень. Появилась новая директория resources.



Возникает логичный вопрос: а что осталось в папке App?

Теперь в папке App хранится только логика самого приложения. Таким образом разработчики узаконили то, что и так делали большинство разработчиков на Laravel до этого — удалили папку model и создали отдельную директорию для всего, что связано с разработкой этого конкретного проекта — модели, команды, события и тому подобное. Прежде всего, это позволяет четко провести границу между кодом самого фреймворка и кодом, который пишет сам разработчик.

В папке App по умолчанию находится 3 новые директории. Директория Console предназначена для классов консольных команд, папка Service Providers содержит классы-поставщики услуг, папка Http содержит контроллеры, фильтры и все, что связано с роутингом.



В свою очередь, в директории Http лежит 3 папки — Controllers для контроллеров приложения, Filters для фильтров маршрутов, которые теперь создаются в виде отдельных классов, и папки Requests, о которой я подробно расскажу ниже.
Папка View была перенесена в директорию Resources, вместе с папкой локализации Lang.
Кому-то новая структура может показаться непривычной, но по себе могу сказать, что уже через пару дней вы поймете, что так намного удобнее.

Первый вопрос, который вероятнее всего возникнет у вас в связи с изменением структуры: а что стало с пространствами имен и автозагрузкой классов?

Пространства имен

К моей огромной радости, Laravel 5 официально использует стандарт psr-4, а значит каждый класс в папке App, у которого будет правильно задано пространство имен будет доступен для автозагрузчика.
Поэтому просто убедитесь, что каждый класс в этой папке начинается с App\*название директории и навсегда забудьте о проблемах с загрузкой файлов.

С другой стороны, использование psr-4 означает, что доступ к фасадам теперь требует обращения из глобального пространства имен, например \Auth::*имя метода* или \Events::*имя метода*.
В связи с этим, фасады теперь необходимо импортировать командой use \имяфасада (например \View) в начале файла или обращаться к ним через обратный слэш.

Кроме этого, теперь необходимо указывать пространства имен для контроллеров. Поэтому удостоверьтесь, что каждый ваш контроллер содержит строку
namespace App\Http\Controllers;

и использует пространство имен абстрактного контроллера
use Illuminate\Routing\Controller;


Если вы используете BaseController как родительский класс всех ваших контроллеров, то вы можете вынести последнюю строчку туда, так все ваши контроллеры получат доступ к этому пространству имен.

Корневая папка приложения
Что если вы не хотите обращаться к основной папке вашего приложения как к App? Что если вы привыкли называть директорию, в которой хранится логика приложения, по названию самого приложения, как делали многие в Laravel 4?

Разработчики предусмотрели и это. Вам достаточно просто написать в командной строке $ php artisan app:name и желаемое имя вашего приложения. Laravel самостоятельно изменит пространства имен в необходимых файлах, а также настройки в файлах конфигурации.

Если вы хотите использовать вложенную директорию, то используйте два обратных слэша, например так
$ php artisan app:name MyAppName\\HabrProject


Кстати, в папке Config появился новый файл namespaces.php, в котором прописывается пространство имен для приложения в целом и пути к файлам. Пригодиться, если будут проблемы с автозагрузкой!

Внедрение параметров метода

Еще одним мощным нововведением Laravel 5 стало внедрение параметров метода (Method Parameter Injection или просто Method Injection).
Раньше, если в контроллере нам необходим был какой-то класс модели, например репозиторий, мы могли использовать Ioc Container Dependency Injection, то есть передать название класса в конструктор контроллера и присвоить его свойству объекта.
Ioc контейнер самостоятельно создавал экземпляр данного класса и возвращал в свойство контроллера, через который мы получали к нему доступ. И это было круто.

Например, так:

 class FeedController extends BaseController {
     protected $feedbackRepository;
     /**
      * @param FeedbackRepository $feedbackRepository
      */
    public function __construct(FeedbackRepository $feedbackRepository)
     {
         $this->feedbackRepository = $feedbackRepository;
     }
     public function index($id)
     {
         $feed = $this->feedbackRepository->getFeed($id);
         return View::make('feed.index', compact('feed'));
     }

Однако что если объект нужен нам только в одном методе? Зачем создавать в конструкторе целого контроллера экзмепляр объекта, если он будет использован только в одном его методе?
Поэтому в Laravel 5 появилось внедрение параметра метода!
Теперь в любом методе контроллера можно указать класс, и вы автоматически получите доступ к его методам через Ioc контейнер. Наш пример теперь выглядел бы так:

 class FeedController extends BaseController {
     public function index(FeedbackRepository $feedRepo, $id){
$feed = $feedRepo->getFeed($id);
Return view(‘feed.index’, compact(‘feed’)
}
}

И все! Волшебным образом Ioc контейнер сам найдет и подключит мой репозиторий.

Но настоящую мощь этого нововведения можно прочувствовать в совокупности с другой новой фичей:

Запросы (Requests) и запросы к форме (FormRequests)

Помните, я говорил про папку Requests в директории App\Http? Вот мы наконец и добрались до нее.
Давайте вспомним, как мы осуществляли проверку введенных пользователем данных при отправке формы в Laravel 4.2.

Если вы работали с Laravel, то вам безусловно знаком фасад Validator.
Он предоставляет мощный функционал валидации данных, полученных от пользователя. Однако каждый разработчик использовал его по-разному. Кто-то использовал валидатор прямо в контроллере,
кто-то прописывал правила валидации в модели (массив rules[]) и использовал метод isValid.

Теперь об этом можно забыть: Laravel предоставляет отдельный уровень абстракции для обработки запросов к форме.
Давайте разберемся, как это работает.
В командной строке наберите php artisan make:request MyRequest и фреймворк самостоятельно сгенерирует для вас шаблон запроса к форме.

В данном классе, который наследует класс FormRequest, содержится всего 2 метода: authorize и rules.
Rules возвращает массив, в котором вы можете прописать правила валидации для своей формы, совсем как в Laravel 4.
Метод authorize по умолчанию возвращает false.
Если сейчас мы попытаемся отправить форму, связанную с этим классом, в браузере мы получим страницу forbidden(запрещено).

Так вот, метод authorize проверяет, имеет ли право пользователь, обращающийся к форме, ее отправлять. Например имеет ли пользователь право редактировать статью, которую написал не он? Постить комментарий, если он не залогинен? Это именно то место, куда теперь нужно помещать проверки.

Предположим, у нас есть форма, которая публикует статус на стену пользователя. Мы хотим, чтобы поле статус (обычный input type ='text' name ='status') было обязательным для заполнения и содержало, скажем, 20 символов. Нам также нужно проверить, что пользователь публикует статус на свою стену, то есть id страницы пользователя совпадает с id автора поста.
В этом примере наш класс-валидатор выглядел бы так.

namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use \Auth;
class AddFeedRequest extends FormRequest {

    public function rules()
    {
        return [
            'status' => 'required|min:20',
        ];
    }

   public function authorize()
   {
        return Auth::id() == $this->route->parameter('id');
   }

Теперь с помощью внедрения параметра метода, о котором мы говорили выше, нам достаточно просто указать название класса в параметрах метода контроллера, ответственного за отправку формы.
Если мы используем REST контроллер, то это будет метод store.

 public function store(MyRequest $request)
     {
         //код отправляющий форму
     }

И все! Больше ничего делать не нужно! Laravel сам осуществит валидацию формы и выполнит код, содержащийся в методе контроллера, если валидация пройдет успешно. Еще раз: ни единая строчка кода из метода store не будет исполнена, если форма не проходит валидацию. На мой взгляд, это безумно круто!

Генераторы

Если мы наберем в командной строке php artisan мы увидим целый новый раздел, который называется make:
Мы уже воспользовались одним из них, для генерации класса myRequest. Кроме этого, команда make: поможет создать контроллер, консольную команду,
фильтр, миграцию, поставщика услуг.

Особенно хочу выделить команду php artisan make:auth. Этот генератор сделает за вас то, что вы делали снова и снова в каждом новом проекте — систему авторизации пользователя.

Если мы выполним ее сейчас, мы увидим, что Laravel создаст для нас два контроллера — один отвечающий за авторизацию, второй — за восстановление пароля, миграцию password resets, 2 класса-валидатора для запросов login и register. Всего одна команда и шаблон для авторизации готов!

Кэширование маршрутов

Команда routes тоже разрослась в целый раздел. Теперь чтобы посмотреть список маршрутов нужно ввести php artisan route:list.
Здесь же трудно не заметить новую команду route:cache. Она делает очень простую вещь — кэширует ваши маршруты.
Если выполнить эту команду, вы увидите, что в папке storage/meta появился файл routes.php. В нем содержится кэш ваших маршрутов. Теперь Laravel будет в первую очередь обращаться к нему, а не к основному файлу http/routes.php.

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

Контракты

Все компоненты Laravel 5 теперь реализуют тот или иной интерфейс из папки illuminate/contracts. Таким образом разработчики попытались сделать ваше приложение более гибким и менее зависимым от самого Laravel.

В Laravel 4 зачастую возникали проблемы с type-hinting-ом интерфейсов. Если вы указывали в параметрах метода экземпляр объекта, который должен реализовывать некий интерфейс, Ioc контейнер рассматривал его как dependency injection и пытался создать экземпляр класса, что приводило к ошибкам.

Чтобы решить эту проблему нужно было напрямую связывать интерфейс с конкретным классом-реализацией интерфейса с помощью app::bind. Однако это все равно вызывало некоторые проблемы, например при unit-тестировании.
В Laravel 5 достаточно использовать интерфейс в начале файла с помощью use (например use Illuminate\Contracts\Mailer) и type-hinting будет работать как надо.

Это позволяет писать более гибкие приложения, не привязываясь к конкретным классам-реализациям.

Что если в дальнейшем вы захотите подключить другой модуль авторизации, отличный от стандартного модуля Laravel? Другой модуль кэширования? Отправки писем? Просто убедитесь, что он реализует интерфейс из папки contracts и пишите код, опираясь на type-hinting интерфейсов.

Новые функции помощники

Мелочь, которую вы будете снова и снова использовать в своих проектах: подключение файлов представления теперь доступно через функцию view('имяпредставления'). Старый способ View::make тоже работает, но теперь к нему, как я уже сказал выше, нужно обращаться через обратный слэш.

Такая же участь постигла и Redirect::to – теперь можно просто писать redirect(‘маршрут’).

Из других изменений в привычных инструментах работы стоит упомянуть и то, что фасады HTML и Form теперь не входят в стандартный пакет Laravel. Не бойтесь, если вы к ним привыкли, вы без труда сможете подключить их через composer.

Socialite

В Laravel 5 появился собственный модуль Socialite Beta, который предназначен для аутентификации сторонних сервисов, таких как Twitter, Facebook, GitHub. Нам приходилось довольно часто дописывать плагины для авторизации под различные социальные сети и как было бы здорово, если бы в других фреймворках были подобные инструменты. Плагин является опциональным и для его добавления достаточно лишь подключить зависимость. Посудите сами, нужно всего лишь создать конфиг провайдера и после этого все необходимые методы будут доступны в виде:

$this->socialite->driver('twitter')->user();

Всё, что для этого нужно сделать, это подключить соответствующий класс в начале вашего файла:
use Laravel\Socialite\Contracts\Factory as SocialiteFactory;
В ближайшее время планируем дописать авторизацию и для vk.

Blade

Из изменений в Blade, есть одно существенное, из-за которого сообщество за последние пару дней создало десятки однотипных вопросов. Теперь и тег {{ link_to_route('login_path') }} и тег{{{ link_to_route('login_path') }}} будут экранироваться и выводиться как текст, чтобы снизить риск инъекций кода.

Вместо этого придется использовать конструкцию
 {!! link_to_route('login_path') !!}

Кстати, для облегчения перехода на новую версию Blade можно заменить теги на старые:
Blade::setRawTags($openTag, $closeTag);
Тогда не придётся переписывать все представления.



Резюме


Пятая версия именно та версия, с которой теперь следует начинать знакомство с Laravel, если вы всё ещё откладываете этот волнующий момент. Подавляющие большинство плагинов уже поддерживает новую версию фреймворка, а к релизу будет готова исчерпывающая документация. Laravel на мой взгляд это наиболее интересный и перспективный проект в php-сообществе за последнее время. Приятно видеть, как с каждым днем он привлекает все больше сторонников.

Если вы хотите поподробнее узнать о Laravel, вот несколько полезных ресурсов:

laravel.com
laravel.io
laracasts.com

Возможно я что-то упустил, тогда пишите в личку, я подправлю. Спасибо за внимание! Надеюсь статья была полезной.
Игорь Сомов @Cubist
карма
9,0
рейтинг 0,0
FullStack Web Developer
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (90)

  • +4
    Уже давольно давно присматриваюсь к этому фреймворку, и вот сейчас, наконец, появилась возможность сделать на нём новый проект. Новая версия как нельзя кстати!
    • 0
      Она немного сырая еще (учитывая, что релиза не было), но начинать смотреть ее очень стоит.
      Это не тот фреймворк, который в ближайшее время может быть заброшен и прекратить развитие =)
      • 0
        Думаю, что пока мы будем пилить проект, он уже успеет релизнуться
    • 0
      Я бы тоже не советовал на 5-ке делать что-то серьезное. Надо немного подождать. Помнится 4-ка стала более менее юзабельной к 4.1
  • –2
    Отличный пост, большое спасибо!
  • 0
    Остается только добавить, что релиз пятой версии будет в ноябре :)
    • +1
      В этой статье я хотел бы написать о новой версии Laravel, официальный релиз которой состоится в ноябре, но скачать и попробовать которую можно уже сейчас через Composer.

      Уже было в статье :)
      • +1
        Оу, тогда прошу извинить, пробежался по посту по диагонали, не заметил :)
        • +1
          Очень зря, отлично написанная статья — узнал много нового даже о 4ке, хотя статья про 5ку. =)
          • 0
            Не спорю, просто все это про пятерку узнал буквально на днях собирая по кусочкам то тут, то там :)
      • +2
        Все же, учитывая частоту коммитов в github.com/laravel/laravel/commits/develop стоит предупредить народ, что начинать проекты на пятерке сейчас не стоит, даже к бете может все очень сильно измениться внутри.
  • 0
    Держите в курсе, тоже присматриваюсь к 5
  • +4
    Спасибо за прекрасную статью, прочитал на одном дыхании. Пишите еще.
    А не присматривались к Yii2, RC выходит через пару дней, он тоже хорош, а автокомплит в PhpStorm просто волшебный.
    Пока метаюсь между ними и пытаюсь понять, что же удобней, но коммьюнити у laravel все таки помощнее, одни только laracasts чего стоят.
    • +1
      Yii 2, имхо, стоит смотреть тем, кто уже привык к первой версии, всем же, кто присматривается к совершенно новому для себя фреймворку — я бы посоветовал именно Laravel.
    • +1
      У Laravel в PhpStorm тоже есть автокомплит, на laracasts есть 2ух минутный урок где объясняется как это сделать, это 15ый из бесплатной серии уроков по PhpStorm. Используется Laravel IDE Helper и он подходит не только под PhpStorm, но и под другие IDE (лично проверял только на PhpStorm).
      • +1
        У Laravel есть автокомплит, никто не спорит. Но вы посмотрите на автокомплит в Yii2, а потом на Laravel. Все станет ясно.
        • 0
          А в чем разница, если не секрет? Чем в Yii лучше?
        • 0
          Присоединяюсь к вопросу, в чём отличие?

          *При наличии "barryvdh/laravel-ide-helper": "1.*", в composer.json у Laravel =)
    • +2
      Попробовал оба (yii2 и laravel 4).
      Я остановился на Yii2. Главная причина — более удобная работа с формами и валидация в моделях (в ларавел нет встроенной валидации моделей).
      А так — оба фреймворка чем то похожи. Даже ларавеловские фасады похожи на компоненты yii.
      Ну и такие фишки у Yii, как gii (для генерации кода), Grid, DataProvider, RBAC из коробки и тд — после того как поработаешь с ними, чуствуешь, что чего не хватает в других фреймворках.

      • 0
        Валидацию специально вынесли отдельно, дабы не перегружать модели. До этого все далали по разному, как правильно заметили в статье. В новой версии с импрувнутым валидатором веротяно процесс как-то унифицируется. По поводу фишек типа gii и прочих, то тут тоже умышленое избегание перегрузки функционалом. Все это есть, все это активно используется, но вынесено в отдельные компоненты. Composer в помощь
        • 0
          В том то и дело, что речь об удобстве. Валидация внутри моделей очень удобна.

          $model->load($_POST);
          if(!$model->save()){
           ...
          }
          


          Я только ради этого функциоанала остался на yii

          А по поводу composer — так он подключается везде, в том числе и в yii2. Другое дело, что в yii есть из коробки работа с RBAC c хорошей описанной документацией, а в ларавел надо что-то искать, подключать, разбираться. А DataProvider? Я вообще больше нигде не встречал ничего похожего (ну кроме views в друпале). Лично мне кажется, что скорость разработки благодаря встроенным компонентам в yii повышается.

          Вот что действительно удобно, чего мне не хватает — это мощное консольное приложение в Laravel.
          Ну и Queues. Хотя, поддержку очередей можно уже доустановить через тот же composer.
          • 0
            просто добавляли метод в модель, например так

            public function validate($data)
              {
                $validator = Validator::make($data, Post::$rules);
                if($validator->fails()) throw new ValidationException($validator);
                return true;
              }
            


            и потом в нужных методах той же модели, например вот так:

            public function store($data)
              {
                $this->validate($data);
                return Post::create($data);
              }
            


            можно навесить на констурктор модели и тогда получим как примерно тоже самое, как у тебя в примере.
            Такая фривольность, очевидно, имеет свои минусы, но именно поэтому мне фреймворк и понравился. Чувствуется, что не ты работаешь на фреймворк, а фреймворк рабтает на тебя.
            • 0
              В том то и дело, что нужно добавлять, что-то доделывать. А тут — не сохранилось, показываем почему не сохранилось (передаем в шаблон эту модель, в которой все свойства уже заполнены, все ошибки уже прописаны). Более того, yii (что 1й что 2й) умеет делать ajax валидацию. Т.е. работа с формами и моделью сводится к выводу input поля и попытки сохранить данные. Все остальное фреймворк сделает сам. Если не сохранилось — сам покажет и заполнит форму, покажет ошибки и тд. Но, валидация модели ещё хороша тем, что делается только 1 раз и забываешь про это. Т.е. если мы хотим заполнить данные модели вручную (не на основе данных, которые пришли из броузера, а, допустим, при выполнении какой-то фоновой задачи, воркера
              $model = new Post();
              $model->a = 'a';
              $model->b = 123;
              $model->save();
              

              то данные будут отвалидированны. Супер. Ну и конечно всё это можно обойти, не использовать, или использовать свои методы. Всё очень гибко.

              На счет кто на кого работает — это уже довольно субъективно :)
              • 0
                В yii все хорошо, пока не понадобится вывести, например, дату для редактирования (в бд метка времени, а в форме — строка) или любые другие поля которые в редактируемом виде отличаются от того что хранится в базе. Вот тогда начинаются всякие извращения (использую самописное поведение для прозрачной конвертации между оригинальным полем и фейковым полей строкой).
                • 0
                  в Yii2 встроенный мощный форматтер на базе intl
                  • 0
                    В L4 на базе Carbon
                    • 0
                      carbon — всего лишь обертка над DateTime, добавляющая сахар.
                      • 0
                        ага, и в 90% случаев достаточно 10% методов Карбона
                        • 0
                          форматтер — не обертка над DateTime. Полный контроль над обработкой и выводом даты с учетом локали. Вообще некорректно сравнивать Carbon и Formatter.
                          • 0
                            Да и ладно, все равно я его люблю не за это
                  • 0
                    Я не про форматирование говорил: пусть есть модель с полем date, которое хранится в бд в виде метки времени, пользователь его вводит в виде «dd.MM.yyyy HH:mm», как его нормально вывести, валидировать и сохранить? Первое что приходит на ум и что везде гуглится это повесить валидатор на `date` и потом где-то перед сохранением модели добавить конвертацию этой строки обратно в метку времени. Вот только это чрезвычайно кривое решение, потому что в одно время поле хранит строку, а в другое — число => никогда не знаешь что там окажется…

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

                    Или в yii 2 эта проблема уже решена?
                    • 0
                      не могу точно сказать. Есть глобальные настройки для вывода дат.
                      В вашем случае не надо ничего фейкового делать, достаточно написать поведение на два события: afterFind и beforeValidate, с двумя аргументами outputFormat и inputFormat.
                      • 0
                        И потом поиметь проблем в различных местах приложения когда в поле вместо метки времени окажется строка (или наоборот)? Нет, спасибо, уже сталкивался. Поэтому теперь всегда использую отдельные поля для отформатированных значений.
                        • 0
                          почему вместо метки времени придет строка? дайте кейс.
                          • +1
                            Если я не ошибаюсь, то вы имели в виде что-то наподобие?
                            class MyModel extends CActiveRecord  {
                                protected function afterFind () {
                                    $this->field = 'конвертируем в строку';
                            
                                    parent::afterFind ();
                                }
                            
                                protected function beforeValidate () {
                                    $this->field = 'конвертиуем в метку времени';
                            
                                    return parent::beforeValidate ();
                                }
                            }
                            

                            В итоге получаем:
                            1) После поиска field строка
                            2) После сохранения там уже число (метка времени)

                            А теперь, где-то в приложении есть следующий код:
                            public function search(MyModel $model) {
                                $search = new CDbCriteria();
                            
                                $search->compare('myfield', $model->field);
                                
                                // .....
                            }
                            

                            Пусть myfield это поле типа INT, тогда:
                            1) Вызвав метод с MyModel созданной при поиске — получаете ошибку
                            2) Вызвав метод с этой же MyModel, но после её сохранения, всё работает как и задумывалось.

                            Пример реальный, гарантировано доставляет огромную кучу радости при отладке и попытках заставить работать со всеми моделями (особенно когда с yii только начинаешь работать).
                            • 0
                              да, конечно нужно еще добавить третье событие afterSave
                              и нет, я не имел в виду такой прямой подход — я имел в виду поведение (behavior)
                              • 0
                                Только на afterValidate наверное (а этого кстати нет во многих примерах которые можно нагуглить). Но, в любом случае, с двумя полями получается гораздо проще/лучше, тем более внутри приложения метка времени нужна чаще чем то, что видит пользователь при выводе/редактировании (собственно у меня форматированная дата только им и используется, в коде везде числа).
                                • 0
                                  нет, после валидации дату надо сохранить, и только потом опять ее привести к читаемому виду.
                                  С двумя полями получается грязнее, но да, возможно так удобнее, если метку еще где-то использовать.
                                  • 0
                                    после валидации дату надо сохранить

                                    Ага, точно, но тогда если просто вызвать validate() получим туже проблему.

                                    с двумя полями получается грязнее

                                    Кода немного больше (если конечно через поведение делать), но он прозрачный.
                • 0
                  В yii все модели наследуются от Component.
                  Поэтому можно использовать встроенные геттеры и сеттеры.

                  Допустим в базе хранится в поле created_at = 1412676897;
                  В модели пишем так:
                  public function getCreated(){
                    return date("Y-m-d H:i", $this->created_at);
                  }
                  


                  Ну и потом используем в шаблонах
                  echo $model->created;
                  


                  — Опа, решил ответить после обеда и страницу не обновил, а тут выше целая дискуссия развернулась.
                  • 0
                    Это всё понятно, но нужен еще setter и где-то хранить введенную пользователем строку до момента валидации и сохранения, а потом еще захочется чтобы эти поля были синхронизированы и… рано или поздно пишется поведение для автоматизации всего этого:

                    /**
                     * @property integer $time          метка времени (то что хранится в бд)
                     * @property string  $timeDatetime  отформатированная дата (фейковое поле)
                     */
                    class MyModel extends CActiveRecord {
                        /**
                         * @return array
                         */
                        public function rules() {
                            return array_merge(parent::rules(), [
                                ['timeDatetime', 'required'],
                                ['timeDatetime', 'date',
                                    'format'             => 'dd.MM.yyyy HH:mm',
                                    'timestampAttribute' => 'time'],
                                ]);
                        }
                    
                        /**
                         * @return array
                         */
                        public function behaviors() {
                            return array_merge(parent::behaviors(), [
                                'timeAttribute' => [
                                    'class'      => 'TimeAttributeBehaviors',
                                    'attributes' => [
                                        'time' => null, // формат, но не обязательно
                                        ],
                                    ],
                                ]);
                        }
                    
                        /**
                         * @return array
                         */
                        public function attributeLabels() {
                            return array_merge(parent::attributeLabels(), [
                                'time'          => 'Дата и время',
                                'timeDatetime'  => 'Дата и время',
                                ]);
                        }
                    
                        /**
                         * @return void
                         */
                        public function refresh() {
                            $this->timeDatetime = null;
                    
                            return parent::refresh();
                        }
                    }
                    
                    • 0
                      выше я вам поведение и предложил. Пишется за 5 минут, проблем никаких.
  • 0
    А может кто-то сказать чем лучше yii 2? Со стороны смотрю на это чудо, и кажется что это тот же yii.
      • +1
        Из моего персонального лагеря (миграции):
        Yii2: pastebin.com/HjiQA2qM
        L4: pastebin.com/FmT64vN3

        =)
        • 0
          А я вот так делаю =-)

          propel diff
          propel migrate
          propel model:build
        • +2
          В варианте с yii ошибка, $this->batchInsert('{{%lang}}', ...)
          А в примере ларавел есть один большой подводный камень. Если в будущем изменится название таблицы lang, миграция с нуля не сработает. Т.к. в момент выполнения этого шага у нас имеется таблица lang, а в коде модели будет прописана таблица language, например.

          Имхо, гибкость миграций yii доставляет больше, т.к. свойства полей описываются привычным sql синтаксисом, и можно точно сказать какое поле будет создано — varchar(255) или text, например.
          • 0
            Согласен, по-этому там следует Lang::create заменить на DB::table('lang')->insert.

            Это же просто пример =)
        • +1
          Я думаю, что вы хотели показать какие классные краткие миграции у L4. Но вот из вашего примера, я совершенно не понимаю, какие поля разрешают NULL, какие — нет, какая длина строковых ключей, какой engine, какая кодировка и т.п. Наверняка это настраивается, но с дополнительными параметрами окажется что пример будет не таким уж и кратким.
          • 0
            Умолчания есть везде :) Если писать полностью, будет выходить что-то вроде
            $t->string('remember_token', 100)->nullable(); 
            


            $t->string('remember_token', 100)->default('1111'); 
            


            По-моему, тоже достаточно кратко.
    • +2
      Ну посмотрите хотя бы на AR, на автозагрузку, все стало гораздо удобнее.
  • 0
    Еще раз: ни единая строчка кода из метода store не будет исполнена, если форма не проходит валидацию.

    Как будет реагировать если форма не приходит валидацию?
    • +2
      За это отвечает метод Illuminate\Foundation\Http\FormRequest@response.
      Если ajax запрос, отдаст json с ошибками и кодом 422, а если нет — редиректит назад со всеми ошибками валидации.
  • 0
    А где можно почитать про существенные отличия от других популярных фреймворков?
    Я недавно тоже попробовал Laravel, почти всё понравилось, но в целом достаточно всё похоже на другие фреймворки, хотя конечно я глубоко его не изучал, прошелся по основным функциям — конфигурация окружений, MVC, работа с БД, авторизация…
    • 0
      Ну, сейчас многие фреймворки в общем очень похожи. А вообще, самый лучший способ, я считаю — почитать документацию. Там всё очень понятно описано.
  • 0
    Я бы еще порекомендовал посмотреть эти скринкасты, там все довольно подробно рассказано про все нововведения :)
  • –5
    Я не считаю себя гуру в php и фреймворках. До этого пару раз работал с первым и вторым зендом, бессмертным битриксом, сталкивался с Yii и Symphony, изобретал велосипеды сам, но каждый раз у меня оставалось смутное чувство неудовлетворенности.

    Переходите уже на Rails, будет меньше отрицательных смутных чувств :)
    • 0
      У нас на работе рельсы (работаю фронтэндером). Нет уж, спасибо, лучше уж синатру, а ещё лучше ларавель. =)
    • 0
      Рельсы написаны человеком для человеков (-:
      Реально на руби и рельсах приятно писать…
  • –5
    Мог бы стать идеальным фреймверком если бы не статические вызовы ((
    • +1
      Решение: Удалить алиасы из app/config/app.php и использовать внутренности напрямую. Или из внутренностей регистри приложения, например:
      app('auth')->user;
      // вместо
      Auth::user;
      
      • 0
        Хм, а это не плохая мысль, надо будет внимательнее изучить такую возможность.
        • 0
          Предлагаю попробовать посмотреть как запускается L4 — это очень много скажет о том, как он устроен и как с ним можно извращаться =)

          Наверное достаточно будет разобраться с этим хелпером: github.com/laravel/framework/blob/4.2/src/Illuminate/Foundation/start.php
      • +1
        Посмотрел код, получается на самом деле все статические вызовы, это всего лишь обвертка. И по хорошему можно с таким же успехом все завернуть в свою обвертку, и работать с нормальным ооп =D
        • 0
          Тоже вначале сильно смутило что слишком много статики, но почти вся статика это по сути фасады и на самом деле они проксят запрос к объекту внутри App. Т.е. на самом деле можно все их дергать прямо через App, но во вьюхах реально удобно именно через фасад — например при генерации форм {{ Form::open… весьма удобно
    • +1
      Статические вызовы — это просто сахарок для контейнера. laravel.com/docs/4.2/facades

      Т.е. изначально есть
      $app->make('cache')->get('key');

      для него создается фасад Cache с обработчиком __callStatic(), чтобы можно было писать так
      Cache::get('key')

      Хотя, конечно, все равно как-то криво. DI тем и хорош, что по описанию конструктора сразу понятно, какие сервисы там используются. А так понатыкают вызовы этих фасадов по всему коду, и выясняется, что класс завязан на 20+ других классов, хотя можно обойтись 2-3.
    • 0
      Нет там никаких статических вызовов :)) Честное слово, этот вопрос в интернете задает каждый второй, кто только увидел Laravel.
  • +5
    С Laravel не работал, но то обстоятельство что у них похоже вообще больше нет публичного списка багов (или есть? где?) и единственный способ запостить баг это использование liferaft, очень сильно способствует тому чтобы о нем просто забыть…

    Активные разработчики, с багами все на самом деле печально или я ошибаюсь?
    • 0
      Работаю с Laravel еще с 3-ей версии. За всё это время только в одной версии был обнаружен критический баг, который на следующий день уже был исправлен.
      Поэтому в стабильных версиях всё нормально. А в dev версиях — бывают, конечно.
      • +1
        Поэтому в стабильных версиях всё нормально.

        Я иногда работаю с yii 1.x, критичных багов там вроде давно уже нет, но регулярно возникают мелкие проблемы, например, из последнего: были проблемы с CGridView при включении history переставал работать .update что полностью ломало поиск. Минут через 15 был найден соответствующий баг на гитхабе (#2017, он до сих пор открыт) и импортирован в проект. Если бы не трекер, пришлось бы потратить кучу времени для решения этой проблемы…

        критический баг, который на следующий день уже был исправлен.

        Похоже что теперь вы о нем узнаете в лучшем случае после выхода нового релиза (у того же yii это может очень много времени занимать).
        • 0
          Ну, вот как-то не появляются мелкие проблемы. Ну, или они моментально фиксятся, что я даже заметить не успеваю.

          Похоже что теперь вы о нем узнаете в лучшем случае после выхода нового релиза (у того же yii это может очень много времени занимать).

          Я читаю твиттер laravel и Тэйлора. Если что-то критическое появляется, информация об этом есть в твиттере.
          • 0
            Тейлор сам на своём сайте ещё пишет, почему он решил что-то использовать и как это по его мнению правильно делать.
            taylorotwell.com/
            Читаю тоже по утрам. Думаешь это баг, а это фича :)
    • 0
  • 0
    А как обстоят дела со скоростью у Laravel по сравнению с Yii2?
    В своё время сравнивал его ещё с первым Yii на «hello world», так Laravel тогда сильно разочаровал.
    • 0
      Честно говоря, мне уже очень давно не попадалось объективных тестов скорости фреймворков. Сейчас все больше развлекаются, тестируя приложения «Hello, world» либо меряя, что быстрее — echo или print ;) А вам?
      • 0
        «Hello world» позволяет прикинуть оверхед фреймворка.
        Что касается бенчмарков, то на techempower.com кое-что есть. К сожалению Yii там отсутствует.
    • –1
      Как всегда зависит от задач.
      Очевидные тормоза в Laravel'e это фасады. Магия, магия.
      DIC сам по себе достаточно прост и не тормознутный (разве что сам DI через рефлексию может напрягать, особенно с учетом изменений в 5ой версии), заросы через Symfony'вский HttpRequest идут.
      Eloquent быстрее чем Doctrine, но попроще.
      Ну а вообще, стандартный ответ — нужна скорость? не пишите на PHP, либо переходите на экзотику типа HHVM / Phalcon / ReactPHP.
      • 0
        HHVM уже не экзотика. Например, Yii 2.0 на нём бегает отлично.
        • 0
          Если HHVM не экзотика — предлагаю привести в пример обычный дешёвенький хостинг с поддержкой HHVM ;)
          • +2
            • 0
              Менее именитые продают подобные 5$ машинки по 2—3$.
  • 0
    Symphony


    Symfony же?
  • 0
    Интересная статья. Особенно понравилось, что автор сначала говорит как там все хорошо и ему нравится Laravel, а потом описывает, что пятая версия решает много «костылей», делавшихся в четверке.

    Автору спасибо — прочитал на одном дыхании!

    Интересует мнение разработчиков на тему Symfony 2.5 vs Laravel 5. Я трогал только Symfony 2.5 — очень понравился — после Symfony 1.4 как глоток свежего воздуха (для тех кто все еще думает переезжать ли с Symfony 1.4).
    • 0
      После симфони 2.4-2.5 пишу на ларавеле 4

      из хорошего, что они прикрутили — очереди, хелперы связи Input и Session, разруливание обработчиков ошибок по типу параметра

      из плохого — их орм, после доктрины как-то совсем не то, особенно миграции, обработка форм — тоже совсем совсем фигово.

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

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

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

      Я не спорю что после какого-то там кодеигнайтера ларавел будет мегакрут, но после симфони это такой шажок назад.
      Полезного на несколько бандлов, а вот убрали побольше
      • 0
        Спасибо за развернутый ответ!

        За это время я тоже потрогал Laravel 4 — понравилось возникшее чувство простоты и понятности. Symfony 2.5 при всех ее плюсах не блещет простотой, иногда даже через чур сложна и требуется время, чтобы вникнуть в предоставляемые ею концепции.

        Для себя я пока остановился на следующем:
        — для своих не больших проектов и/или проектов для души беру Laravel 4 (для новых проектов Laravel 5);
        — для долгоиграющих рабочих проектов беру Symfony 2.6.
      • 0
        с учетом того что кишки симфони торчат отовсюду, это называется хипстеры не осилили симфони, поэтому взяли то что осилили, а в пятой похоже осилили чуть больше.

        Это просто отличное сравнение, лучше бы выразиться я не смог. В точку!
  • 0
    Супер фреймворк. Особенно для rest api
  • 0
    Вообще кесарю кесарево. Ведь фреймворк изначально был заточен под rest. У нас используется еще с третьей версии. Используется в основном для бекенда разных сервисов. Он именно еще тогда зацепил простотой. С выходом 4-ки пришлось перестроиться, но по прежнему писать rest api было просто и быстро, да и код получался элегантный. Судя по обзору 5-ка выглядит как логичное продолжение 4-ки, при этом с некоторыми почти фундаментальными изменениями. Опять придется пересроиться. Опять же структура файлов, она может и удобная, но переключаться между старыми проектами и новыми, мне видится, будет не очень удобно. Но это неизбежные потери.
  • 0
    Еще одна замечательная вещь, которую вы не упомянули говоря о роутинге, это возможность указывать пути в php аннотациях. Эта штука мне понравилась в Symfony2, только в случаее с Ларой придется еще и запустить комманду в артисан, что бы сгенерировался файл роутинга, но все же это уже радует и упрощает разработку. Тут Мэтт Стауффер описывает как раз таки аннотации, так же есть еще несколько статей по новым фитчам в Laravel 5

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.