WSLが急に起動しなくなって焦った

先日気づいたらWSLが起動しなくなっていました。 復旧手順をメモしておきます。

症状

  • Linux側のシェルを起動しようとすると、長い待ちの後Wsl/Service/CreateInstance/CreateVm/HCS/ERROR_FILE_NOT_FOUNDというエラーが出る
  • wsl --shutdownもできない

環境

wsl --version の出力

WSL バージョン: 2.7.8.0
カーネル バージョン: 6.18.33.1-1
WSLg バージョン: 1.0.73.2
MSRDC バージョン: 1.2.6676
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
Windows バージョン: 10.0.26200.8655

やったこと

  1. GitHubのReleaseページからmsiファイルをダウンロード
  2. 以下の記事を参考に、system.vhdtools/modules.vhdをコピー → 効果なし
    • zenn.dev
    • 確かにこの2ファイルがなくなってはいました
  3. Issue #40448を参考に、エクスプローラー上でmsiファイルを「Shift+右クリック→修復」を実行 → 「wsl --shutdownでシャットダウンしてから再実行しろ」という旨のメッセージが出る。上記の通りそれが動かないので、Windows自体を再起動
  4. 再起動後再度msiファイルから修復を実行 → 修復が完了しPCを再起動

ここまできてようやくWSLが起動し、中のデータも無事であることが確認できました。

さいごに

WSLが急に起動しない、というのはかなり心臓に悪いですね……

WSLにあるのはほとんどコードで大半はgit管理していますが、中にはまだリモートリポジトリ未作成のものもあるので、pushのタイミングなどもう少し考えなければ、と感じました。

PHPerKaigi 2026に参加・登壇しました

PHPerKaigi 2026の会場の撮影スポット。ロゴ入りの大きなパネルが背景になっている。

PHPerKaigi 2026の参加ブログです。 PHPerコードバトルについては既に記事を書いたので、それ以外について書いていきます。

takaram.hatenablog.com

登壇

『DIコンテナとAutowireの「魔法」を実装して理解する』というタイトルで登壇しました。

fortee.jp

DIコンテナって使ったことはあっても、どうやって動いているかを理解している人はなかなか少ないのでは?と思い今回のプロポーザルを出しました。

当日は20分セッションの前半でDIコンテナの説明、後半で実際にDIコンテナを実装してデモで動かしてみる、という構成でしたが、その際のコードはGitHubで公開しています。 かなりシンプルなコードでAutowireが実装できているのがわかっていただければ幸いです。

github.com

ちなみに、せっかくなのでデモで使ったコードに実用で必要な最低限の機能を追加したものをOSStakaram/nano-diとして公開してみました。

packagist.org

聞いたセッション(一部)

20年以上続く PHP 大規模プロダクトを Kubernetes へ ── クラウド基盤刷新プロジェクトの4年間

fortee.jp

サイボウズさんのGaroonのVM→Kubernetesへの移行のお話でした。

うちの会社も2000年代から続くPHP+VMのプロダクトが複数あるので、おそらく今後めちゃくちゃ参考にするだろうなと思いながら聞いていました。p.21「Forest の課題」のスライドは「これ完全にうちのプロダクトだな??」となってました。

「お金で解決」が全てではない!大規模WebアプリのCI高速化

fortee.jp

改善の前に計測、鉄則ではあるもののすぐ改善に行きたくなる誘惑を断ってちゃんとやってるのが素晴らしいですね。

Railsアプリでの事例ではあるものの、他の言語・DBでも応用できそうな話ばかりで非常に参考になったので、早速これを参考に自分のチームでも改善……の前に計測ですね😉

Ruby VM 開発者がZend VMのopcodeを眺めてみた

fortee.jp

RubyのVM、YARVを開発した笹田さんによるルーキーズLTです。ルーキーとは??*1

スタックマシンやレジスタマシン、名前は知ってるけど全然わかってないのでどこかでちゃんと勉強したいです。

なぜarray_firstとarray_lastは採用、array_value_firstとarray_value_lastは見送りだったか

fortee.jp

