ytake blog

Web Application Developer

PHPカンファレンス2018でApache Sparkの話をしました #phocon

2018年のペチコンも楽しかった!

f:id:ytakezawa:20181230010118j:plain

もう二週間前の話ですが、
PHPとApache Sparkで始めるデータ解析処理 という話をしました。

speakerdeck.com

現在公開されている動画はこちら
youtu.be *分割されたものが公開されるらしい

アプリケーションを成長させるためには、  
アプリケーションの開発だけではなく、ログデータや、  
様々なメタデータを的確に利用できるようにすることが重要です。  
このセッションではこれらを叶えるためにApache Sparkによるデータ解析処理と、  
ビッグデータ対応のデータベース、  
PHPアプリケーションを組み合わせてアプリケーションをグロースさせるヒントの実装の考え方をお話しします。

トーク補足

Apache Sparkそのものについては、
たくさんの書籍や、ネット上の記事も多くありますのでその詳細は話しませんでした。
(日本国内の記事よりも海外の記事の方がおすすめです)

Apache Sparkを活用するには、まず活用のポイントを知っておかなければなりません。
小さなアプリケーションだったり、
アプリケーションからアドホックに叩きまくりたい、というケースで導入すると
ミスマッチにもなりますし、
自分たち自身で分散システムの保守・運用ができる体制や知識がないと
デメリットとなりますので、その辺りに軽く触れました。
といいつつもWebアプリケーション系に相性もいいSpark SQLを中心に、
Event SourcingとCQRSのランタイムと同時にシステムを支える考え方を交えて紹介しました。

f:id:ytakezawa:20181230012926p:plain

こうした考え方とミドルウェアの組み合わせは、
大きなアプリケーションだったり、リアルタイム性が重要なアプリケーションや、
マイクロサービスアーキテクチャ化に取り入れることもできます。
データ処理アーキテクチャのLambdaアーキテクチャやKappaアーキテクチャでは、
この処理フローを元に様々な処理を連携させていきます。
現代のアーキテクチャで導入を検討するケースも多いパターンかもしれません。
が、やはり事前にその知識が必要であったりするため、セッション自体は少し難しかったかもしれません。

後半はALS (Alternative Least Squares・交互最小二乗法)を用いたレコメンデーションの作り方について、
IBMで公開されているものを元に処理の流れと実装内容を解説しました。

github.com

実際の開発に導入する場合もこれを元に拡張していくといいかもしれません。
自分はSpark MLlibとElasticsearchとHadoopの組み合わせで、
PythonではなくScalaで実装して利用しています。
これは使えそうだ!と思ったら是非アプリケーションに導入してみてください。

アプリケーション開発をしていると、多くは実装だったり、実装のための設計だったり、
そのためのチームでのMTGだったりと、通常その辺りに時間を多く使われると思います。
が、実装や設計といったものと切り離せないデータベースや、
データ処理そのものの情報を吸収するのは難しく
枯れているからこそこれまでの情報と知識を使いがちになります。

が、サービスの規模が大きくなったり、想定外の成長を遂げるアプリケーションを支えるには
技術面における柔軟性と、状態変化に強くするための知識アップデートが必要になることも多いです。

そんな現代において、コンテンツのレコメンデーションなどに代表される機械学習や、
それを作るための大規模なデータとWebアプリケーションを結びつけるものの具体的なイメージがあれば、
アプリケーション開発へのヒントだったり、ログデータの重要性が見えてきたり、
開発者から行えるサービスへのアプローチの面白さ、みたいなのを知るきっかけになれば、
と思います。

スポンサーとしても参加

毎年登壇はしていたんですが、
今回はせっかくなのでスポンサーとしても参加しました。
会社のみなさんにも協力いただいて(自分はほとんど丸投げだった・・・)
たくさんの方がスポンサーブースに来ていただきました。
感謝

f:id:ytakezawa:20181230010136j:plain
アイスタイルブース

