Веб-разработка в 2016

PHP. Фреймворки. Yii

Александр Макаров

Yii core team, Stay.com

2013...

  • Генерация HTML — основной вид веб-проектов.
  • Все преезжают на GitHub.
  • PHP не моден. PHP-шников принижают.
  • Полох как язык, хорош как платформа для веб.
  • Самый широко используемый язык для веб.
  • PSR-0 и Composer начинают приживаться.
  • Несколько хороших фреймворков.
  • Фреймворки усложняются.
  • Yii 1.1 — основная версия. Ещё нет стабильного Yii 2.0.

А что же в 2016?

Сначала про веб в общем

REST, SPA и мобильные приложения

  • Телефон у каждого
  • В веб довольно много приложений (не сайтов)
  • REST более-менее устоялся (и идёт к SOAP)

realtime, боты

  • Чаты везде
  • Slack
  • Gitter
  • Новая волна ботов

HTTPS, HTTP/2

  • Объёмы данных
  • Минификация
  • Безопасность
  • Подход к API

Статичные вебсайты

Вписывается в общую тенденцию выбора правильного инструмента.

Рейтинги языков

RedMonk (GitHub, Stack Overflow)

  • JavaScript
  • Java
  • PHP
  • Python
  • C#

TIOBE

  • Java
  • C
  • C++
  • C#
  • Python
  • ↑ PHP
  • ↑ JavaScript

↑: Perl, Ruby, Swift

↑↑: Go

W3C

  • PHP - 82%
  • ASP.NET - 15.7%
  • Java - 2.8%
  • static files - 1.5%
  • ColdFusion - 0.7%
  • Ruby - 0.6%

Node.js / JavaScript

  • Инструменты
  • Express
  • TypeScript
  • ES2015
  • Мода меняется

Go

Всё ещё экзотика

  • Haskell
  • Clojure
  • Rust
  • Elixir

И, скорее всего, экзотикой останутся...

Python

  • Python 3
  • Django
  • Flask

Ruby

  • Rails
  • Sinatra

Java

  • Play
  • Spark

CMS

Всё популярное на PHP.

  • Wordpress
  • Drupal
  • Менее популярные на фреймворках (Craft, October)

DB

Уходит тренд на noSQL для всего. Остались:

Традиционные реляционные

  • Postgres
  • MySQL/MariaDB
  • + корпоративный сектор

JSON columns

Git - стандарт

  • GitHub
  • BitBucket
  • GitLab

Теперь про PHP

PHP живее всех

81% всех сайтов в 2013, 82% в 2016

http://w3techs.com/technologies/overview/programming_language/all

Фреймворки

  • Yii
  • Laravel
  • Symfony
  • Slim
  • ...

Скорость++

  • HHVM
  • PHP7
  • Начата работа над JIT
http://www.phptherightway.com/

Общяя тенденция — наборы библиотек

Не все делают это хорошо

Иногда это убивает сообщество

  • Solar → Aura ... OK, но...
  • Kohana → :(
  • ZF → ?

Переусложнение

PHP-код становится слишком слоистым из за стремления к безграничной гибкости.

Многие считают, что это единственный правильный путь.

Все проблемы программирования можно решить дополнительным слоем абстракции… кроме проблемы избыточной абстракции


David Wheeler

И получаем

  • Иногда легче тестировать, но сложнее писать, отлаживать и изучать код.
  • Слои. Много слоёв.
  • Плата за гибкость — сложность. Сверхгибкость нужна не часто.
  • Невозможно отдать рутину менее опытным разработчикам не потратив много времени на обучение.

И что делать?

Практичные фреймворки

  • Без лишних сложностей.
  • Проще изучить.
  • Меньше магии.
  • Меньше слоёв.
  • Меньше конфигурации.
  • Простой и удобный API.
Yii
практичный фреймворк

Мифы о фреймворках

  • Переизобрёл колесо = плохой.
  • Контейнер DI и клёвые паттерны = хороший.
  • Сделали фичу первыми = лучше остальных.
  • Слабо связанный = всегда лучше.
  • Нет фичи X = плохой.

Действительно важно

  • Легко изучать.
  • Легко отлаживать и исправлять ошибки.
  • Не мешает работать и использовать сторонний код.
  • Дружелюбное активное сообщество.
  • Обратно совместим и стабилен.
  • Нет сложностей при попытках настроить и расширить.
  • Фреймворк должен нравиться ;)

Что такое Yii 2.0?

  • PHP 5.4.
  • Сбалансированный.
  • Будет стабильным и поддерживаемым.
  • Лицензирован под BSD.
  • Решает практически все задачи веб-разработки.
  • REST API framework.
  • Инструменты для отладки.
  • Генерация кода.
  • Очень приятная работа с данными.
  • Хорошая документация и дружелюбное сообщество.
