localdisk

PHP とか Java とか Web とか好きなことを書きます。

ベルフェイス株式会社に入社しました

脱無職

7月から進めていた求職活動ですが、10月1日よりベルフェイス株式会社に入社しています。

bell-face.com

求職エントリを書いてから、幸いなことに色々と声をかけていただきました。本当にありがとうございます。

ベルフェイス株式会社に決めた理由ですが、ビジネスは好調なもののエンジニアリング周りが色々と足りてなくて、ここなら自分の経験を生かしつつ、色々貢献できるだろうということ思ったからです。以前は

  • 何をやるかより とやるか
  • 仕事で取り組むことになる技術が自分の市場価値を上げることに繋がるか

というをわりと重視していたのですが、今回の求職活動ではそのへんの優先度を少し下げました。あまり自分のこと(市場価値とかそういうの)を考えなくなってきてて年をとったのかなぁという気持ちです。

このへんのことは先日PHPの現場でも喋ったのでよかったら聴いてみてください。

php-genba.shin1x1.com

新原さん、喋る機会をいただきありがとうございました。

リモートワークとライフイベントについて

ちょっと入社エントリと趣旨はずれますが、ちょうどよいのでリモートワークという選択をしたことについて。PHPの現場で話し忘れていました。

今私はフルリモートで自宅から働いてます。自分の体調もあってそうせざるを得ないのが実情ですが、自分が健康であっても近いうちにフルリモートワークを選択するつもりでした。

現在私は妻子のいない気楽な身分ですが、そう遠くないうちに1つのライフイベントがやってきます。それは「親あるいは近親者の介護」です。今のところ両親は健在で大きな病気もしていませんが、これからもそうである保障はどこにもありません。なので今のうちからそういうイベントが起きても柔軟に取り組めるような態勢を整えておきたかった、というのが理由です。

これはエンジニア関係なく私くらいの年頃(40代前半)の人はみんな考えてるのではないかなぁと思っています。

リモートワークは決して楽なものではなく、きめ細かいコミュニケーションや時間内にしっかりと成果を出すということが求められます。一方で介護に限らず結婚や出産等のライフイベントにたいして柔軟に対応できるという一面もあります。そのへんを会社に理解してもらった上でしっかりやっていきたいですね。

ベルフェイスはエンジニアを募集しています

仕事中にこのエントリを書いているので宣伝。ベルフェイスはエンジニア・デザイナーを募集しています(切実)。フロントエンドは jQuery, サーバーサイドは CakePHP2 なモノリシックなアプリケーションなのですが、これを少しずつ置き換えていったり、小さくバラしたりということをしています。今のところは Laravel とか Nuxt に置き換える予定。リモートワーク大丈夫です。

www.wantedly.com

追記

CM動画あったんだった

youtu.be

求職エントリ

株式会社イノベーター・ジャパン を 7/14 付で退職することになりました。

原因

昨年から結構ひどめの不眠を患っており、11月に一度休職。年明けから復帰したのですが、4月に再発。んで5月から休職で現在に至ります。

お医者さんによると「概日リズム睡眠障害」という病気らしいです。現在はわりと元気なのですが、仕事をする上で同期的なコミュニケーションをとることができないので(9時〜18時に起きてる保証がない)退職したほうがよいな、と。

今後の予定とか

7, 8月はゆっくり休んで治療に専念しつつ、9〜10月くらいから働けるといいなと思っています。問題は今の状態でプログラム書けるの? という話ですが、僕自身不安になったので、元気な時間を利用してwebサービス作ってみました。

https://yarana.io/

簡単に説明するとブラウザで専ブラみたいなことができるやつです。スマホでも見れると思います。Laravel と Vue.js で作りました。SPAでPWAに対応してます(対応しただけで大したことはやっていない)。ユーザー管理には Firebase 使ってます。すごい手軽に使えてびっくりした。

求職してます

求職エントリなので、自分がやれることや就職先として求めることを書きます。

言語

PHP

  • 自分が一番パフォーマンスが出せる言語です
  • そこそこちゃんと書けると思います

JavaScript

  • 書くことに苦労はしないけど、得意かと言われると考え込むレベル
  • 自分の技術的興味は web 一般なので、もう少し詳しくなりたい
  • サーバーサイドでは使ったことないです

TypeScript

  • 上記のwebサービスJavaScriptから書き直してる途中
  • 最初から TypeScript にしときゃよかったと後悔してる

SQL

  • あまり複雑なものは得意ではないです
    • というか、複雑なSQLを書いたら負けだと思ってる
      • 集計とかバッチ系はのぞく
    • 複雑なSQLを書かなくてもいいように設計したいタイプです
    • ORMにすべて任せたい