Laravelクイズ的なものを実はQRコードで配布していましたが、
結構ちゃんと考えないといけない内容だった為、あまり遊ばれませんでした
Laravel JP Conference2019でもやろうかな
そんな逮捕用のパネルで遊んでくれた方々。

f:id:ytakezawa:20181230010044j:plainf:id:ytakezawa:20181230010104j:plain

サイン会の様子

ありがたいことに今回は、
今年発売された PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応 のサイン会がありました。
サイン会で完売!!!
多くの方に参加していただきありがとうございました!

PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応

PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応

最後にLaravel JP Conderence2019

ペチコンでも最後に宣伝させていただきましたが、
来年開催される Laravel JP Conference2019の参加申し込みが始まっております!

conference2019.laravel.jp

タイムテーブル自体ももうすぐ公開されますが、
豪華な国内ゲストを迎えてLaravelを軸としたセッションをお届けします。
ゲストの紹介、タイムテーブルの公開は、公式Twitterアカウントをフォローしてチェックしてみてください。

twitter.com

来年は1月の仙台、Hackの話をさせていただきます!
楽しみ!!!!!

Kakfa ConnectでSinkが動かないときの確認メモ

Apache KafkaからHadoopのHDFS転送で、
うまく転送できないものがあり、忘れないようにするためのメモ

アプリケーション自体はいわゆるWebアクセス系のトラッキング

  • メタデータを付与したログデータをFluentdで収集
  • Apache Kafkaのtopicに格納
  • Kafka StreamsでTopicのデータ内で完結する前処理後、他topicへ転送
  • Kafka Streams処理後のデータをHDFSへ転送

connect-distributed

distributedで動かすのは、connect-distributedコマンドで直接実行するか、
または

$ systemctl start confluent-kafka-connect

通常のアプリケーションから送信されるときはJSONにして送ることが多く、
そのままの設定でconnectへ登録しました(Webアプリケーション側にはAvro導入していない)

hdfsへのsink connect例は下記

name=hdfs-sink
connector.class=io.confluent.connect.hdfs.HdfsSinkConnector
tasks.max=1
topics=streamed.purchase_promotion
hdfs.url=hdfs://hdfshostname/path
flush.size=3

key.converter=org.apache.kafka.connect.json.JsonConverter
key.converter.schemas.enable=false
 
value.converter=org.apache.kafka.connect.json.JsonConverter
value.converter.schemas.enable=false
# 省略
format.class=io.confluent.connect.hdfs.json.JsonFormat

正常に登録されたかどうかは、RESTで問い合わせることで判定ができます。

$ curl localhost:8083/connectors
["hdfs-sink"]

対象のconnectorだけを確認する場合は、
curl localhost:8083/connectors/connector-name で問い合わせます。
Fluentdからの転送とKafka Streamsの動作を確認して、
Connectだけが動かない・・・。

確認するところ

connectorのtask状況もRESTで問い合わせて確認できます。

curl localhost:8083/connectors/connector-name/tasks/0/status | jq
{
  "state": "FAILED",
  "trace": "org.apache.kafka.connect.errors.ConnectException: Tolerance exceeded in error handler\n\tat ....(省略",
}

何かエラーが出ているので、その内容を探します。

jacksonでパースエラー発生

Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'hoge': was expecting

topicへ挿入されるメッセージ自体はconsumeコマンドで確認できます。

$ kafka-console-consumer --from-beginning --topic topic.name --bootstrap-server hostname:9092
{"referer":null,"event": "blog"}

JSONで挿入されているので問題はありませんでした。
このデータはいわゆるValueなため、Keyも確認します。
keyを取得する場合は、property print.key=true を指定します。

$ kafka-console-consumer --property print.key=true --from-beginning --topic topic.name --bootstrap-server hostname:9092
hoge.stdout  {"referer":null,"event": "blog"}

どう云ったキーで送信されているかがわかります。
kafka-connectのkey.converterをStringに対応させるには以下のConverterを指定

key.converter=org.apache.kafka.connect.storage.StringConverter

