PHPerKaigi 2021 プロポーザル一覧
無駄な物をなるべく作らないリプレイス戦略

6年続くWebサービスをリプレイスすることになりました。
あなたならまず最初に何から手を付けますか?
このトークでは、弊社(コネヒト)が運営するママ向けNo.1アプリである「ママリ」のシステムの一部(CakePHP2.x / PHP7)をリプレイスしている状況を共有したいと思います。
長年に渡って機能改修が繰り返され、複雑なドメインを有するサービスは単純にフレームワークを新しくしたり、あるいはLaravelなど別のフレームワークに載せ替えるだけでは解決できない問題がたくさんあります。
様々な工夫を凝らし、今回の基本戦略である「無駄な物をなるべく作らない」という方針でどうやってリプレイスを進めているのか、具体的なプラクティスを交えながらご紹介します。
PHPでImageMagickとICUを使って画像に縦書きテキストを描画する

PHPで画像に縦書きテキストを描画する話です。
横書きテキストしか描画できないImageMagickと、ICU (Intl) を使って実現します。
発表では以下の内容を踏まえて縦書きテキストを画像に描画する方法とその要素技術についてお話しします。
- 縦書きテキストとは何か
- テキストを構成する文字について
- 文字を描画するためのフォントファイルについて
- フォントファイルを扱う時に便利なttxというツールについて
- PHPから使えるImageMagickについて
- PHPから使えるICUについて
- 文字列を折り返すということについて
静的型解析を用いた大規模レガシーコードのリファクタリング計画

2021年のPHPはPHPStanやPhan、Psalmを用いる事で型検査や不要なコードの検出が可能です。
新規のプロジェクトでは、初期から静的解析ライブラリを導入することにより実行時エラーをデプロイ前に検出することができますが、古くからあるプロジェクトでは、導入しても十分に静的解析の力を発揮することができない場合があります。
古くからあるプロジェクトに静的解析ライブラリを導入するために、何が静的解析の障害となっているか調査しました。
計画的にレガシーコードのリファクタリングを行なうために行なったコードの解析手法についてお話しします。
トラブルのない決済システムを作ろうと奮闘したお話
トラブルの耐えない決済システムをPHP×Laravelフレームワークでリプレイスするにあたって、どのような課題に対して、どうやって改善したかをお話します。
前半20分は、リプレイス後の決済システムのしくみについて、後半20分は、20万レコード更新を同期処理で実現したことについて、弊社DBAのyoku0825さんと感想戦をします。
Terraformのレポジトリ、ディレクトリ構成どうする?

AWS,GCPなど様々なクラウドリソースのコード管理を実現するTerraform。
小規模なインフラ構成であれば単一レポジトリにディレクトリを分けずに配置して、シュッとお手軽に利用できます。
しかし、大規模な構成になってくると、途端に管理が面倒になり、ベストプラクティスも存在しない世界になります。。
このトークでは、Terraformのレポジトリ、ディレクトリ構成について、これまでの苦闘した軌跡と、現状のベストだと思う構成、将来的にどうあると良いと考えているか?について話します!
トーク後にはぜひみなさんとディスカッションしていきたいです〜
PhpStorm使ってるんなら.ideaは共有していこうぜ!!

「より良くPhpStormを使うために、コーディング規約やテスト実行の設定をプロジェクトやチームで共通化しよう」
.idea/
ディレクトリを.gitignoreで無視するように設定しているレポジトリをよく見かけます。
もし”慣習的に”そうしているのであれば、勿体ないかも知れません!
普段の開発にPhpStormやInteliJ IDEAファミリーを利用している方も多いのではないかと思います。
高機能でありながら、「少しだけ」使う分にも充分に威力を発揮することには、ユーザーの皆さんも同意されるのではないかと思います。
他方で、「設定しなければいけない項目」も少なくないのも事実です。
Inspectionの設定、Interpreterの設定、テスト実行の設定・・・
これらを「PJメンバー全員で同期する」ことができれば、一気に効率が良くなります。
「生産効率」の水準が揃う、という手段となります。
そのための手段が「.ideaを共有する」なのです!!
どのように使えば良いのでしょうか?
また、それによってどこまで実現できるのでしょうか?
本トークを通じて紹介します!
phpinfoの写経します

phpinfoは、インストールする時によく使いますね。
それがどのように動いているのか知りたくなったので、phpinfoを写経してみて、わかったことを共有したいです。
PHP で型と生きる