PHPの機能追加・変更を決めるRFCの合意形成・投票の裏側を紹介するLTでした。

スコープを絞って合意を取りやすくするといった話は、意外と私たちがやっているプロダクト開発でのプロジェクトマネジメントと同じような話だなと興味深く感じました。

その他

飲食

PHPerKaigiほど参加者をもてなすカンファレンスを他に知りません。 今回も軽食・ドリンク・バドワイザーも美味しく頂きました!(あんまり食べたもの、飲んだものの写真撮ってなかった……)

スポンサーブース

スポンサーブースも回って、いろいろとノベルティも頂きました。ノベルティもブースの企画も各社凝っててすごいなあ……

スポンサーブースで頂いたノベルティ(の一部)
(ニコニコのコースターだけスポンサーブースじゃなかった気がする)

PHPerガチャ

スポンサーブースを回ったりしてスタンプを集めるなどすると、ガチャを回せる企画がありました。 2回だけ回したのですが、1等と2等のTシャツ・缶バッジを頂きました!この日は珍しく引きがよかったですね。

PHPerガチャのカプセルマシーンと、ビニールに包まれた黒いPHPerKaigi Tシャツ、小さい缶バッジ
当たったTシャツと缶バッジ


PHPerKaigiは他のカンファレンスとはまた違った楽しさがあるので、来年も参加したいです!*2
委員長の長谷川さんはじめスタッフの皆さん、ありがとうございました!


*1:

ルーキーズLTは、PHPerKaigiではじめてトークする方のための応募枠です。

プロポーザル募集ページより)とのことなので正真正銘ルーキーです

*2:2027は「純白の白紙」だそうですがきっとあると信じてます🥹

PHPerコードバトル2026に参加した #phperkaigi

TL;DR

はじめに

PHPerKaigi 2026が3/20~22の3日間開催されています。
この中で、PHPerコードバトルというコンテンツが実施されました。

これがどんなコンテンツかはPHPerKaigiスタッフブログをご覧いただくといいと思いますが、簡単に言うとコードゴルフ対決です。

blog.phperkaigi.jp

昨年から始まった第2回目の企画で、前回は優勝させていただいたので今年も挑戦していました。

予選

オフライン予選通過4名 + オンライン予選上位2名が決勝参加できる、というレギュレーションでした。

オンライン予選に参加しましたが、最終順位は3位で惜しくも予選通過ならず……と思いきや、2位の方が当日参加できないとのことで急遽繰り上がりで決勝トーナメントに参加させてもらいました。

準々決勝、準決勝

3/20のDay 0は準々決勝と準決勝でした。 プレオープニング直前に参加することが決まってバタバタしつつも、何とか決勝進出することができました。

余談ですが、準々決勝のお題のコードとほぼ同じものがzoeさんの登壇に出てきて笑いました😂

決勝

決勝は3/21のDay 1に実施されました。

前日の準決勝で、もう1人の決勝進出者のLemnisさんがAIにコードを書かせている*1とのことだったので、真似してみようと事前にAGENTS.mdを作成しておきました。 書いたのはルールと手順(テストスクリプトを作ってからそれを壊さないように短くする)という程度です。もともと手元で簡易的にスコアを計算できるスクリプトを用意していたので、それもAIに渡しています。

決勝は3本勝負で、それぞれの私が手で書いたコード、AIに書かせたコード、対戦相手のLemnisさんのコードのスコアは以下のような形でした。

takaram (人間) takaram (AI) Lemnisさん
1回戦 342 174 208
2回戦 121 118 *2 117
3回戦 177 141 200

毎回、最初に問題文とサンプルコードをコピペしてCodex (GPT-5.4 high) に渡し、その後は放置して手でコードを縮めているうちにAIが回答を出している、という流れを取りました。

1回戦は15分で上手く縮められず、全然だめだーと思っていたら、Codexが圧倒的に短いコードを書いてくれていて、正直びっくりしました。2回戦はほぼ互角ですが、それ以外は私よりもAIの方が強いという結果になりました。 AIがコードゴルフもここまで得意とは正直意外でした。またAGENTS.mdを整備したおかげか、一度二度ほどの指示でほぼ完成形のコードを出してくれたので、Codexが頑張っている間自分でも手でコードゴルフに挑むことができました。

