PHPカンファレンス 2020を見たので簡単な感想を

コロナなのでオンライン。オンラインのカンファレンス見るのは初。今年そもそもカンファレンス初。あと~関西じゃないPHPカンファレンスも初だな。

ほんと簡単な感想です。アーカイブぜんぶ残るみたいなので興味あるセッションはアーカイブ見ましょう。

スライドへのリンクは、すでにまとめてくれてる方がいるので張らない。

https://qiita.com/ucan-lab/items/c644675ea7da4093c664

前夜祭

「Laravelの黒魔術」が気になったので前夜祭も。オフライン開催だとなかなか行けないが、オンラインだと気軽に行けるのでここは利点。

Laravelの黒魔術

最近もうLaravelのことなら大体わかったぜ、な気持ちだったが軽くノックアウトされた。ほんとに黒魔術的な話ばかりで、最後のHigher-Order Messages以外はまったく知らない話だった。

AliasLoaderはちょっと読んでたのに、ファサードクラスをファイルからオンザフライで作るみたいなことやってるところに気付かなかったのはほんと負けた気分。

時間が足りなくて最後の1つがだいぶショートカットされたのは残念だったが、しっかり黒魔術してて楽しい話だった。

SPAのAPI開発の「やりづらさ」をDDDとオブジェクト指向の発想で解決する

SPAのAPI開発ではまりがちな問題を、オブジェクト指向ドメイン駆動設計のやり方で地道にしっかり解決していこう的な話かな。SPAはようわからんので……。

APIの機能は、ユーザ(≒顧客)のではなく、フロントエンドの要求に合わせて作ることが大事、そうした方がサーバサイドでもいい感じでやれる、みたいな話は普段サーバサイドのコード書いてても似たようなこと考えるので納得できた。

あともちろん、引数増やして混乱したメソッド作るのではなく機能ごとにたくさんメソッド作れをAPIに適用するみたいな話も。APIも普通のメソッド・関数も、最終的には同じように扱うのがいいのかもしれない。

本編

PHPの今とこれから2020

基調講演なのかな。PHP 8の新機能や変更点の話が割と多かった。いろいろ使いたい機能あるので早く仕事で使いたいところだがさて。

PHP WEBアプリケーション設計入門――10年先を見据えて作る

ドメイン駆動設計入門の著者によるセッション。DDDは特に関係ない、むしろレイヤードアーキテクチャ方向。10年後に困らないためにフレームワークに依存せず、一方向の依存できれいに設計してやろうという話。

すごく面白かった。とはいえ異論もあって、個人的には10年後に困る理由ってフレームワークへの依存じゃなくて、単純に設計・実装が駄目駄目なのが原因だと思うので、フレームワークはもっと活かして行っていいと思う。

スポンサーLT

「トイサブ!」さんにぜんぶ持って行かれてた。

ゼロベースから Laravel を用いた API 実装オートメーション

この時間帯失敗して、Track1とこれで迷ってふらふらしたりして最初の3分の1ちゃんと聞けなかった。工数をがっつり削減するために高度な自動生成するという話ですごい趣味に合った話なので、ちゃんと最初から聞けばよかった。

内容的にはもっと実装レベルの話を聞きたかった。特に気になるのが自動生成って基本的に危ないものだと思ってて、特にこれほど大量にコードを生成するような場合、自動生成後のコードと同等の機能をライブラリとして作った上でライブラリで定義を読んで動かす方が安全だと思うんだけど、どうしてそういう方向にならなかったのか、ってあたりで、そのためにももっと具体的なところが知りたかった。

このセッションでは通信環境の問題か音質がかなり厳しかったのは残念。オンライン開催のデメリットか。

PSRで学ぶHTTP Webアプリケーションの実践

ちょっと想定レベルがわからなかったかな。最初の半分なしで始めてよかったような。最後時間余ってからの話がいちばん面白かった。

Composer 2.0って何?どう変わるの?読んでみました!

Composer 2の高速化が実装レベルでどうしたなのかみたいな話。コンパクトにまとまっていてよかった。

前ちょっとした事情からComposerのメタデータファイルの構成はある程度把握してたので、より楽しく聞けた。

最後ちょっと駆け足になったのは残念。

今こそ理解する、PHP日時計

思ったより基本的な話だった。昔はdate()やらstrtotime()やら使ってて、そこから一足飛びに今ではCarbonなので、DateTime周りの話を聞けたのはよかった。

効果的な静的解析のCI導入パターンを求めて