最近の PHP コードは意外と型の恩恵が得られます。
PHP 7.0 でのスカラ型宣言、7.1 での nullable、7.4 でのプロパティ型宣言、 8.0 での Union や明示的 mixed の導入といった言語自体の機能追加もあるのですが、psalm や phpstan といった静的解析ツールを利用することで、静的型検査や mixed の排除、Type Erasure な Generics の利用といったことさえできます。
このトークではそんな最近の PHP の型事情、ツールについてのお話や、実際に静的解析ツールを最高レベルで利用し型をガチガチにしながら PHP コードを書く際の注意点についてお話します。
PHP7から定数配列がOPcacheに乗るのでKVSを置き換えられるかもしれない話

PHPでは配列の初期化処理がopcode列にコンパイルされて実行されるため、巨大配列の初期化は実行時にコストがかかっていました。ところが、PHP 7からは定数だけで構成された配列リテラル(=定数配列)をコンパイル時に生成して利用するように変わっています。さらに定数配列はOPcacheのキャッシュ対象になっているため、キャッシュヒットすれば巨大な定数配列を生成コストなしで使えるようになっています。本トークでは技術的背景を簡単に説明した上で、定数配列とKVS(APCu・memcached・Redis)で同じ機能を実現した場合の性能比較を行います。
大規模サイトにおけるSEO観点でのURL設計

いわゆる「大規模」と言われるウェブサービスで、SEOを考えるときに直面するのが、「クロールバジェット」と呼ばれている、クロール割り当ての最適化です。
婚活パーティーのポータルサイトであるオミカレでは、最大で4万件以上の婚活パーティーの情報と、それを検索するための都道府県・市区町村・ジャンルといった多種多様なリストが存在し、「ページ」数は膨大なものとなっています。
その膨大な中から「Googlebotに見てほしいページ」にどうやって効率よく誘導するか?はとても大きな課題です。
そこで、2019年6月に行ったオミカレのフルリニューアル以降、直面したクロールバジェットにおける問題や対処法について紹介します。
主な内容
- 立ちはだかるリニューアル前のURL
- 想定通りにならないcanonical
- 第一回リダイレクト祭り
- 居座るはるか昔の日付
- 一筋縄では行かないrobots.txt
- 検索とパラメーターとインデックスとランディング
- 終わらない内部リンクの検証
- 第二回リダイレクト祭り
- これまでの教訓
「組織の技術力を高めよう」って言われたら、どう立ち向かうか?

「プロダクト開発が、メンバーの技術力を高めるのか」「メンバーの技術力向上が、プロダクトの品質や可能性を高めるのか」
皆さんは、この「鶏が先かと卵が先か」に似た構造を持つ問題についてどのような考えをお持ちでしょうか?
本セッションは、自分自身の取り組んでいることを紹介した上で、
オーディエンスの皆さんからの視点や経験を織り交ぜたフィードバックと議論を集め、『共有知』を生み出す試みとしたいと考えています。
(折角のオンライン&録画発表なので!)
この課題を選んだ背景
プロダクト開発や(Web)サービスの提供を行う会社において、
Webエンジニアに求められる主要な成果は「プロダクトを良くする」ことだと思います。
プロダクトをよく出来るエンジニアとは、どういう存在でしょうか?
実は、「プロダクトをよく出来るエンジニア」になるには「プロダクトを開発する以上の技量」が要求されるのではないでしょうか。
ここには大きな矛盾があると考えています。
「プロダクトを良くし続けるには、プロダクトに必要なレベルの技量では足りない」という矛盾です。
これについて、自分自身が、所属先の企業でのロールが変化したのをきっかけに取り組むようになりました。
組織の姿が「プロダクトを作れる」を超えた「プロダクトの未来を作れる」ようになるにはどうすればよいか・・?と現在進行系で考えています。
紹介するお話
例えば、以下のような取り組みが「自分なりに考えたこと」でした。
- 「技術力」を定義する
- プロダクトと技術力の関係
- 自分自身が「技術的な成長」を感じた瞬間を構造化して捉える
- その「良いフィードバックの獲得の仕方」を組織的に再現できないか?
こうした話を「議論のネタ」として提供したいと考えています。
PHP で実行中のスクリプトの動作を下から覗き見る