という形で、私が勝ったと言っていいのかどうか……という気分ではありますが、昨年に続き優勝させていただきました。 開催してくださった長谷川さんはじめPHPerKaigiスタッフの皆さん、解説のお二人、問題を作られたいまむらさん、対戦いただいた方々、そしてご覧いただいた皆さん、ありがとうございました🙇

最後に

実際に使ったAGENTS.mdはGistで公開しました。*3
https://gist.github.com/takaram/bd221f4a86bee0bdffd0f55c3cc38ef2

また、予選・本戦の各問題は現在誰でも挑戦できるようです。 https://fortee.jp/phperkaigi-2026/go/phper-codebattle-qualifying

せっかくなので、手で挑戦するもよし、AIにやらせるもよし、挑戦してみてはいかがでしょうか?

*1:ルール上は検索してもAIに聞いてもOKとなっていました

*2:出てきた改行のないコードを提出前に整形してと頼んだ結果、波括弧が入ってしまい、手で書いたコードの方が短いと勘違いしたため本番でこのスコアは出ていません。いずれにしても負けていましたが

*3:ちなみに、末尾の「制限事項」節は当初はなく、決勝第1試合、第2試合終了後に少しずつ付け足してブラッシュアップしたりしています

PHPカンファレンス香川2025参加記 #phpconkagawa

11月24日に開催された、PHPカンファレンス香川に行ってきました。 初開催の昨年に続き2回目の参加でした。

前夜祭

昨年同様、大阪から在来線で高松へ向かいました。途中岡山で途中下車して何か名物でも食べようと思い、駅ビルで見つけたえびめしとデミカツを食べたりしながら、昼過ぎに高松に到着しました。

前夜祭は今年オープンしたあなぶきアリーナの会議室での開催でした。 前夜祭は香川銘菓を頂きながらトークを聞いていました。

トーク

fortee.jp

個人開発でWebサイトを公開したことがなく、このあたりの事情を全然知らないんですが、必要になるときが来たらLightsailも試してみたいですね。

fortee.jp

5分間に内容を詰めに詰めており、倍速再生の動画を見ている気分になりました(?)

当日は喋りに圧倒されていましたが、資料も改めて見るとクオリティ高くてわかりやすい……!

fortee.jp

docker composerはやりますよね😂 個人的には"status"をtypoする手癖があるのでgit stgit statusエイリアスに設定しているんですが、かなりストレスが減るので気に入っています。

ご飯

夜は骨付鳥を食べに、寄鳥味鳥に向かったのですが大行列のため、他のお店で骨付鳥を頂きました。

2件目は海鮮居酒屋的なお店でしたが、魚も日本酒も美味しくてご主人もいい人で素敵なお店でした。僕らと入れ替わりで店を出た人が「この店めっちゃいいですよ!」と言い残して行って、そんなに…?と思ったんですがそんなにでした。

手前にたこの酢の物、その奥に氷の上に載った馬刺し、一番奥に日本酒の一升瓶が3本
たこの酢の物と馬刺しと日本酒

tabelog.com

本編

トーク

fortee.jp

Doctrine完全に理解した!

個人的には、カンファレンス参加後にMikroORMというJS/TSのORMを触る機会があったのですが、「Data Mapper, Entity Manager, Unit of Work... 進研ゼミぺちこん香川で見たやつだ!」となったのが嬉しかったですね

スポンサーブース

今回は5団体のブースが出展されていました。

高松市のブースで担当者の方が「うちは知名度がないので……」と仰っていたのが印象的でした。そんなに?と思ったのは僕が西日本の人間だからでしょうか。

Postmanさんのブースで、PostmanでOpenAPI仕様書を扱えるのを初めて知りました。これから使っていきます……!

無限うどん

昨年に引き続き、参加者はうどん食べ放題でした(!) スポンサーブースでスタンプをもらうとおにぎりや油揚げがゲットできるのも前回同様です。