静的解析をCIで導入する話なんだけど、単に導入するだけでは駄目で、うまく運用していくためにはどうするか、についてのパターンをめっちゃいい感じに説明してくれた。

ちゃんと導入したことはないけど、とりあえず人の書いたコードとかどうこうする前に使ったくらいはあって、じっさいそういうときに最初からすごいエラーが出てまあ大変なんだけど、そういうのどうするかみたいな話もしっかりあってよい。これ見たら俺も静的解析導入できそう! となる。

今回の見た中でベストだったかも。

微妙な違いも見逃すな!ビジュアルリグレッションテスト!

割とフロント寄りの話。そっちは専門じゃないんだけど、画面をそのままテストする系の話は興味がある。昔HTMLの差分をそのままテストするようなツール書いたことがあって。

Atomic Designとかも名前聞いたことある以上ではないくらいさっぱりだったけど、その辺も必要なところは説明してくれた上での話だったのでわかりやすかった。

フロントエンドはいろいろクールだなあとか、それでもこういうテストやるには地道にいろいろ用意必要みたいで大変そう、とかそういう感想。

LT

基本時間内でまとめきっていてすごかった。内容もどれもよく、LTじゃなくてフルタイムのセッション聞かせてくれ、というのがいくつもあった。ここは印象深いいくつかだけ感想。

エンジニアでもできる簡単親切エラーUI

フォームでエラーをどう見せるかの話。ポップで動きがあっていいスライド。

誰にどうしてもらうためのエラーか、それを全うするためにどう表現するか、というまあ基本的な話ではあるんだけど、スライドのよさもあってとにかくわかりやすい。

チームメンバーをエンパワーメントしよう!レガシープロジェクト改善事始め

あら、今見るとスライドが権限なくて見れないとかなってるな。

チームをよくするために外堀から埋めるみたいな話。こういうツールでこうやっていくというだけではなく、やりやすい・やってもらいやすいところから少しずつ、じっくりやっていかないと駄目だよー、的な話。だったはず。

自分は基本一人でやるんだけど、たまにほかのプログラマと仕事するときにもっといろいろなんとかしたい! と思ってはなかなかできずに、みたいなことが多いので、こういう話はほんと参考になる。

静的解析から始める負債コード解消

静的解析でCIなセッションもあったけどこっちはちょっと違って、PhpStormのInspection機能を使って、すぐに始められるという売りの話。

俺はVimだけど最近はvim-lsp + Intelephense使ってて、これでもちょっとした型の問題なんかは見つけてくれて便利だけど、PhpStormのInspectionはさらに自前でこういう感じのコードがあったらエラーにしたい、みたいなことができるらしくてすごい。

オンラインカンファレンスのよかったところ・いまいちだったところ

よい

  • 前夜祭に気楽に行ける。大体行けるカンファレンスが大阪で、それでも片道2時間くらいはかかるので、なかなか前夜祭までは……という感じだったがオンラインなら片道0秒なので余裕。
  • トイレに困らない。ある程度大きなカンファレンスでは基本トイレは並ぶのでつらいけど、オンラインなら自宅トイレなので余裕。

いまいち

  • 見るセッションに迷うと、簡単にあっち見てみたりこっち見てみたりができるのでふらふらしがち。これはほんとよくないので、事前に見るの決めて、よほどのことがない限り変えないのがよさそう。
  • ネットワーク状況次第で音声がいまいちだったりすることも。
  • 懇親会は……オンラインのはちょっと気後れするかな。今回行かなかったのはそれだけじゃないけど。

最後に

楽しかった。オンラインどうかな、途中で飽きないかなと思ったけどそんなことぜんぜんなかった。

仕事ではすごいプログラマと仕事するみたいなこともなく、ほっとくと自信過剰になっちゃうんだけど、カンファレンスはそういうのすべてリセットしてくれて、お前はまだまだなんだってわからせてくれるから楽しい。

AutoHotkeyを管理者権限のウィンドウ上でも動かしたいけど管理者権限で動かしたくない場合

昔ならいざ知らず現代においてAutoHotkeyを管理者権限で動かすようなことは普通はしないのだけど、そうすると、管理者権限で実行したプログラムのウィンドウ上でAutoHotkeyが動かない。

まあ権限が低いプログラムから権限が高いプログラムを操作されたら問題なわけで、当然の挙動なんだろうけど、管理者権限のウィンドウでだけあの操作もこの操作もできない、となると不便である。

その不便にずっと甘んじていたんだけど、今度こそなんとかしようと調べ始めたら、なんとだいぶ前(2011年くらい?)から、WindowsUIAccessという機能を使って(多分)安全にこの制限を回避できるようになっていた。