※ 以前にタガヤスという技術勉強会でお話した内容の改訂版です。
普段我々が使っているコンピュータシステムというのは、階層的なシステムです。
物理法則から電気回路が作られ、ハードウェアが作られ、ハードウェアの上で動くファームウェアや OS があって、更にその上で動くアプリケーションがあって、アプリケーションの中でも C 言語で書かれた PHP 処理系、更にその上で動く PHP で書かれたスクリプト、というように、何重もの階層化がされています。
土台になるものから高く階層を積み上げていく、というイメージで、階層の上のほうにある技術を高レイヤー、下のほうにある技術を低レイヤーと呼んだりします。
PHP のスクリプトというのは比較的高レイヤーに属するプログラムなわけですが、PHP コードがコンピュータ上で実際にはどう振る舞っているのか、どういう仕組みでできているのか、というのは、当然より低レイヤーの技術で成り立っています。
今回のセッションでは、そんな PHP より低レイヤーの世界へ FFI を通じて PHP スクリプトからアクセスし、PHP 自身から階層をぶち抜いてスクリプトの動作を下の方から覗き見てみるという、少しひねくれたことをやる自作のツール、php-profiler についてお話します。
雑に言うと PHP で ELF と procfs と ZendEngine の内部構造体をパースしつつ FFI で外部プロセスのメモリを読み取り、スクリプトの動作を盗み見るお話です。
Documentation as Codeとは何か

私はドキュメント運用のアプローチとして「コードによる生成を含んだドキュメント運用」に興味を持っています。
私はこれを「Documentation as Code」と呼んでいます。そして、そのような概念はすでに世の中にあり、時として「Documentation as Code」と呼ばれているようです。
例えばPHPDocなどはソースコード自体の構造とアノテーションをトレースしてドキュメントの自動生成を実現しています。
OpenAPIのように構造化されたデータとして情報を記述することでドキュメントと同時にAPIクライアントやの自動生成が実現できている例もあります。
テストケースに振る舞いを自然言語で併記しながらテストコードを書くことで結果としてテスト仕様や要求仕様のドキュメントで実現するようなアプローチもあります。
私もシステムやコードからドキュメントを生成するようなツールを少なからず作ってきました。
そういった経験から、本発表では、上記のような「Documentation as Code」を実現するツールを独自にモデル化してそれぞれの特性について考えていきます。
そして本発表を通じて皆さんが「Documentation as Code」に興味を持ってもらえればと嬉しいです。
PHPでCSVを安心して扱うために

令和の世においても根強く利用されるデータフォーマット『CSV』
他サービスとのデータ連携やバルクデータ入出力などで使い勝手が良いため、未だに大活躍しています。
ですが、PHPでは扱うための癖が強く「微妙にダメなのは判っているけど諦めて使っている」「そもそも絶対におかしくなるので編集してから利用、または入れてから編集している」などのつらくきびしい現実がありました。
また、一般的には「変換不能文字があると行ごと無かったことにするiconvストリームフィルタ」や「メモリが枯渇しやすくなるmb_convert_encodingを用いた対応」など、一見安全に対応できたように見えて運用面で深刻な問題を抱える対策が蔓延っています。
このトークではそんな現実と対決し「ダメだと判っていたそれを解決」「そもそもおかしくならないのでゼロストップでデータ入出力」できる方法をご紹介します。
作って理解するDIコンテナ

人は言います——モジュールを疎結合にせよ、と。
人は言います——具象ではなく抽象に依存して実装せよ、と。
ソフトウェア設計におけるベストプラクティスは異口同音に関心の分離の重要性を説きます。SOLID原則の「D」ことThe Dependency Inversion Principle / 依存性逆転の原則を実装するための道具立てとしてDIコンテナ、あるいはIoCコンテナと呼ばれる仕組みが利用されることがあります。
「PHP DI」などで検索すると、さまざまな説明が読めることでしょう。……御託はわかった。しかし昔の私には問題意識も活用方法も理解できず時間は過ぎ去っていきました。フレームワーク嫌いの私も数年も経験を積み、いくつかのフレームワークに触れてそれぞれの長短がわかってくると「Laravelのこれだけ使いたい」とか「CakePHPのここだけ羨ましい」などと考えはじめるものです。
このトークではPHP-DIに触発された簡易的なDIコンテナの実装方法を紹介し、PSR-18のような外部と通信するインターフェイスを分離しオブジェクトの生成をDIコンテナのオートワイヤリングに任せることで、どのように実装を簡潔にできるかを説明します。発表内容は実装にフォーカスしており、設計原則やソフトウェアアーキテクチャについては言及しません。
今回の発表では以下のコードの実装時に得られた知見を含みます。
- 特定のフレームワークに依存せずPHP-DIを用いてオブジェクト生成とメソッドのディスパッチを行なったWebアプリケーション
https://github.com/phppg/phperkaigi-golf - リフレクションを用いてメソッドを動的ディスパッチするライブラリ
https://github.com/bag2php/meta
Laravel Livewire でアプリケーションを作成した話