再度登録し直して、転送がスタートされました。

Laravel JP Conference 2019開催について

Laravel JP Conference2019

f:id:ytakezawa:20181008205256p:plain

Twitterなどでももう知っている方も多いと思いますが、

2019/02/16 にLaravel JP Conference2019を開催します。

今回自分が実行委員長を努めさせていただきます。

概要について

概要についてはこちらをご覧ください

Laravelを軸としたカンファレンスになりますが、基本的にはPHP関連を扱うカンファレンスと同等の内容でお届けします。
当日は3会場あり、それぞれの会場は以下のカテゴリで分けて同時に開催されます。

  • Laravelメインのセッション
  • PHP関連システムに関連するセッション・
  • その他企画・実装相談会・ワークショップなど

スポンサーについて

ブロンズとドリンクスポンサー以外は売り切れとなっていますが、
まだ枠はございます。
他にもこういう協力ができるかも、という企業様などがありましたら竹澤までご連絡いただけると幸いです。

twitter.com

Twitterについて

公式のアカウントは以下のアカウントです。

twitter.com

スピーカー募集やチケット販売などは公式アカウントからアナウンスさせていただきますので、
ぜひフォローしてください!

スピーカー募集について

募集開始については上記のアカウントからアナウンスとなりますが、
以下の内容でトークできるぜ!という方は是非お願いします!

  • Laravelのノウハウ・Laravelを実際にこうして使っているよ (商用投入系が望ましい)
  • PHPアプリケーション設計技法について (Laravel問わず)
  • アプリケーションを支えるデータベース設計・ミドルウェア周りについて
  • ワークショップをやりたい

スピーカー応募は10月中旬頃から開始予定です。

チケット販売について

チケットについてはカンファレンス本編のチケット・懇親会チケットと分けて販売されます。
こちらも今月中旬以降に開始予定です。

スタッフ募集について

当日スタッフなどの募集は後日アナウンスされます。
コアスタッフについては現在募集枠として用意している訳ではありませんが、
是非やりたい!という方はご連絡ください!

現時点では一度限りのカンファレンスとしており、2020年は開催する予定はありません。

「PHPフレームワーク Laravel Webアプリケーション開発」執筆しました

新しいLaravel本

今回下記の書籍を執筆しました

PHPフレームワーク Laravel Webアプリケーション開発

Laravelリファレンス の延長という訳ではなく、
機能解説ではなく、実際に開発を行う上でヒントになるような内容になっていると思います。
Laravelに慣れた次のステップに進められるような内容だったり、
バージョン問わず導入できる内容を心がけました。

今回担当したのは、3章、4章後半、6章、7章と10章です。

全体を通してドメイン駆動設計などは盛り込まず、責務分割や、API設計などの視点がいくつか入っています。
いくつかとりあげてみると・・・

3章

幅を広げすぎないようにMVCとADRのみに焦点を絞って、簡単な解説などがあります。
どちらがいい、という話ではなく開発チームの体制や、長期運用するかどうかなどで大きく変わります。
この先の知識や学習するにはどうしたらいいんだろう、
公式ドキュメントだけの使い方だけではない選択肢の一つとして読んでみると楽しめると思います。

4章後半

レスポンスとミドルウェアが主ですが、
少し前に取り上げられることも多かったSSE(ストリームを使ったレスポンス)だったり、
APIの REST Level 3 / HALの導入方法だったり、
これからのアプリケーション開発に導入することができる内容になっていると思います。

7章

EventとQueueの基本に触れながら、データ分析処理などでも用いることが多いCQRSライクな方法に発展します。
大きなアプリケーションではメッセージングをApache KafkaやAmazon SQS、Kinesis Data Firehose、
RabbitMQなどに差し替えてみてください。

個人的なオススメは後半のテスト関連の9章と11章です!

本書は必ずしも初めてLaravelを使う、という方には難しい内容かもしれませんが、
多くの内容はLaravelに限らず導入できる内容になっています。

