Serializerを使ってPHPでのJSONと配列やオブジェクトの相互変換を楽にする
Serializerとは
PHPの配列やオブジェクトをXMLやJSONにシリアライズしたり、その逆にデシリアライズすることができるライブラリです。
PHP向けのre:dash APIクライアントを作っている時に見つけました。
SymfonyにもSerializerというコンポーネントがありますが、Githubのスター数が多いという理由で今回はschmittjoh/serializerを選択しました。
Githubのスター数こそ少ないですが、Symfony内部で使われていそうなので、実ユーザーはこちらのほうが多いかもしれません。
インストール
Composerでインストールできます。
$ composer require jms/serializer
使い方
簡単なサンプルコードで使い方を紹介します。
サンプルコード
シリアライズ
<?php $loader = require_once './vendor/autoload.php'; $data = [ ['name' => 'PHP', 'description' => 'PHP is a popular general-purpose scripting language that is especially suited to web development.'], ['name' => 'Ruby', 'description' => 'A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.'], ['name' => 'Go', 'description' => 'Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.'], ]; $serializer = JMS\Serializer\SerializerBuilder::create()->build(); $jsonContent = $serializer->serialize($data, 'json'); echo $jsonContent;
これを実行するとこんな感じになります。
$ php example.php [{"name":"PHP","description":"PHP is a popular general-purpose scripting language that is especially suited to web development."},{"name":"Ruby","description":"A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write."},{"name":"Go","description":"Go is an open source programming language that makes it easy to build simple, reliable, and efficient software."}]
JSONがPretty printされていないので読みにくいですが、配列がJSONに変換されていることがわかります。でも、これはjson_encode
関数とあまり変わらないですね。
デシリアライズ
シリアライズのサンプルコードを少し改変して、JSONからのデシリアライズも試してみます。
<?php $loader = require_once './vendor/autoload.php'; use Doctrine\Common\Annotations\AnnotationRegistry; use JMS\Serializer\Annotation\Type; AnnotationRegistry::registerLoader('class_exists'); class Language { /** * @Type("string") */ public $name; /** * @Type("string") */ public $description; } $data = [ ['name' => 'PHP', 'description' => 'PHP is a popular general-purpose scripting language that is especially suited to web development.'], ['name' => 'Ruby', 'description' => 'A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.'], ['name' => 'Go', 'description' => 'Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.'], ]; $serializer = JMS\Serializer\SerializerBuilder::create()->build(); $jsonContent = $serializer->serialize($data, 'json'); // echo $jsonContent; $serializer = JMS\Serializer\SerializerBuilder::create()->build(); $object = $serializer->deserialize($jsonContent, 'array<Language>', 'json'); var_dump($object);
JSONからオブジェクトにデシリアライズする場合は、使用するクラスのメンバー変数にアノテーションを付ける必要があります。
ここでは、Language
クラスを用意し、JSONをLanguage
オブジェクトの配列にデシリアライズしています。
実行してみると、以下のような感じです。
$ php example.php array(3) { [0]=> object(Language)#23 (2) { ["name"]=> string(3) "PHP" ["description"]=> string(97) "PHP is a popular general-purpose scripting language that is especially suited to web development." } [1]=> object(Language)#6 (2) { ["name"]=> string(4) "Ruby" ["description"]=> string(156) "A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write." } [2]=> object(Language)#27 (2) { ["name"]=> string(2) "Go" ["description"]=> string(111) "Go is an open source programming language that makes it easy to build simple, reliable, and efficient software." } }
まとめ
REST APIを使う場面では、ほとんどの場合JSONを使うことになりますが、決まった形式のJSONであればSerializerを使うことでPHPでの扱いが楽になるかもしれません。
さくらインターネットのArukasでSlackのBotkitを動かしてみる
Arukasとは
さくらインターネットが提供しているDockerコンテナーのホスティングサービスです。Container as a Serviceとでも言ったらいいのでしょうか。
2016年5月現在はベータ期間中なので無償で利用することができ、現時点での料金プランではEssentialプランで3コンテナーまで無料とのことなので、ベータ期間が終わってもちょっとだけ使ってみたいというのであれば、無料で使用できそうです。
今回は、このArukas上で発言に反応するようなBotが動作するDockerコンテナーを起動し、動作確認するところまでをやってみます。
SlackのBotユーザーを作成する
Botの作成にはBotkitを利用します。
Botkitを利用するには、SlackのBotユーザーが必要です。以下のリンクからBotユーザーの追加ができるので、適当に名前を決めて登録し、BotユーザーのAPIトークンを取得します。
既存のBotユーザーがある場合はそのユーザーのトークンを利用することもできます。
https://my.slack.com/services/new/bot
ここで取得したBotユーザーのトークンは、後ほどArukasの設定で使用します。
Arukasの設定
Arukasにログインし、新しいアプリケーションを追加します。
その際、主要な項目は以下のように設定してください。
- Image: ariarijp/botkit
- Instances: 1
- Memory: 256MB
- Endpoint: (空白)
- Port: 8080 tcp
- ENV: 指定する
ベータ版の時点ではDockerイメージはDocker Hubからのpullのみの対応となっており、プライベートリポジトリには対応していないようです。今回使用するイメージは、この記事にあわせて作成したものとなりますが、Botの挙動を変更したい場合は、元のリポジトリをForkするなどして、JavaScriptを書き換えることになります。
また、ArukasはWebアプリ向けに作られているのか、必ずひとつ以上のポートを公開する必要があります。
発言に反応するBotを動作させる場合はポートを公開する必要がないのですが、今回使用するコンテナでは、SlackのSlash Commandのエンドポイントも含めており。そのエンドポイントが使用するポートを番号を指定しています(Slash Commandの設定については割愛します
各項目を入力したら、設定を保存してアプリを起動します。
アプリの起動後、詳細画面で「アプリは起動状態です」と表示されていれば、正常に起動ができているということになります。
動作確認
最後にSlackで動作確認します。アプリが起動している状態でSlackを見ると、Botユーザーがログインしている状態になっています。
この状態で、テストで利用するチャンネルにBotユーザーを招待し、以下のようにメンションをつけてメッセージを投稿します。
@Botユーザー名 hello
メッセージを「hello」とBotユーザー宛に投稿すると「hello」とBotユーザーはメッセージを送信します。
まとめ
今回は単純なBotをArukasにデプロイしただけですが、Dockerコンテナーに依存関係を押し込んでしまうことで、デプロイ先の環境などを気にせずBotを開発できますね。
しかし、Arukasはまだコンテナー同士のリンクや永続的なストレージには現時点で対応していないため、データが揮発することを考えてアプリを実装する必要があることには注意が必要です。
参考
PHP-FPMのステータスをメトリクスとして収集するMackerelプラグインを作った
週末にまとまった時間ができたので何か書こうと思った結果としてできた。
(6/30更新:本家にマージしていただきました!)
使ってみるとこんな感じ。Queue関連のメトリクスを実際の値でテストしたかったけれど、Backlogとかその辺がいろいろわかってないせいかできなかったので以下の動作イメージでも0のまま。
インストールは適当にgo get
して$GOPATH/bin
からコピーするのを想定。
ひさしぶりにGoを書いたのでMackerelのヘルプを写経してから書いた。
ヘルプをよく読めば気づいたことではあるけど、メトリクスはuint64
またはfloat64
でないと送信できないことに気づくまで2時間近くハマってしまった。それがなかったら1時間ちょっとで大体の処理は書けていたと思う。
テストコードではHTTPリクエストをモックできるhttpmockを使ってみた。
大したものではないけど、久しぶりに没頭できたので良い気分転換になった。
PHPでSlackに例外を通知するときに便利なariarijp/exception-to-slack-attachmentsを作った
ほとんどREADMEの内容に書いてあることだけど、ひさしぶりにブログも書いてみることにしました。
何がしたかったのか
PHPで例外を捕捉してSlackに通知する時に、SlackのMessage Attachmentsを使って見やすく通知したかったので、
PHPでSlackを連携するのによく使われるであろうmaknz/slackで使えるAttachmentsの配列を例外オブジェクトから生成するようにしました。
使い方
composer.jsonを用意してcomposer install
する。既存のcomposer.jsonに追記する場合はcomposer update
をするなどうまい具合にしてください。
"require": { "ariarijp/exception-to-slack-attachments": "dev-master" }
try-catchやフレームワークの例外ハンドラー内で例外オブジェクトを受け取ってSlackに通知する。といった使い方を想定しています。
以下はtryの中で例外を発生させ、その例外情報をSlackに通知する例です。
<?php require_once __DIR__.'/vendor/autoload.php'; use Maknz\Slack; use ExceptionToSlackAttachments\ExceptionToSlackAttachments; try { throw new \Exception('Something went wrong'); } catch (\Exception $e) { $attachments = ExceptionToSlackAttachments::toAttachments($e); $client = new Slack\Client('http://your.slack.endpoint'); $client->to('#general') ->attach($attachments) ->send(); }
例外は以下のような感じで通知されます。
Shibuya.go#1に参加して、あとで調べたくなったことメモ
昨日に引き続きGo関連のイベントに参加してきました。
Goを実践的に使っている話が多く、昨日のGoもくもく会とは違った形で刺激をうけました。
発表のなかでいくつか使ってみたいものがあったので、忘れないようにメモしておきます。
eapache/channels
Channelの扱いを楽にできそう。
Songmu/goshim
よりよい go run
。
karupanerura/gostress
HTTP(S)のストレステストツール。いろいろ参考にできそう。
walter-cd/walter
Serverspecでも有名なmizzyさんが参加されてるビルドツール。会場ではJenkinsつらい問題対策への期待感を感じた。
yusukebe/revealgo
かっこ良すぎるプレゼンツールreveal.jsを便利に使えるCLIツール。perlで作ったプロダクトの移植とのこと。
gin-gonic/gin
Go界隈で今は人気がありそうなWAF。
Chronograf
TSDBのInfluxDB向け可視化ツール。
その他
ariarijp/horenso-reporter-slack
songmuさんのスライド中で自作のツールを紹介していただいた。
horensoのreporterとしてSlackに結果を通知するCLIアプリ。
嬉しかったけど驚いて変な汗が出た。
まとめ
次回も開催決定しているとのことで、抽選あたったら参加したい。
内容が濃い会だったので、もうちょっとGoを使っておきたいところ。
主催のVOYAGE GROUPさん。ありがとうございました!おしゃれなオフィスだったなー。