2020年の10月に「Fukuoka.php Vol.32」という勉強会で Laravel Livewire のデモを発表する機会をいただきました。
概ね好評だったのですが、一部の方から
「キモい」
「ヤバイ」
「怖い」
「負荷で死にそう」
「次世代jQuery」
という感想もいただきました。これらの危惧を払拭すべく個人プロジェクトではありますがLaravel Livewireを使用したアプリケーションを作成しました。
作成したアプリケーションを例に Laravel Livewire の使い方、内部ではどのように動いているのか、作成時に気をつけたことなど説明します。
Laravel Livewire は決して怖くはありません!!!!
スポンサー担当するのは楽しい

エンジニア向けイベントのスポンサー担当をここ数年やっています。
会社としてはもともとそんなに積極的にスポンサー活動をしていたわけではないので、どういったことをきっかけにするようになったかの背景を始め
・スポンサーするにあたって予算とかどうしている?
・効果測定は?
・実務面では何している?
について話します。
このトークをきっかけに、より多くの会社様がエンジニア向けイベントのスポンサーになってもらえればと思います。
もっともそれ以前に、スポンサー担当していると、自社のロゴがイベントサイトに掲載されたり、会場でロゴがあったりするだけでイベント参加が一段と楽しくなるので、そういう楽しさを是非共有したいです。
PHP 8 で Web 以外の世界の扉を叩く

※ PHP カンファレンス 2020 でお話した内容の改訂版です。図表が増えたりデモを失敗しなくなったりします!
PHP は "PHP: Hypertext Preprocessor" の略ですが、この 25 年間で Web は高度化し、複雑化し、それに伴い Web サイトを作るための言語にも、いっそう複雑な機能が要求されるようになってきました。
昨年リリースされた PHP 8 では、満を持して JIT コンパイラ が導入されました。
典型的な PHP アプリケーションは I/O バウンド(DB バウンド)です。JIT はそのような既存のアプリケーションのためというより、これまで PHP が使われてこなかった、使えると思われてもこなかったような、新たな領域への扉を開くものとして、FFI や Preloading との組み合わせを念頭に提案されたものです。
一方、世間の CPU は着実に多コアの時代へと進んできました。今の時代にある程度 CPU を使うアプリケーションを作ることは、JIT を使うだけの話では済まず、何らかの並列処理機構を用いこの多コアの CPU とも向き合う必要があります。
このトークではそんな新時代における PHP を使い、
- FFI でシステムコールを呼び出し外部プロセスのメモリをのぞき見たり
- (非 Web の) GUI ライブラリを利用してデータを可視化したり
- ext-parallel によりプログラムをマルチスレッド動作させたり
- スレッドの動作効率化ため preloading を活用したり
- JIT によりそのようなプログラム全体の動作を高速化したり
といった、一味違った PHP の利用方法への挑戦を紹介するとともに、そこで得られた知見、現状の制限についてお話します。
PHPアプリケーションを無言で落とす方法

比較的モダンなフレームワークでは、例外処理や例外発生時の検知・ロギングが仕組まれていますが、PHPでは検知をすり抜けてアプリケーションを終了させる手段が多数存在します。本セッションではPHPのプログラム実行の仕組みから、どのようにすれば検知の網の目をすり抜けることが出来るのかを解説します。この知識を得ることによって、逆にどのようにアプリケーションを作成すれば、比較的安全を担保できるのかが理解できるようになります。
このトークでお話すること
- PHPの例外検知機構と検知不能が発生する仕組み
- 最後の悪あがき「register_shutdown_function」の仕組み
- 検知不能状態を検知する方法の提案
PHP 8 と V8 (JavaScript) で速さを見比べてみよう!

バージョン 8 にしてとうとう僕らの PHP にも JIT がやってきました!
が、PHP 8 の JIT は生まれたてで、同じ 8 でも JavaScript の V8 にはまだまだ速度的な面で追いつかない部分があります。
PHP と JavaScript のそれぞれについて、おおむね同等の処理を行うマイクロベンチマークのコードを用い、プロファイルをとりながらああだこうだ言いつつ速さの特性差や PHP の現状の限界、得意な点や不得意な点を探っていきます。
■ 想定する聴講者
典型的な Web アプリケーションは主に I/O バウンドとかそういう現実の話は脇に置いておいて、PHP スクリプトの性能や測定方法が気になる人
今後の PHP の性能の伸びしろに思いを馳せたい人
しょうもないマイクロベンチマークが好きな人
■ お話しないこと
明日から業務に使える役立つ知識