Проекты
И ещё проекты

Один из самых быстрых PHP-фреймворков*.

*Кроме PECL и микрофреймворков

Отлично работает на HHVM и PHP 7

Ставим basic


                php composer.phar create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
                cd basic
                php -S localhost:80
                

http://www.yiiframework.com/download/

bootstrap

валидация и формы

отладчик

помнит всё

ищет по логам

полезные ошибки

полезные фаталы

Все ошибки — ErrorException


                try {
                    file_get_contents('test');
                } catch (\yii\base\ErrorException $e) {
                    // ну и ладно :(
                }
                

генератор кода

генерируем контроллер

preview

diff

консоль

Мало?

advanced

  • Работа с данными.
  • Авторизация, аутентификация, восстановление пароля.
  • Разделение на frontend/backend/common/console + environments.

Ещё?

Официальные расширения

  • twig, smarty
  • swiftmailer
  • sphinx, elasticsearch
  • redis, mongodb
  • bootstrap, jui
  • imagine
  • gii, debug
  • codeception, faker
  • authclient
  • apidoc
  • http client

ставятся очень просто:


                php composer.phar require --prefer-dist yiisoft/yii2-mongodb
                

и всё, можно работать

Много сторонних расширений.

Работа с базами данных

Один синтаксис для всего.


                $query = new \yii\db\Query;
                $query->select('id, name')
                  ->from('tbl_user')
                  ->orderBy('id DESC')
                  ->limit(10);

                $command = $query->createCommand();
                echo $command->sql;
                $rows = $command->queryAll();

                $users = User::model()->find()
                  ->orderBy('id DESC')
                  ->limit(10)
                  ->all();
                                

Разделены модель и Query


                $finder = Post::find()->where(['a' => 10]);
                $finder2 = clone $finder;
                $finder2->addWhere(['b' => 1]);

                $model = $finder->one();
                $model2 = $finder2->one();

                // шорткаты
                $post = Post::findOne(10); // pk = 10
                $post = Post::findOne(['a' => 10, 'b' => 1]); // where a = 10 and b = 1
                                    

Связи AR

has one, has many. Объявляются методами.


                class User extends \yii\db\ActiveRecord
                {
                  public function getPosts()
                  {
                    return $this->hasMany('Post', ['user_id' => 'id']);
                  }

                  public function getActivePosts()
                  {
                    return $this->hasMany('Post', ['user_id' => 'id'])
                      ->where(['status' => Post::STATUS_ACTIVE]);
                  }
                }
                                    

                $posts = $user->getPosts()->limit(10)->all();
                $postCount = $user->getPosts()->count();
                                    

Многие ко многим


                class Post extends \yii\db\ActiveRecord
                {
                    public function getTags()
                    {
                        return $this->hasMany(Tag::className(), ['id' => 'tag_id'])
                            ->viaTable('post_tag', ['post_id' => 'id']);
                    }
                }
                

AR asArray


                $posts = Post::find()->limit(10)->asArray()->all();
                foreach($posts as $post) {
                  echo $post['title']."\n";
                }
                                    

dirty attributes и link

При save() сохраняется только то, что поменялось.

Появился метод link для сохранения связанных записей и unlink для удаления.


                $comment = new Comment();
                $comment->text = 'Hello, Yii!';

                // INSERT INTO post_comment ...
                $post->link('comments', $comment);

                // DELETE FROM post_comment ...
                $post->unlink('comments', $comment);
                                    

Получение данных порциями


                // 10 записей за раз
                foreach (Customer::find()->batch(10) as $customers) {
                    // $customers — массив 10 или менее объектов
                }
                // 10 записей за раз, итерация по одной
                foreach (Customer::find()->each(10) as $customer) {
                    // $customer — объект Customer
                }
                // с жадной загрузкой
                foreach (Customer::find()->with('orders')->each() as $customer) {
                }
                

А также

  • AR работает с noSQL, в т.ч. связи между моделями
  • Жадная и ленивая загрузка данных

О приоритетах

Мы не усложняем

Сложность вносится только когда это действительно необходимо.

Мы балансируем

Делаем приятный API, покрываем 80%, даём умолчания, позволяем расширять остальное.

Мы документируем

Документация

А ещё...

  • Мы любим инструменты (apidoc) и IDE
  • Не забываем про производительность
  • Сами используем фреймворк

Мы следим за тенденциями

REST API framework

Удобно

  • controller action — API endpoint
  • controller — группа endpoint для одного типа ресурса
  • model — ресурс

Пример


                namespace app\controllers;

                use yii\rest\ActiveController;

                class UserController extends ActiveController
                {
                    public $modelClass = 'app\models\User';

                    public function actionSearch($keyword) // !!!
                    {
                        $result = SearchService::search($keyword);
                        return $result;
                    }
                }
                