元々はAHKのフォーラム上で公開されていた.ahkスクリプトを使ってどうこうやるみたいな感じだったようだが、現在ではGUIインストーラを使えばかなり簡単にできるようだ。

ということでその方法を紹介する。

  • まずインストール時に、オプションの"Add 'Run with UI Access' to context menus"をオンにしてインストールする。
  • なおインストール先はC:\Program Filesじゃないと駄目なはずだが未確認。
  • スクリプトを手動で起動する場合、コンテキストメニューから、Run with UI Accessでいい感じに動く。
  • スクリプトをスタートアップ時に自動起動などする場合(おそらくほとんどがそうだろう)、"C:\Program Files\AutoHotkey\AutoHotkeyU64_UIA.exe" <SCRIPT_PATH> /uiAccessのような形で実行する。今までの実行ファイルではなく、_UIAとついているのを使い、/uiAccessオプションを追加する、それだけ。

詳しくは以下公式ドキュメントに書いてある。

https://www.autohotkey.com/docs/Program.htm#Installer_uiAccess

Composerの高速化を設定した状態で2系に上げるとトラブる

https://github.com/hirak/prestissimo プラグインを入れたり、https://packagist.jp/ ミラーを使うように設定した状態で、Composerを2系にアップデートすると、composer require時等に以下のような警告・エラーが出る。

The "hirak/prestissimo" plugin was skipped because it requires a Plugin API version ("^1.0.0") that does not match your Composer installation ("2.0.0"). You may need to run composer update with the "--no-plugins" option.

これはとりあえず--no-pluginsオプションをつけて実行することでも対処できるが、多分ほかのプラグインも動かないし、アンインストールしてしまおう。

composer global remove hirak/prestissimo

Composer 2系ではprestissimoがなくても、並列ダウンロードしてくれるようでだいぶ高速になっている。

また、

[InvalidArgumentException]
Could not find a version of package livewire/livewire matching your minimum-stability (dev). Require it with an explicit version constr
aint allowing its desired stability.

あるいは、

[InvalidArgumentException]
Could not find package livewire/livewire.

このようなエラーが出る場合は、ミラーの https://packagist.jp/ が2系用のパッケージを持っていないせいのようだ。エラーメッセージもうちょっとなんとかならないのかとは思うが。

packagist.jpのウェブページに書いてある通り、

composer config -g --unset repos.packagist

すればおけ。prestissimoが多分いらないかなという状況なのに対して、ミラーはまだある程度速度に効いてそう、つまり2系Composeでも地理的なネックがあるような気はするので、もしpackagist.jpが2系に対応してくれるならこれは戻すのもありかも。

Laravelのファサードとはなにか

ずっと使っているけど十分に理解できなかったので調べた。

ファサードとはなにか

結論から言うと、ファサードは、対応したサービスのインスタンスのメソッドを、静的にコールできる仕組み、のようだ。

GoFデザインパターンのFacadeパターンとはちょっと違う。あれは複数の複雑な機能に対する一つのアクセス方法を提供するものだったと思うので。こっちはもっとシンプル。多少の例外はあるが、基本的にはサービスに委譲するだけだ。

Illuminate\Support\Facades\Requestファサード(以下Requestファサード)を例に挙げる。このファサード'request'エイリアスのサービスと対応していて、その実体はIlluminate\Http\Requestインスタンスである。

コントローラアクションで、Illuminate\Http\RequestをDIして持って来た$requestのたとえば$request->all()と、ファサードRequest::all()は同等になる。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request as HttpRequest;
use Illuminate\Support\Facades\Request;

class TestController extends Controller
{
    public function index(HttpRequest $request)
    {
        dd($request->all(), Request::all()); # 等しい
    }
}

ファサードはどう実装されているか

まずファサードはクラスである。Illuminate\Support\Facades名前空間以下にあるクラスで、Illuminate\Support\Facades\Facade抽象クラスを継承している。

ファサードクラス内にはgetFacadeAccessor()というメソッドが共通して存在していて、これが肝になっている。単純にこの戻り値によって対応するサービスが決まっている。

大抵文字列で、サービスのエイリアスが返されているが、Schemaファサードに関してはオブジェクトが直接返されていたりする。

オブジェクトの場合はそのまま使うだけだが、サービスのエイリアス等の場合は、必要に応じてresolve()相当の解決が行われている。

つまりRequestファサードで静的にメソッドを呼び出すのと、resolve('request')されたオブジェクトのメソッドを呼び出すのも同じことになる。

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Request;