CSS/HTML

  • 普通に書けると思います
  • Vue.js の scoped があることによって CSS の難易度がすごく下がったと思う

Java

  • わりと好きな言語
  • でも最後に書いたバージョンは 7

フレームワークとかライブラリとか

Laravel

Vue.js

  • JavaScriptフレームワーク
  • 手になじむので使ってます
  • 書くには困らないが、自分のコードがベストプラクティスかどうか判断できないレベル

インフラ周り

ほとんど投資してないです。Dockerはコマンド打てる程度、AWScli からじゃなくてコンソールからぽちぽちやる感じです。

やりたいこと・やりたくないこと

これやりたい!みたいなのは特にないです。受託でもサービスでもどんとこいです。やりたくないのは MovableType です。

就職先に求めること

福岡に住んでても大丈夫

今住んでいる福岡市から引っ越す予定はないので、それでもよいと言ってくれるところです。会社自体はどこにあっても気にしません。

時間軸がずれてても大丈夫

自分も努力はしますが、9〜18時という一般的なタイムゾーンで毎日働くことはできないと思います。現状だとそのタイムゾーンで自分が起きてるのは週1〜2日程度です。

フルリモート大丈夫

上記のような感じなので、そもそも出社が困難です。タイムゾーンがあってるときに出社ならいけると思います。会議など週1の定例などでしたら可能です。

お問い合わせ

上記のような条件でも大丈夫!という方は、私の Twitter アカウントである@localdisk の DM にてご連絡ください。現在どなたからでも受け取れるようにしています。

カノジョできないエンジニア Advent Calendar とインターネット懐古おじさんの昔話

ごあいさつ

shinichi-takahashi さんからバトンを受け取りましたので、カノジョできないエンジニア Advent Calendar 2016 の24日目を @localdisk がお送りします。

クリスマスを目前に控えたこの日に自分はなにをやってるんだろう…という疑問に蓋をして頑張っていこうと思います。もうなんか色々やさぐれているので技術的要素は皆無です。

カノジョできないエンジニア Advent Calendar にたいする既視感

さて、以前から カノジョできないエンジニア Advent Calendar 2016 についてずっと既視感がありました。これどこかで見たぞ。という感覚。なんだろうなぁと思い出せずに日々過ごしていたのですが先日公開された下記エントリで思い出しました。

omocoro.jp

ああ、そうだ。X'mas殲滅委員会 だ。この ドロッ とした情念。なにか通じるものがある。X'mas殲滅委員会というのは何かというと、ろじっくぱらだいすのワタナベさんを中心とした「一人寂しくクリスマスを過ごすテキストサイト管理人たちが、クリスマス当日に狂ったように自サイトを更新しまくる」というちょっとアレなお祭りです。このお祭りは1999年と2000年に行われ一部の層から絶大な支持を得ました。

僕も当時、小さなテキストサイトを運営していました。参加はしていませんが空いた時間で見ていた記憶があります。懐かしい。

インターネット懐古おじさんが思うこと

ある程度長い間インターネットの片隅で生きていると 人生なるようになる ものだなぁと思います。数は多くありませんが テキストサイト運営時に知り合った人たちは概ね幸せそうです。TwitterFacebook を見ると家庭を築いたり会社で偉くなってたり社長やってたりします。観測できない人たちも多いですがまぁそこそこ幸せにやってるんだろうと思います。

カノジョできないエンジニア Advent Calendar 2016 に参加したエンジニアもきっと幸せになれるだろうと思います。参加してる人の中には実際にお会いしたことのある人もいて、みんな愉快で優秀です。来年の今頃はわりと充実したクリスマスを送っているのではないでしょうか。

さいごに

来年は好きな人と過ごしながら上から目線で カノジョできないエンジニア Advent Calendar を眺めていたいと思います。きっと shinichi-takahashi さんが今年と同じように半べそかきながら立ててくれることでしょう。

メリークリスマス。そしてよいお年を。

PHPカンファレンス関西の感想と100万件バッチで死なないLaravel

2016年7月16日(土) に開催された PHP カンファレンス関西 2016 に行ってきました。

conference.kphpug.jp

会場は、昨年と同じブリーゼプラザ(大阪西梅田)で行われました。uzulla さんのエントリにあるように綺麗でオシャレ感漂うビルです。

さて、ここからは聞いたセッションの感想等を。

[基調講演] Composerを速くするために必要だったもの

speakerdeck.com