写真を見返したら、4杯+おにぎり1つを頂いていたようです。 ごちそうさまでした🙏

うどんを写した4枚の写真。左上の写真は背景に「やまびこ号」という垂れ幕が写っている。右上の写真はおにぎりも写っていて、うどんには揚げが載っている。左下は温泉卵が載っている。
今回いただいた4杯のうどん+おにぎり

懇親会

前夜祭と同じあなぶきアリーナの、アリーナの客席を出たところが交流スペースとして貸し出されていて、そこでの開催でした。

あなぶきアリーナのメインアリーナ(上)、客席(右下)、客席から見た交流スペース(左下)
あなぶきアリーナ

途中で突然 @koriym さんの野良トークが始まってめちゃくちゃいい話でした

翌日

朝・昼とうどんを食べ、栗林公園に遊びに行きました。 (お昼から骨付鳥を食べようかと思ったけど、どの店もランチ営業はしてなかった……)

おわりに

来年は都合がつかず不参加の予定ですが、隣県の愛媛でPHPカンファレンス愛媛があるのでそっちは行けるといいな……!

PHPカンファレンス関西2025@神戸 に行ってきて登壇した

7月19日、PHPカンファレンス関西2025に参加してきました。

2025.kphpug.jp

登壇

『遊びながら強くなる!コードゴルフで学ぶPHPの言語仕様』というタイトルで発表しました。

fortee.jp

PHPerKaigi 2025のPHPerコードバトルに参加したこともあり、「コードゴルフ楽しいよ!」ということを話そうと登壇しました。

15分トーク+5分質疑応答 の20分枠にもかかわらず、練習では大体20~21分になってしまい、スライドを削り切れない状態でした。まあ余計な話を削れば18分くらいにはなるかと思いつつ臨もうと思った矢先、トラブルで開始時間が2,3分押してしまいました。

その結果、トークが15分ほどで収まりました。なんで? たぶん思った以上に早口で喋ってしまったんじゃないでしょうか。滑舌悪い上に早口で聞き取りにくかったら申し訳ないです。

ただ、Xのハッシュタグや終わった後に話しかけていただいたり、懇親会でも↓のようないい反応も頂けたので、トータルでは悪くない発表ができたのではないかと思っています。

聞きに来てくださった皆さん、ありがとうございました!

聞いたトーク

自分以外の聞いたトーク(一部)の感想を書いていきます。

ソフトウェア・デザインに向かおう ~ 世界を(ちょっとだけ)変えるソフトウェアを目指して ~

今回の基調講演です。設計とは何ぞや、アーキテクチャとは何ぞや、という部分の見方、解像度が少し変わったような気がしました!

全日本PHPersコミュニティーサミット

ランチセッションとして、全国各地で行われているPHP系勉強会の主催メンバーが集まって話す、という企画が行われました。 勉強会の主催をしてくださる方々には本当に感謝ですね🙏

あと、ランチセッションということで軽食が提供されました。次の時間帯が自分の登壇ということもあり、お昼をゆっくり食べる余裕がないかと思っていたのでめちゃくちゃ有り難かったです😭

構文解析器入門

Ruby構文解析周りのコントリビューター(最近PHPにもコントリビュートした!)ydahさんの発表です。 PHPの構文はzend_language_scanner.lに記述されているらしいとは知っていても、あまり見方がわかっていなかったんですが、これで少しは読めそうな気がしました!

カンファレンスに参加したあなたが明日からできること

実行委員長によるこの日最後のLTです。 カンファレンスで学んだことをどのように持って帰るのか、委員長の熱のこもった、ラストにふさわしいトークでした!!


地元・関西で登壇できて、他の方のお話もたくさん聞けて楽しかったです!ありがとうございました!

PHPカンファレンス小田原2025に行ってきた

2025/4/12に開催された、PHPカンファレンス小田原に参加して来ました。

phpcon-odawara.jp

大阪からはなかなか遠く去年は不参加でしたが、今年はちょうど前日に東京出張があり、帰り道に寄っていくことができました笑