'urlManager' => [
                    'enablePrettyUrl' => true,
                    'enableStrictParsing' => true,
                    'showScriptName' => false,
                    'rules' => [
                        [
                            'class' => 'yii\rest\UrlRule',
                            'controller' => 'user'
                        ],
                    ],
                ]
  • GET /users: постранично все юзеры;
  • HEAD /users: заголовки ↑;
  • POST /users: новый юзер;
  • GET /users/123: информация юзера 123;
  • HEAD /users/123: заголовки ↑;
  • PATCH /users/123 и PUT /users/123: обновить юзера 123;
  • DELETE /users/123: удалить юзера 123;
  • OPTIONS /users: показать какие HTTP-verbs можно использовать для /users;
  • OPTIONS /users/123: показать какие HTTP-verbs можно использовать /users/123.

Пробуем


                curl -i -H "Accept:application/json" "http://localhost/users"
                

                    HTTP/1.1 200 OK
                    Date: Sun, 02 Mar 2014 05:31:43 GMT
                    Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
                    X-Powered-By: PHP/5.4.20
                    X-Pagination-Total-Count: 1000
                    X-Pagination-Page-Count: 50
                    X-Pagination-Current-Page: 1
                    X-Pagination-Per-Page: 20
                    Link: <http://localhost/users?page=1>; rel=self,
                        <http://localhost/users?page=2>; rel=next,
                        <http://localhost/users?page=50>; rel=last
                    Transfer-Encoding: chunked
                    Content-Type: application/json; charset=UTF-8

                    [
                        {
                            "id": 1,
                            ...
                        },
                        {
                            "id": 2,
                            ...
                        },
                        ...
                    ]
                                

Возможности

  • Быстрое прототипирование
  • JSON/XML или свой формат
  • Версионирование
  • Настраиваемая сериализация, можно выбрать что отдавать
  • Коллекции, поля и постраничная разбивка, валидация

Возможности

  • REST + fallback
  • OPTIONS и HEAD
  • Аутентификация (HTTP basic, URL token, OAuth2), авторизация (обычная: access filter и RBAC)
  • HATEOAS (Hypermedia as the Engine of Application State)
  • HTTP-кеш
  • Rate limiting: N запросов в секунду на пользователя

Документация: http://www.yiiframework.com/doc-2.0/guide-rest.html

Немного истории

Prado 1.0 (2004)

  • Qiang Xue, релиз в июне 2004
  • Вдохновлялся Apache Tapestry, Borland Delphi и Microsoft ASP.NET.
  • Финалист Zend gophp5

Prado 2.0 (2005)

  • Wei Zhuo помог с i18n и l10n
  • После релиза принято решение переписать проект

Prado 3.0 (2006)

  • Вдохновлялся Microsoft ASP.NET 2.0
  • Последняя версия с большими улучшениями
  • Жива и поддерживается до сих пор

Yii 1.0 (2006 - 2008)

  • Qiang аносирует альфу Yii
  • Большинство фич из Prado: ActiveRecord, i18n, l10n и так далее.
  • Вдохновлялись RoR, symfony1, Joomla
  • Быстрее остальных фреймворков
  • Быстрый рост сообщества

yiiframework.ru

  • Запущен в 2009
  • В него плавно перетекла часть сообщества code-igniter.ru

Yii 1.1 (2010)

  • Построитель форм, реляционные запросы AR, готовый каркас для unit-тестов и многое другое.
  • Я присодинился к команде.
  • Релизнут новый сайт.
  • Первые книги.

Yii 1.2 (2010)

  • Обновить 1.1
  • Оставить совместимость с 5.2 и 5.3
  • Так и не вышел

Yii cookbook (2011-2013)

  • Моя книга
  • Русская и английская версии
  • PACKT
  • Вышло отлично

2012 - 2013

  • CeBe присоединился к команде в 2012
  • Paul Klimov присоединился к команде в 2013
  • GitHub
  • Ещё книги

Yii 2.0 (2012 - ...)

  • Разрабатывался в приватном репозитории до 2013.
  • Релизнут в 2014.
  • В 2015 к команде присоединился SilverFire.
  • В 2016 разделены релизы расширений и фреймворка.

Планы

  • Поддержка критичных вещей в 1.1
  • Поддержка 2.0
  • Yii 2.1, LTS
  • Новые сайты

Революции не будет

Yii 2.1 (2016?)

  • PHP 5.6
  • Вычистить @deprecated
  • Вытащить asset-ы из ядра
  • Сделать что-то с fxp
  • Выпилить клиентсайд из ядра
  • ...

Yii 2.2

  • PHP 7
  • Больше интерфейсов, строже типизация
  • Больше пакетов выпилить из ядра
  • Отвязать роутинг от MVC
  • ...

Чем помочь:

The end

Слоник намекает...