移動の都合で、はじめのほうを聞き逃してしまったんですけど、最高でした。僕はもう Composer ないと生きていけないし、それをより速くしてくれた Hiraku さんには感謝しかない。 本当に必要だったのは問題を向き合うこと という言葉にはしびれました。

大量のデータで困ってませんか?

Google BigQuery のお話。こういうPHPほとんどでてこない話が聞けるというのも、PHPカンファレンスらしくてよいところ。僕は触ったことがないのですが何かしらのデータを分析するときに使ってみたいなぁ。

ORMユーザー対談 〜Laravel/Doctrine/CakePHP3〜

殴り合いを期待して…というのは冗談で普通に和やかな空気でした。で、最後のほうで「100万件バッチどうする?」という話が出ました。ORM使ってるとこういう大量データのバッチ処理が問題になるのですが、カジュアルに Post::all() とかやると死にます。なので今回は死なない方法をここに書いておきます。5.2.33 以上で使えます。

gist.github.com

44行目に注目してください cursor メソッドを使っています。これは 5.2.33 から追加されました*1。内部でジェネレータを使っているのでメモリ不足で死ななくて最高です。

Laravel は 100万件バッチでも死なない。これだけははっきりと真実を伝えたかった。

あ、あと、MySQLのオプションを変えたいときは config/database.phpoption を変えるとよいです。

fideloper.com

追記

100万件とか作るコマンドも貼っておきます。

gist.github.com

php artisan make:post 1000000 とかやればおk。プログレスバーが使えて便利。こんな感じでバルクインサートできます。

ビューのソースコードコンフリクトから解放される、PHPerのための次世代Webアプリケーション開発への道

人がすごかった。演台の前に体育座りで聴いてた人もいた。この時間はスポンサーブース回ったりEC-Cubeの講演をちら見したり。

Laravel と DIコンテナ、コンポーネントの設計

この講演も人気で入れず。残念。あ、そうそう。動画が公開されるらしいですよ。PHPカンファレンス福岡も先日動画を公開したのでよかったらご覧ください。

PHPerに知ってほしいDB設計の話

speakerdeck.com

そーだい さんの講演はなにげに PHPカンファレンス北海道、福岡、やぱちーと全て聴いています。少しずつアップデートされているのがわかって楽しいです。

LT

で、LT。僕も一枠頂いたのでテストで簡単なモックを作りたいときは無名クラスでいいのではないかという話をさせていただきました。

懇親会

飲んだり食べたり。午前2時くらいまでワイワイやってました。

まとめ

楽しかった!また来るぞ!!

追記

id:sasezaki さんよりコメントをいただいたので、軽く計測してみました。

環境

OS: Mac OS X 10.11.6 CPU: Intel Core i5 2.7 GHz メモリ: 16 GB

Vagrant

Laravel Homestead 使用 CPU: 1 メモリ: 2G

posts テーブル

mysql> show columns from posts;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255)     | NO   |     | NULL    |                |
| body       | text             | NO   |     | NULL    |                |
| created_at | timestamp        | YES  |     | NULL    |                |
| updated_at | timestamp        | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+

計測方法

こんな感じに書いてみました。

<?php

class FetchPost extends Command
{

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $start = microtime(true);
        $posts = Post::cursor();
        foreach ($posts as $post) {
            $this->line($post->body);
        }
        $usage          = number_format(memory_get_usage());
        $peakUsage      = number_format(memory_get_peak_usage());
        $processingTime = (microtime(true) - $start) * 1000;

        $this->info(sprintf("\nMemory: %s / %s bytes\nTime: %f ms", $usage, $peakUsage, $processingTime));
    }
}

計測結果

Memory: 8,126,624 / 426,113,968 bytes
Time: 723790.810108 ms

12分くらい。

*1:カジュアルに機能を足しすぎだよなぁとは思う

PHPカンファレンス北海道に行ってきました

4月16日におこなわれた PHPカンファレンス北海道 2016 に行ってきました。ついでにLaravelを布教してきました。

speakerdeck.com

初心者向けというかフレームワークの乗り換えを考えてる方むけにつくりました。参考になれば幸い。15分はあっという間ですね。

午前一発目の発表だったので、他のセッションも色々見ることができました。以下聞いたセッションの簡単な紹介です。

HerokuでPHPのココが便利

HerokuでPHPのココが便利 mimemo スライドモードがついてるの便利だ。

フリープランが制限されてしまった Heroku ですが、カジュアルに動かせる魅力は相変わらず。Terraform便利っぽい。

クラウド時代だからこそ見直したい
PHPアプリケーションのパフォーマンスチューニング

www.slideshare.net

インフラの話多め。ここらへん強くないので非常に参考になった。スライド見ていただけるとボリュームがかなりあって、時間が足りなくなって大変そうでした。