アプリケーション開発のヒントとして役立てていただければ幸いです。

blog.shin1x1.com

おまけ
f:id:ytakezawa:20180930032902j:plain
厚さに注目!

PHPカンファレンス福岡2018で「Event Sourcing, CQRS For PHP」の話をしました

先日開催されたPHPカンファレンス福岡2018

f:id:ytakezawa:20180704013557j:plain

いいカンファレンスを開催しよう!という福岡の皆さんの気持ちがとても良いカンファレンスで、
今年も登壇しつつ、いろんなセッションに参加したり、 いろんな方と技術なトークができて最高でした。

phpcon.fukuoka.jp

トーク内容

今年はタイトルにもある通り、「Event Sourcing, CQRS For PHPという話をしました。
DDDと一緒に紹介されたりすることも多いものですが、
データ処理方面からの話が主の内容でお届けしました。

ビックデータの処理、といえばphp以外の言語で処理することがほとんどですが、
こういったミドルウェアアーキテクチャを組み合わせることで、 目の前にある課題をシンプルに解決していくためのヒントになることも多く、
データ周りが複雑で、どうやったらいいんだろう、という方にも参考になれば幸いです。

この辺りのテーマは一昨年、去年、今年としばらくデータ処理系の開発や、 アーキテクチャを考えることが多く、
そこで実際に導入した方法や苦労したことなどをphpを通して話をしてるシリーズの一つです。

ytake.hateblo.jp

デブサミ2018 [Apache Kafkaによるスケーラブルアプリケーション開発] で登壇してきました #devsumi

トーク終了後、Ask the Speakerでもたくさんの方が質問してきてくれたり、
ミドルウェア周りの悩みをみんなで話したり、今回この話を選択してよかったなぁと思いました。

Twitterなどでも色々反応いただけてありがとうございました。

参加したセッション

skaffold を使って Kubernetes してみたLaravel Queue でスケーラブルなバッチシステムの構築

PHPerのためのよくわかるCPU脆弱性解説DDoS攻撃との終わりなき戦い

PofEAAで読み解くDoctrine2AI(人工知能)に聞いてみた! - クラウドサービスではじめる動画解析/音声変換 -

そして最後の 物理層のこと、時々でいいから、思い出してください。

でした。

DDoS攻撃物理層の話が特に印象に残りました。
また来年のカンファレンスも楽しみにしています!

カンファレンス前後

カンファレンス前後はやっぱりいつものところでphper大集結でした

f:id:ytakezawa:20180704013547j:plain

ラーメン食べたり

f:id:ytakezawa:20180704013601j:plain

懇親会では良いビールがあったり

f:id:ytakezawa:20180704013639j:plain

今回は会社のステッカーを持って行きました

f:id:ytakezawa:20180704013611j:plain

最高!

そして Laravel JPカンファレンス

さらっとここに記載しますが、
来年Laravel JPカンファレンスを開催します。
東京で開催しますが、2トラック進行とLaravel相談会を用意する予定です。
Laravelづくしのトラックと、アプリケーション開発・設計におけるトラックを考えていますが、
まだわかりません。

こちらはこちらでお楽しみに・・!

HHVM/Hack マイクロフレームワークにCache追加

ytake.hateblo.jp

以前から作ってたフレームワークで、
都度Cache組み込むのが面倒なのと、HackでPSRに準拠する必要もないだろうということで、
JavaEhcacheっぽい名前(名前だけ) のものを作り、
マイクロフレームワークに組み込みました。

github.com

HHVM/Hackにはmemcachedとredisのエクステンションが含まれているので、
なにもしなくても使えるのが楽で良いです。

後日 Mcrouter 対応ドライバも追加してリリースする予定です。

簡単な使い方

使いたいキャッシュドライバーをCacheManagerで指定すると、
そのキャッシュドライバが利用できるようにしています。

が、ドライバー単体でも利用できます

<?hh
use Nazg\HCache\Element;
use Nazg\HCache\CacheManager;