聞いたセッション

PHPと旅する OSI 7階層

docs.google.com

HTTPより下の層は「ClientHelloっていうのがあって……」「まずSYNパケットを送って……」という話程度にしか知らなかったので面白かったです。 「自作TCPあるある」きっと二度と聞かないパワーワードでしたw

恣意性から考える、変更に強いモデルの作り方

speakerdeck.com

めっちゃいい話でした。「これってドメイン層に実装するの?アプリケーション層だっけ?」は最近よく考えることなので、それに対する一つの考え方として、個人的にはとても腹落ちしました。

PHP で学ぶ OAuth 入門

speakerdeck.com

最近仕事でOAuthを触っていたので、改めて頭の整理ができてよかったです。 認証と認可の違い、大事

おだわランチ

スタッフおすすめのお店が4店舗紹介されていたので、その中から味噌ラーメンのお店に行きました。

note.com

ご紹介するのは4店舗。どれも実行委員長をはじめ小田原在住スタッフおすすめのお店です。そしてなんと、ぺちおだ2025のためにお得な特典を用意していただけた、ランチコラボ店です!(特典は2025年4月12日のみ有効)

このカンファレンス地元密着すぎませんか?ただおかげで小田原を楽しめました😄

チャーシュー、煮卵、ネギがのった味噌ラーメン
麺屋 加藤兵太郎商店 の兵太郎味噌ラーメン(大盛り)

ぺちおだ大合戦

参加者同士のコミュニケーションコンテンツとして企画された「ぺちおだ大合戦」 ランダムに割り振られた3人1組で、PHPに関連したクイズなどを通して交流するコンテンツです。

note.com

↑のnoteの末尾にちょこっとヒントがあったんですが、やりながら「あ~もうちょっと小田原に関して予習しておけば」と同じチームの人と言っていました😂

「指示があるまで中を見ないこと」と書かれた、ホチキス止めされた冊子の表紙冊子の2枚目。「ぺちおだ試験」の見出しの下に注意事項が書かれている
受験とか大学の試験を思い出す、クイズの問題用紙

最後のHTTPステータスコード百人一首も盛り上がりましたし、チームメンバーとの交流もできて全体として非常にいいコンテンツでしたね!

最後に

今回初参加でしたが、ランチなどで小田原を楽しむこともできいいカンファレンスでした。

懇親会は参加できなかったので、来年は……と思っていたら、来年の開催はないとのことで寂しいですね。

……おや?

PHPerコードバトルで書いたコードを紹介してみる

先日 PHPerKaigi 2025 に参加し、PHPer コードバトルで優勝させていただきました。

takaram.hatenablog.com

PHPer コードバトルで僕がどんなコードを書いてたか、というのを紹介していくだけの記事です。

準決勝 第1試合

問題はこちら https://t.nil.ninja/phperkaigi/2025/code-battle/golf/11/watch

標準入力から行区切りでテキストが入力されます。テキストに含まれる数字を漢数字に置換して出力してください。置換は一桁ずつおこない、数字が連続している場合でも「十」や「百」にはしないでください。

入力:
1234567890
第8回
ペチパー会議2025
気温は摂氏7度
総勢123人
税込98700円

出力:
一二三四五六七八九〇
第八回
ペチパー会議二〇二五
気温は摂氏七度
総勢一二三人
税込九八七〇〇円

本戦の15分間で僕が書いたコードはこちら

<?php
while($l = fgets(STDIN))
    echo strtr(
        $l,
        str_split('〇一二三四五六七八九', 3)
    );

練習がてらやっていたオンライン予選で見つけたstrtrを利用したコードです。

www.php.net

strtrは、たとえば "a → A, b → B, c → C" のような変換をするときに2通りの書き方ができます。

<?php
// パターン1
strtr($str, 'abc', 'ABC');
// パターン2
strtr($str, ['a' => 'A', 'b' => 'B', 'c' => 'C']);

この2つ目の書き方を利用しています。ちょうど置換前の文字が0からの連番なので、'0' =>のようにキーを書く必要がありませんでした。