お昼ごはん

今回は、美味しいお弁当を用意していただきました。唐揚げ弁当美味しかったです。で、お弁当食べながらランチョンスポンサーセッションを聞きました。

PHPer人生、一度はフレームワークを作っておこう!

speakerdeck.com

オレオレフレームワークのすすめ。独自のグルーヴ感と、そのトークを支える技術力。圧巻の一言。このスライドを作るためにオレオレフレームワークを3つ作成してて、熱意がすごい。

PSRを活用するフレームワーク開発

残念。内容は PSR の内容を追っていきながら実際はどのように実装されているのかという話でした。あとミドルウェア。スライドの内容もミドルウェア

PHPerに知ってほしいRDBの事

speakerdeck.com

これも良かったですね。インデックス・実行計画etc…。MySQL は高速・シンプルだが、それを活かすためには設計力が問われるというくだりがよかった。

あとMySQL Workbench で実行計画をグラフィカルに見れるの知らなかった。

漢(オトコ)のコンピュータ道: MySQLでVisual Explain

PHPer にイマイチ PostgreSQL 人気ないの単純に縁がないからなんですよね。WordPress とかそもそも MySQL じゃないと動かないので。PostgreSQL の Window 素敵。

PSR が分かってきた

スライド見つからず。PSR を0から説明していく感じでした。こちらも時間が足りなくなってて、気がついたら徳丸さんの講演が始まってました。

『例えば、PHPを避ける』以降PHPはどれだけ安全になったか

www.slideshare.net

途中からですが素晴らしいプレゼンでした。

  • 検証環境の数驚きの205個
    • Docker でほしい
    • この環境を使って、デモをされてました
  • 「夜遅くに攻撃者の気持ちになってですね…」などおもしろワードが飛び交ってた

振り返って

4年ぶりとの開催とのことでしたが、ブランクを感じさせない素晴らしい内容でした。運営者視点でみると色々参考になることも多く、取り入れたい要素がたくさんありました。懇親会も楽しかった!

次は 5/21 に開催する PHPカンファレンス福岡2016 です。まだまだ参加者を募集しておりますのでお早めにどうぞ。

最後に…今年は PSR の年

なのではないかと思います。北海道でも PSR をネタにした方が3人おり、来月行われる PHPカンファレンス福岡2016 でも同様です。北海道の後、福岡・関西と続きますので東京で総括してくれると楽しいことになると思います(願望)

Laravel 5.2 でセッションがNULLになる時はミドルウェアを疑え

あけましておめでとうございます。今年もよろしくお願いします。

まずはこちらのエントリを参照してみてください。

Laravel 5.2 socialite twitter認証で$this->request->getSession()がnull | Romantique 76

はい、タイトルまんま。Laravel 5.2 でミドルウェアグループという機能ができました。複数ミドルウェアに名前をつけて登録できるというものです。で、この機能が実装されたため、5.1 でグローバルミドルウェアとして登録されていたものが web という名前のミドルウェアグループになってます(グローバルミドルウェアに登録されているのはメンテナンスチェックのみ)。

コードだと App\Http\Kernel クラスがそれになります。 アドベントカレンダーに書いてなくて申し訳ない。

https://github.com/laravel/laravel/blob/master/app/Http/Kernel.php#L26

そんなわけで、今までどおり書いてしまうとセッション等のミドルウェアを通過しなくなるので、なぜかセッションが作られない…どういうことなの…? となります注意してくださいね。下記のように書けばOKです。

<?php

Route::group(['middleware' => ['web']], function () {
    Route::get('/', function () {
        if (! Auth::check()) {
            return Redirect::to('github/authorize');
        }
    });

    Route::get('{provider}/authorize', function ($provider) {
        // ソーシャルログイン処理
        return Socialite::with($provider)->redirect();
    });

    Route::get('{provider}/login', function ($provider) {
        // ユーザー情報取得
        $userData = Socialite::with($provider)->user();
        dd($userData);
    });
});

RateLimit とか MultiAuth とか、書いてない新機能もありますので近いうちに書きます。

デプロイツールを使ってLaravelをデプロイする

メリークリスマス!!この記事は Laravelリファレンス発売記念!販売促進!! Advent Calendar 2015 - Adventar の 12/19 分です。メリークリスマス!!

親方!Capistrano に Laravel プラグインが!

f:id:localdisk:20151206205015p:plain
A remote server automation and deployment tool written in Ruby.