$manager = new CacheManager();
$cache = $manager->createCache('memcached');
$mc = new \Memcached('mc');
$mc->addServers([['127.0.0.1', 11211]]);
$cache->setMemcached($mc);
$cache->createCache('map')?->save('cache', new Element('testing', 0));

独自ドライバ追加方法

Nazg\HCache\CacheProvider クラスを継承していればなんでも使えます
ドライバ実装は下記の通りです。

<?hh // strict

use Nazg\HCache\CacheProvider;

class NullCache extends CacheProvider {
  <<__Override>>
  public function fetch(string $id): mixed {
    return;
  }
  <<__Override>>
  public function contains(string $id): bool {
    return false;
  }
  <<__Override>>
  public function save(string $id, Element $element): bool {
    return true;
  }
  <<__Override>>
  public function delete(string $id): bool {
    return true;
  }
  <<__Override>>
  public function flushAll(): bool {
    return true;
  }
}

上記の登録後は、以下の通りに記述するだけで利用できます。
簡単

<?hh

use Nazg\HCache\Element;
use Nazg\HCache\CacheManager;

$manager = new CacheManager();
$manager->addCache('null', () ==> new NullCache());
$manager->createCache('null'); // return NullCache

Hackで動的メソッドコール実装するヒント

Hackでは基本的に動的メソッドはtype checkerでエラーになりますが、
type checkerが理解できるように記述すればOKです。

CacheManagerは下記の実装になっています

<?hh

  protected Map<string, classname<CacheProvider>> $cache = Map {
    'apc' => \Nazg\HCache\Driver\ApcCache::class,
    'void' => \Nazg\HCache\Driver\VoidCache::class,
    'map' => \Nazg\HCache\Driver\MapCache::class,
    'file' => \Nazg\HCache\Driver\FileSystemCache::class,
    'memcached' => \Nazg\HCache\Driver\MemcachedCache::class,
    'redis' => \Nazg\HCache\Driver\RedisCache::class,
  };

  protected Map<string, (function():CacheProvider)> $userCache = Map{};

  public function createCache(string $namedCache): ?CacheProvider {
    if($this->cache->contains($namedCache)) {
      $cache = $this->cache->at($namedCache);
      return new $cache();
    }
    if($this->userCache->contains($namedCache)) {
      $cache = $this->userCache->at($namedCache);
      return $cache();
    }
    return null;
  }

CacheProviderでは実は下記のようになっており、継承に制約をつけています。

<?hh // strict

namespace Nazg\HCache;

use Nazg\HCache\{Cacheable, FlushableCache};

<<__ConsistentConstruct>>
abstract class CacheProvider implements Cacheable, FlushableCache {

}

コンストラクタに何かを付け加えることはできませんので、
インスタンス生成方法が統一されていますので、type checkerが 通ってよし と判断しています。

フレームワークへの組み込み

Containerにインスタンス生成方法等を登録します。

設定値はクラスでは関与せず、外から与えるものとしてshapeで縛っています。

<?hh

abstract class CacheServiceModule extends ServiceModule {
  protected Driver $defaultDriver = Driver::File;
  <<__Override>>
  public function provide(FactoryContainer $container): void {
    $container->set(
      CacheManager::class,
      $container ==> new CacheManager(),
      \Ytake\HHContainer\Scope::SINGLETON,
    );
    $container->set(
      CacheProvider::class,
      $container ==> {
        $manager = $container->get(CacheManager::class);
        if($manager instanceof CacheManager) {
          return $this->detectCacheProvider(
            $manager->createCache($this->defaultDriver),
            $this->cacheConfigure($container)
          );
        }
        throw new \RuntimeException("Failed to resolve " . CacheProvider::class);
      },
      \Ytake\HHContainer\Scope::SINGLETON,
    );
  }

  abstract protected function cacheConfigure(
    FactoryContainer $container
  ): CacheConfiguration;