class TestController extends Controller
{
    public function index()
    {
        dd(resolve('request')->all(), Request::all()); # 等しい
    }
}

関連1: クラス名のエイリアス

ファサードに関連する紛らわしい個所が2つある。1つはクラス名のエイリアスで、ファサードとは直接関係ないがほぼファサードに関連して使われている。

これはuse Requestuse Illuminate\Support\Facades\Requestと同等になるあたりの話だ。

通常エイリアスを使うことはほぼ使わないと思うが、一部の素のPHPスクリプト上では、useせず、エイリアスが直接使われていることがあるかもしれない。

php artisan ui vue --authなどとして認証機能を有効にした場合、routes/web.phpAuth::routes()が追加されるが、このときファイル上部ではuse Illuminate\Support\Facades\Authとはされていないはずだ。

これはエイリアスのおかげで動作している。

エイリアスは単純に、spl_autoload_register()を使って、動的にclass_alias()されることで設定されている。

設定されているエイリアスに関しては、Illuminate\Foundation\AliasLoader::getInstance()->getAliases()をtinker等から実行すれば確認できる。

これらのほとんどはconfig/app.phpaliasesで設定されるものだが、一部Composerでインストールされたパッケージから設定されるものがある。composer.lock(じっさいにはinstalled.jsonから読まれているが)のパッケージ設定にextra.laravel.aliasesがある場合、config/app.phpaliasesのものに追加でエイリアスが作られる。

デフォルトではLaravel 7のエラー表示パッケージであるIgnitionから、Flareクラスのエイリアスが設定されているはずだ。

// ...
        {
            "name": "facade/ignition",
            // ...
            "extra": {
                "laravel": {
                    "aliases": {
                        "Flare": "Facade\\Ignition\\Facades\\Flare"
                    }
                }
            },
        },
// ...

関連2: Arr, Str

もう1つはIlluminate\Support以下の、Arr, Strクラスだ。これらのクラスはファサードではないが、静的メソッドの使用がメインで、かつエイリアスも設定されているため、場合によってはファサードと区別がしづらいかもしれない。

とはいえ区別する必要もあまりない。クラスのソースコードを見れば、一目で裏にサービスインスタンスのない静的メソッドだけのクラスとわかる。

Let's Encryptの証明書の期限切れ通知メールをunsubscribeすると現状どうしようもないっぽい

ある日更新が不要になったLet's Encryptで取得した証明書の期限切れ通知メールを見てて、unsubscribeと書いてあるのに気付いてふとクリックしてしまった。

クリックした後の感じでは、どうもこの通知解除は、あるドメインに対してだけではなくメールアドレス単位で解除されるようだ。

それはちょっと不便なのでなんとかならないかと調べてみたが、どうしようもなさそう。

公式の情報。別のメールアドレス使ってねとある。

Expiration Emails - Let's Encrypt - Free SSL/TLS Certificates

Let's Encryptのコミュニティの情報。2016年から問題にされていて、2020年になっても十分な対策はないようだ。

Accidentally Unsubscribed - Let's Encrypt Community Support

オチはない。

Googleの検索結果一覧で狭い画面でも横スクロールバーが出ないようにする

いつの間にかmin-widthが1261pxとかになっていて、ブラウザのウィンドウは小さめ派には微妙な感じになっていたのでなんとかしてみた。

#appbar,
.rhscol,
#top_nav,
div#searchform,
#fbar {
    min-width: 0px;
}

まずmin-widthが1261pxに設定されているすべての要素のmin-widthを0pxにする。これで表示領域1168pxまでは横スクロールバーが出ないようになる。

個人的にはこれで十分だったが、もう少し小さなウィンドウでブラウジングしてる人はさらに以下のスタイルシートを当てる。

#rhs {
    display: none;
}

これが謎要素で、子を見た感じ表示する必要がそもそもなさそうなんだが表示されていて、しかも珍妙なサイズの左マージンが設定されているせいで表示に影響している。

とりあえず問題なさそうなので非表示にすることで、今度は表示領域852pxまでは横スクロールバーが表示されなくなる。

Gitであるauthorが変更したファイル一覧が欲しい

git diff --name-onlyとかで行けるかなと思ったけど、git diffはどうもauthorの指定はできないようだった。まあ仕組みを考えると妥当か。

ちょっとややこしいけど、以下のようにしてgit logでそれっぽい感じで取れた。--name-onlyじゃなくて--name-statusなのは、ファイル名とコミット概要部分を分けやすいようにしてるだけ。

git log --name-status --oneline --author='Author Name' | sort -u | grep -e '^\w\s'