喜び勇んで リポジトリ を参照してみたところ…最終更新が2年前。Laravel 5 対応の PR が5月にされていますが、マージされいない…。解散(白目

ちなみに Ruby の環境を整えてたら2時間くらい吹っ飛んでた。

Deployer を使おう

はい、というわけで Deployer 使ってみましょうか。Rocketeer より簡単ですし、PHPわかんなくても shell がわかればなんとかなります。

Deployer のインストール

TOPページにある Download deployer.phar をクリックして deployer.phar をダウンロードしましょう。これは phar をそのままプロジェクトルートに置くもよし、/usr/local/bin あたりに mv するもよしです。Jenkins さんにデプロイを任せてたいのであれば後者がよいでしょう。

chmod +x depoyer.phar して実行権限をつけておきましょう。詳しいことは公式ドキュメントを読もう。

使ってみる

では、ダウンロードした deployer.phar を叩いてみましょう。

➜  deploy  php deployer.phar
Deployer version 3.0.10

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -f, --file[=FILE]     Specify Deployer file.
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  help         Displays help for a command
  list         Lists commands
  self-update  Updates deployer.phar to the latest version
  worker       Deployer uses workers for parallel deployment.

なるほど、この時点で実行できるのは help, list, self-update, worker コマンドのみですね。では deploy.php を作って以下のように書いてみましょう。

<?php

require 'recipe/common.php';

でもう一度実行。

➜  deploy  php deployer.phar
Deployer version 3.0.10

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -f, --file[=FILE]     Specify Deployer file.
      --tag[=TAG]       Tag to deploy.
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  cleanup             Cleaning up old releases
  current             Show current release.
  help                Displays help for a command
  list                Lists commands
  rollback            Rollback to previous release
  self-update         Updates deployer.phar to the latest version
  worker              Deployer uses workers for parallel deployment.
 deploy
  deploy:copy_dirs    Copy directories
  deploy:prepare      Preparing server for deploy
  deploy:release      Prepare release
  deploy:shared       Creating symlinks for shared files
  deploy:symlink      Creating symlink to release
  deploy:update_code  Updating code
  deploy:vendors      Installing vendors
  deploy:writable     Make writable dirs

お、実行できるタスクが随分増えました。これは、deployer はデフォルトで deploy.php が探す*1のと recipe/common.php にあらかじめ便利そうなタスク群が組み込まれているためです。

ついでに説明しておきますと、Deployerは使う分には学習コストがほとんどかからないことです。半日くらいいじっていれば大体なんとかなります。

deployer
├── bin
├── recipe
├── src
└── test

上記が deployer のディレクトリ構成なんですが、bin のなかの dep というファイルがコマンドを受け付けるエンドポイント。recipeディレクトリがフレームワークや著名なプロダクト(WrodPressとかDrupalとか)のデプロイタスクとか。大事なのは common.php で、他の各タスクもこの common.phprequire してます。

タスクがどんな処理をやってるかはソースコードみれば大体わかります。php よりも shell の知識があったほうがよいくらいです。

各タスクがなにやってるのか

全ては網羅してませんが、だいたいこんな感じです。

あとはリリースをひとつ前に戻す rollback とか大体揃ってる感じです。

サーバーとの接続

こんな感じ。server 関数を使います。第1引数は任意の名前、第2引数がホスト名あるいはIPアドレス、第3引数がポート。user 関数はログインユーザー、identityFilessh の key を指定します。今回は ssh 使ってますが、password 関数もあるのでそういう認証も可能。stage 関数はデプロイ対象サーバーがたくさんある場合に意味が出てきます。今回は割愛。で、env 関数でデプロイするディレクトリを指定。

詳しく知りたい場合は Deployer — Servers を熟読しよう。

<?php

require 'recipe/laravel.php';

server('test', '127.0.0.1', 2222)
    ->user('vagrant')
    ->identityFile('public key path', 'private key path')
    ->stage('test')
    ->env('deploy_path', '/home/vagrant/deploy_test');


set('repository', 'https://github.com/laravel/laravel');

で、 php deployer.phar deploy -vvv test とやればOK。test はサーバーで指定した名前、-vvv とやるとログが詳細にでるので便利。この例では Laravel のレシピを使ってますが、実際使うときは 最新レシピを使ったほうがいいかもですが、これでも色々足りなかったり(optimizeとか)cleanup してたりする(cleanup されたら rollback 不可)ので自分でタレ作ったほうがよいです。年内に僕のタレをここに載せておきます(このエントリも複数日に分けて書いてます)。 載せました。

gist.github.com

カスタマイズとか

recipe を読むと捗ります。ローカルから直接アップロードとか。functions.php を見ておくとはかどります。自分でタスク作ったりとかそういうやつです。migrate したり optimize したり等々。あとサードパーティのレシピも参考になります。

では、よいクリスマスを!

*1:他のファイル名にしたいときは-f=ファイル名をつける

Laravel を高速化というか最適化する

この記事は Laravelリファレンス発売記念!販売促進!! Advent Calendar 2015 - Adventar 12/5 分の記事です。

Laravel について「遅い」とか言われるたびに、「ちゃんと最適化してる?」って思ってたので良い機会なのでここらへんちゃんと書いておこうと思います。

まずは、アプリケーションのコードを一切変えないお手軽な方法から。

コードを修正しないお手軽な方法

optimize コマンド

これ、デプロイ時は必須です。やってくることは

注意点としては config/app.phpdebugtrue だと clear-compiled が走るだけで終了するので、本番時はちゃんと false を設定しよう。

route:cache コマンド

ルート定義をキャッシュします。実際何してるかというと、ルート定義をシリアライズして base64_encode したものを /bootstrap/cache/routes.php に出力しています。

注意点としては、routes.phpクロージャを書いている場合はシリアライズできなくてエラーになる。以下の様なルート定義はダメということです。

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

キャッシュしたければコントローラーを作ってルート定義しよう。

config:cache コマンド

設定ファイルをキャッシュします。実際何してるかというと、すべての設定値を var_export して /bootstrap/cache/config.php に出力しています。

これらのコマンドは使って困ることはないので、デプロイ時には必ず実行させましょう。

番外

これは Laravel に限らないのですが

とかね。早くなりますよ。PHP 7 はともかく OPcache は必ず有効にしましょう。

コードを変更して早くする方法

ここからはコードを少し変更して最適化を目指します。

不要なミドルウェアの削除

App\Http\Kernel クラスにはグローバルミドルウェアとして幾つかのミドルウェアがあらかじめ登録されています。使わないものを削除してしまいましょう。

  • CheckForMaintenanceMode
    • メンテナンスモードかどうかをチェックする。メンテナンスモードだったら 503 を返す。
  • EncryptCookies
    • クッキーの暗号化。
  • AddQueuedCookiesToResponse
    • クッキー使わなければいらない(APIサーバーとか)
  • StartSession
    • セッション使わなければいらない(APIサーバーとか)
  • ShareErrorsFromSession
    • セッションに errors という名前で登録された内容をすべてのビューで共有している
  • VerifyCsrfToken
    • CRSF チェック。

不要なサービスプロバイダ/ファサードを削除

Laravel は多機能なフレームワークなので、要件には必要のない機能もあると思います。必要のないものは config/app.php から削除してしまいましょう。

ファサードを使わない

必要なインスタンスファサードを経由するのではなく、コンストラクタメソッドの引数としてインジェクションしたり、コンテナから直接引っ張ってくればファサードは必要なくなります。config/app.phpaliases の配列をごっそり削除すれば初期処理は早くなります。

ここらへんは 12/15 に @ex_takezawa さんが詳しく解説してくれると思います。

利便性とトレードオフですが、難易度はさほど高くありません。

Eloquent を使わない

すべての処理を QueryBuilder に任せる方法です。Eloquent はマジックメソッドを多用しているので、使用しないことで若干のパフォーマンス上昇が望めると思います。 こちらはファサードを使わないよりも難易度が高くなると思います。Eloquent を使わないということは…

  • リレーション
  • Eagerローディング
  • マスアサインメント
  • 論理削除
  • クエリースコープ
  • モデルイベント
  • アクセサ / ミューテーター
  • シリアライズ

の機能が使えないということなので、慎重に検討する必要があります。僕はたぶん無理。

結論

そこまで頑張るんだったら Lumen 使おう。

まとめ

いろいろ最適化の手法を紹介しましたが、いかがでしたでしょうか? まぁ、うん、それでも満足できない場合は Go とか Java 使ったほうがいいと思います。

宣伝

よろしくお願いします!

www.amazon.co.jp

Laravel Socialite の独自ドライバを実装する

この記事は Laravelリファレンス発売記念!販売促進!! Advent Calendar 2015 - Adventar の3日目の記事です。

ちょうど1年前にこんな記事を書きました。

qiita.com

ドライバの独自実装

今書いています。ごめんなさい。更新したら通知するようにしますのでストックしてくれていいのよ?(チラチラ http://qiita.com/localdisk/items/2e2724f31864fd49b675

気がついたら一年経ってたよ…。というわけでドライバの実装をしてみたいと思います。現在 Socialite で実装されているドライバは

となります。一年前と比較すると LinkedIn と BItbucket が増えましたね。今回は折角なので はてなのOAuth ドライバを実装したいと思います。自分はてなーなので。

はてなの OAuth のバージョン

調べてみるとはてなの OAuth のバージョンは1のようです。Socialite だと一緒なのは Twitter と Bitbucket ですね。ソースコードを読んでみると2つクラスを作る必要があるようです。

ですね。まずは、app/Socialite ディレクトリを作成しましょう。

HatenaProvider

空でOK。

<?php

namespace App\Socialite;

use Laravel\Socialite\One\AbstractProvider;

class HatenaProvider extends AbstractProvider
{

}

親クラスの Laravel\Socialite\One\AbstractProvider ですが、abstract class なのに abstract method がない(困惑)のでこれでよいです。

HatenaServer

<?php

namespace App\Socialite;


use Laravel\Socialite\One\User;
use League\OAuth1\Client\Server\Server;
use League\OAuth1\Client\Credentials\TokenCredentials;

class HatenaServer extends Server
{
    /**
     * {@inheritDoc}
     */
    public function urlTemporaryCredentials()
    {
        $scopes = implode(',', config('services.hatena.scope'));

        return "https://www.hatena.com/oauth/initiate?scope={$scopes}";
    }

    /**
     * {@inheritDoc}
     */
    public function urlAuthorization()
    {
        return 'https://www.hatena.ne.jp/oauth/authorize';
    }

    /**
     * {@inheritDoc}
     */
    public function urlTokenCredentials()
    {
        return 'https://www.hatena.com/oauth/token';
    }

    /**
     * {@inheritDoc}
     */
    public function urlUserDetails()
    {
        return 'http://n.hatena.com/applications/my.json';
    }

    /**
     * {@inheritDoc}
     */
    public function userDetails($data, TokenCredentials $tokenCredentials)
    {
        $user = new User();

        $user->uid      = $data['url_name'];
        $user->nickname = $data['display_name'];
        $user->name     = $data['url_name'];
        $user->imageUrl = $data['profile_image_url'];
        $user->email    = '';

        $used = ['url_name', 'display_name', 'profile_image_url'];

        foreach ($data as $key => $value) {
            if (strpos($key, 'url') !== false) {
                if (!in_array($key, $used)) {
                    $used[] = $key;
                }

                $user->urls[$key] = $value;
            }
        }

        // Save all extra data
        $user->extra = array_diff_key($data, array_flip($used));

        return $user;
    }

    /**
     * {@inheritDoc}
     */
    public function userUid($data, TokenCredentials $tokenCredentials)
    {
        return $data['url_name'];
    }

    /**
     * {@inheritDoc}
     */
    public function userEmail($data, TokenCredentials $tokenCredentials)
    {
        return;
    }

    /**
     * {@inheritDoc}
     */
    public function userScreenName($data, TokenCredentials $tokenCredentials)
    {
        return $data['name'];
    }

}

メソッドの説明

urlTemporaryCredentials

Request token の取得。はてなの場合、ここが特殊で scope というパラメータ名で "承認を求める操作名" を渡す必要があります(複数の場合はカンマ区切りで渡す)。

  • read_public
  • write_public
  • read_private
  • write_private

この情報を渡すために今回は config/services.php に"承認を求める操作名"を定義しています。

<?php

return [
    'hatena' => [
        'client_id'     => 'XXX',
        'client_secret' => 'XXX',
        'redirect'      => 'http://localhost:8000/hatena/login',
        'scope'         => ['read_public', 'write_public']
    ],
];

urlAuthorization

リダイレクトする認証用URLを返します。はてなの場合は PC / スマホ / 携帯電話 用にそれぞれ違うURLが用意されているので真面目に作る場合はデバイス判定が必要です。

urlTokenCredentials

Access token を取得するURLを返します。

urlUserDetails

ユーザー情報を取得するURLを返します。

userDetails

ユーザー取得APIを叩いた結果をオブジェクトに詰めています。

userUid / userEmail / userScreenName

継承元のメソッドはこれらのメソッドをコールした時に通信してるので、そうしないようにオーバーライドしています。Socialite の実装を参考に書いただけはあんまり深い意味はないです。

AuthServiceProvider に登録

独自ドライバを実装したら使えるように登録します。AuthServiceProviderboot メソッドにこんな感じで。

<?php
class AuthServiceProvider extends ServiceProvider
    public function boot(GateContract $gate)
    {
        $this->registerPolicies($gate);

        \Socialite::extend('hatena', function($app) {
            $setting = $app['config']['services.hatena'];
            $config  = array_merge([
                'identifier'   => $setting['client_id'],
                'secret'       => $setting['client_secret'],
                'callback_uri' => $setting['redirect'],
            ], $setting);
            return new HatenaProvider($app['request'], new HatenaServer($config));
        });
    }
}

使ってみる。

<?php
// routes.php
// view にはこんな感じで書く

// <p><a href="{{ url('github/ahthorize') }}">github login</a></p>
// <p><a href="{{ url('hatena/ahthorize') }}">hatena login</a></p>


Route::get('{provider}/ahthorize', function ($provider) {
    return Socialite::with($provider)->redirect();
});

Route::get('{provider}/login', function ($provider) {
    /** @var \Laravel\Socialite\Contracts\User $data */
    $data           = Socialite::with($provider)->user();
    dd($data);
});

シンプル!

参考

Consumer key を取得して OAuth 開発をはじめよう - Hatena Developer Center

宣伝

よろしくおねがいします!

www.amazon.co.jp

リリース間近!5.2 の新機能と変更点

この記事は Laravelリファレンス発売記念!販売促進!! Advent Calendar 2015 - Adventar の 12/1 ぶんの記事です。

注意

長いので、ブックマークでもして後で読むといいのではと思います。せっかちな人のためにまずは結論から。

リリースはいつ頃?

まもなくでしょう。昨日(11/30) symfony 2.8 / 3.0 がリリースされました。この両バージョンはAPIの互換性があるようで、Laravelの各 composer.json には "symfony/http-kernel": "2.8.*|3.0.*", のように書かれています。

移行すべき?

5.1 のユーザーであれば特に必要を感じないかな…というのが僕の感想です。ただ、非推奨・削除されたクラス・メソッド・関数等がそれなりにあるのでキャッチアップしておかないと、バージョンアップで苦労しそうです。

試してみたい

https://github.com/laravel/laravel.gitgit clone して branch を develop に切り替えてください。その後に composer install すれば完了です。

新機能

さて、5.2 の新機能を紹介していきましょう。今回のバージョンアップでは破壊的なものはないので「バージョンあげたいが…ぐぬぬ…」となるようなこともないでしょう。

Implicit model binding

ルートを解決して処理を行う前にパラメータを精査してモデルを findOrFail あるいは find した状態でインジェクションする機能です。

<?php

// http://localhost:8000/test/1
Route::get('test/{user}', function(\App\User $user) {
    // find された値が入っている
    dd($user);
});

// http://localhost:8000/users/1
Route::get('users/{user}', 'UserController@index');

注意点としては、ルートパラメーターの名前をモデルの名前と合わせる。test/{user} の部分ですね。もうひとつは引数にデフォルト値をつけないと findOrFail が実行されるということです。モデルが見つからない場合でも例外を起こしたくない場合は

<?php

// http://localhost:8000/test/1
Route::get('test/{user}', function(\App\User $user = null) {
    // find された値が入っている
    dd($user);
});

のように引数にデフォルト値をつける必要があります。

Appending output from scheduled tasks

スケジュールの出力を任意のファイルに出せるようになりました。これ 5.2 の新機能として紹介されていますが 5.1 にも入ってます。

Collections Wildcards

Collection でワイルドカードが使えるようになりました。Eloquent 等でリレーションを使うときに便利だと思います。

[5.2] Add support for nested indexed arrays to array_pluck and data_get by JosephSilber · Pull Request #10709 · laravel/framework · GitHub

使い方としてはテストコードが参考になるかと思います。ここらへんとか

Form Array Validation

上記Collections Wildcardsが入ったのもあって Validation で配列を使用する例が楽になっています。

Database Session Driver

データベースにセッションを保存するときのテーブルに user_id, ip_address, user_agent の項目が増えました。互換性を保つために lagacy_database というドライバが増えています。このドライバは5.2で非推奨となっており、おそらく 5.3 で削除されるでしょう。

新機能はざっくりと以上です。次は変更点を。長いです

削除されたもの

5.1 で非推奨になったものが削除されました

非推奨

  • Strクラスの randomBytes メソッドが非推奨に
    • php7 の random_bytes を視野に?
    • 5.3 は php7 か?
  • Route::controller / Route::controllers が非推奨(5.3で削除)
  • Collection の lists メソッドが非推奨に
  • array_build が非推奨

小さな変更

  • Facade クラスの getFacadeAccessor が abstract メソッド
  • Seeder クラスの run メソッドが abstract メソッド
  • guzzlehttp/guzzle ~6.0
  • php7 の Throwable サポート
  • validateSame/validateDifferent が型までチェックするようになった

現場からは以上です。

宣伝

一番大事なこと忘れてた…

www.amazon.co.jp

発売されます!よろしくおねがいします!