  protected function detectCacheProvider(
    ?CacheProvider $provider, 
    CacheConfiguration $cacheConfigure
  ): CacheProvider {
    invariant($provider instanceof CacheProvider, "provider type error");
    if($this->defaultDriver === Driver::File) {
      if($provider instanceof FileSystemCache) {
        $dir = $cacheConfigure->getFileSystemDir();
        if(!is_null($dir)) {
          $provider->setDirectory($dir);
        }
      }
    }
    if($this->defaultDriver === Driver::Memcached) {
      if($provider instanceof MemcachedCache) {
        $m = $cacheConfigure->getMemcached();
        if(!is_null($m)) {
          $provider->setMemcached($m);
        }
      }
    }
    if($this->defaultDriver === Driver::Redis) {
      if($provider instanceof RedisCache) {
        $r = $cacheConfigure->getRedis();
        if(!is_null($r)) {
          $provider->setRedis($r);
        }
      }
    }
    return $provider;
  }
}

このクラスを継承し、利用者がどこから設定値を持ってくるかを指定すれば適切に起動します。
設定値のshapeは下記の通りです。

<?hh // strict

namespace Nazg\Cache;

type MemcachedServer = shape(
  'host' => string,
  'port' => int,
  ?'weight' => int,
);
type FileSystemConfig = shape(
  'cacheStoreDir' => string
);
type MemcachedConfig = shape(
  'servers' => ImmVector<MemcachedServer>,
  ?'persistentId' => string,
);
type RedisConfig = shape(
  'host' => string,
  ?'port' => int,
  ?'password' => string,
  ?'prefix' => string,
  ?'readTimeout' => float,
  ?'persistent' => bool,
  ?'database' => int
);

Skeletonへの組み込み

フレームワークのSkeletonを使えばこの辺りはデフォルトで対応しています。

github.com

設定値は下記で用意しています。(cache.global.php)

<?hh

use Nazg\Cache\Driver;
return [
  \Nazg\Foundation\Service::CACHE => [
    /*
     * Supported "apc", "map", "file", "memcached", "redis", "void"
     * Driver::Apc, Driver::Map, Driver::File, Driver::Memcached, Driver::Redis, Driver::void
     */
    'driver' => Driver::Memcached,
    'drivers' => [
      Driver::File => shape(
        'cacheStoreDir' => __DIR__ . '/../storages/cache/',
      ),
      Driver::Memcached => shape(
        'servers' => ImmVector{
          shape(
            'host' => '127.0.0.1',
            'port' => 11211,
            'weight' => 100,
          ),
        },
        // 'persistentId' => 'rename',
      ),
      Driver::Redis => shape(
        'host' => '127.0.0.1',
        'port' => 6379,
        'database' => 0,
        // 'password' => '', // optional
        // 'prefix' => '', // optional
        // 'readTimeout' => 1, // optional
        // 'persistent' => false, // optional
      ),
    ],
  ],
];

PHPerKaigi2018 Hackについて、と Laravel相談会司会担当で参加しました

*先日開催されたデブサミ2018での発表 [Apache Kafkaによるスケーラブルアプリケーション開発] については、
会社のブログに記載していますので、そちらを参照ください。

PHPerKaigi 2018は最高だった

お世辞抜きで良いイベントでした。
数週間前にデブサミという大きなイベントで登壇していたのもありますが、
規模感がすごくよかった。

それに各登壇者の方々(自分は除き)が、日本のPHPの第一人者といってもおかしくない方々と、
PHPと関わりのあるデータベース界隈から最高な方々が集まり、
参加した全ての方にいい刺激になったイベントだったのでは、と思います。

タイムテーブルの関係でTrack Aのほとんどのセッションに参加できませんでしたが、
ベストトーク賞に選ばれた後藤さんの内容は忘れないように気をつけていきたいと思います。

speakerdeck.com

Laravel相談会司会担当

phperkaigi.jp

3/10の朝一からLaravel相談会の司会を担当していました。