また、配列は['〇', '一', '二', ...]の代わりにstr_splitを使っています。普通はmb_str_splitを使うところですが、全て3バイト文字なのでstr_splitの第2引数を指定して3バイトずつ区切っています。

試合後解説のめもりーさんがおっしゃっていたように、1行ずつ処理せずstrtrの第1引数に直接fread(STDIN, 1e5)とかを渡すともっと短くなります。

準決勝 第2試合

問題はこちら https://t.nil.ninja/phperkaigi/2025/code-battle/golf/12/watch

標準入力から「西暦年-月」の形式で 2025-02 のような行が1行入力されます。入力された月に合わせて「[Y年M月]」と出力してから、入力された月のカレンダーを日曜始まり形式で整列して出力してください。日付はすべて「3桁空白右寄せ」で表示します。

入力:
2025-02

出力
[2025年2月]
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

はてなブログだと出力例部分が表示崩れしてしまうようです

こちらは自分は出場していませんが、観戦しながら自分でも書いていたコードを紹介します。

<?php
$f = strtotime(fgets(STDIN) . "-1");
echo date("[Y年n月]\n", $f);

foreach(
    array_chunk([
        ...array_fill(0, date('w', $f), ''),
        ...range(1, date('d', strtotime("last day of", $f)))
    ], 7) as $w
){
    foreach ($w as $d)
        printf("%3s", $d);

    echo "\n";
}

出力用の配列を作るために、サンプルコードではもう1つforeachループがありましたが、array_chunkを使うことでそれが不要になっています。

www.php.net

array_chunkを使うのは、作問担当の@tadsanさんの想定解だったようです。

後から知ったんですが、date('d', strtotime("last day of", $f))の部分はdate('t', $f)でよかったようです。何ですかtって……

www.php.net

t 指定した月の日数。 28 から 31

決勝

問題はこちら https://t.nil.ninja/phperkaigi/2025/code-battle/golf/13/watch

標準入力の最初の行に出力の最大行数 $max が、次以降の行に置換リストが 数,名前 の形式で改行区切りで入力されます。置換リストに含まれる数は2以上の素数で、昇順に入力されます。1 から $max までの連続した整数を改行区切りで出力してください。その際、出力しようとしている数が置換リストの数の倍数なら対応する名前に置き換え、その数が置換リストに含まれる複数の数の公倍数ならリスト内の数が小さい順に連結して置き換えてください。

入力:
10
2,Dizz
3,Fizz
5,Buzz

出力:
1
Dizz
Fizz
Dizz
Buzz
DizzFizz
7
Dizz
Fizz
DizzBuzz

決勝の15分で書いたコードがこちら

<?php
$x = fgets(STDIN);
while ([$n, $m] = fgetcsv(STDIN)) {
    $a[$n] = $m;
}

for ($i = 0; $i++ < $x; $s = '') {
    foreach ($a as $n => $m)
        $i % $n || $s .= $m;

    echo $s ?: $i, "
";
}

元のサンプルコードから離れることなく、地道に短縮していった結果です。

最終日にランキングを見てみたら、上のコード以上に短縮している方がたくさんいらっしゃったので、自分もさらにやってみた結果↓のようになりました。

<?php
for ($x = fgets(STDIN); !$s = ++$i > $x; $a[] = fgetcsv(STDIN)) {
    foreach ($a as $r)
        $r && $s .= $r[$i % $r[0] + 1];

    echo $s ?: $i, "
";
}

入力を読み込むループと出力するループを1つにまとめてしまっています。

1, 2, 3, ... と順番に出力するわけですが、nを出力する段階では、n以下の置換リストだけ読み込めていれば十分です。 問題の制約として、置換リストの入力は「2以上の素数で昇順」というのを考慮すると「1行出力して1行読み込む」で問題ないことがわかります。

ただし、出力が終わるまで入力を読み込み続けてしまうので、$afalseが入り込んでしまいます。そのため foreach の中で$r &&が必要になっています。

あとは、出力文字列$sの初期化を false で行っているあたりも工夫ポイントです。