最初は数人から始まったのもあり、
純粋な質問会だったり、実装相談みたいなところから始まりましたが、
参加された方同士で意見交換が行われたり、
実際に使っている情報だったりが出てきて、相談のテーマが広がっていったり
まさにKaigi的な発展をしていったのがすごい楽しかった。

参加者の方々同士のコミュニケーションに発展していったり、
よくあるカンファレンスの一方向のトークではなく、
まさにsocket.ioみたいな双方向通信のコミュニケーションが生まれていくのは、
イベントとしてもかなりいい体験の提供ができる可能性があると思いました。

海外のカンファレンスで同様のものがあって、とりあえずやってみた、という長谷川さん!
やらせていただいてありがとうございました。

他のイベントでも是非またやりたい・・・!

自分は登壇よりもこういった相談会的なものの方が、
いろんな方の話が聞けるし、自分の糧にもなるので好みです。
*自社でもそういうことをしたりしているのもありますが

Hackについて話した

内容は以前にブログに書いたことの裏側です。

ytake.hateblo.jp

ytake.hateblo.jp

Hack自体は結構前から好きで使っていて、
実際に導入した時に今後使い続ける時に、
分離が進む中でPHPフレームワークに左右されるのも嫌だなーという思いから、
Zend Expressiveの挙動が好きだったのと、
LaravelのServiceProviderライクにシンプルに依存定義したい、
というのを混ぜてHTTP Request/ResponseとMiddleware以外の概念を取っ払ったものをHack専用に作り、
興味がある人のきっかけになればいいな、
という想いから今回そのテーマで話すことにしました。

Hackを気軽に始めるには、
数年前のHHVMとPHPの関係性の知識だけでは古くなっているのもあり、
最近の事情だったり、ライブラリを混ぜて紹介しながら、
実際の例も混ぜてみました。
strictにしなければ、結構簡単だったりしますので、
興味持った方は是非チャレンジしてみてください。

現在のPHP界隈で言われる型を意識した実装や、
テーマに興味がある方は結構マッチすると思っており、
逆にゆるふわなところが好みであれば戸惑うことも多いと思います。

Q&A

発表後にいくつかQ&Aがありました。
(いつも自分の発表にQ&Aがあまりないので嬉しかった・・)

バックボーンなどについて

PHPとHackは似ています、がやはり解決したいものが違うため、
JavaScalaのような関係だと自分自身は思っています。

どういう時にHackを選択するのか

I/Oが発生する通信や、MySQLへの問い合わせなど、
今回のトークにはありませんがAsync Awaitがあったりしますので、
そういった部分や、
PHPよりももっと堅実なアプリケーション開発を行う場合や、
Hackではコード内にHTMLを含ませることができなかったり(XHPで)、
XHP自体も脆弱性が生まれないように考えられていたりしますので、
そういったものがマッチすれば十分に選択肢となるのではないでしょうか?

実際に開発で利用するとわかると思いますが、
VectorなどのCollectionは使い勝手もよく堅くなりますので、
コード量が減る、というのもあります。
不確実な型の判定がなくなりますので、これだけでも十分だと思います。

初心者に勧められるかどうか

人によっては勧められる、といえるかもしれませんが、
自分自身 突然Rustを勧めるようなものだと思っており、
型が厳格なためチームでのアプリケーション開発はかなり良いと思っていますが、
教育コストと、導入者自身が理解していないと難しいと思いますので、
必ずしもYesとは言い難く、
HHVM/Hackにはたくさんの概念があり、まずはPHPを触れてみて、というのが良いかなと思います。

ちなみに実はそこまでパワープレイしていません!!!(笑)

当日の資料はこちら

speakerdeck.com

残念・・・!

健康について

去年ヘルニアで入院+しばらく休んでいたのでその体験を元に10分喋りました。

気をつけましょう!

当日の様子はこちらをどうぞ

togetter.com

今年のPHPイベントは始まったばかり!
次のイベントも楽しみですね!
いくぞ!福岡!(いきます