[Hoge::class, 'method'] が Callable なのはなぜ?
正確さを保証できない記事です
社内Slackで [$instance, 'hello']()
と呼べる、という話と
この記事を見て、タイトルの疑問については
※力尽きたので一旦記事は公開する
とあり、自分で php-src を読みに行った話です
なお ぼくはC言語読めません。高校のときにポケコンで書いた main
を書いたくらいなので、雰囲気で読んでます
Laravel のルーティングなどで [HogeController::class, 'index']
とか書いていますが、とくに疑問に思いませんでしたが、これは Callable なんですね Callable だから ()
をつければ実行できると
じゃあなぜ Callable なのか、どこで判定しているのか探ります
辿った php-src は次のコミット時点のものです
is_callable()
はどこで実装されてるか
ここに PHP の is_callable()
が実装されています
実際に Callable か判定しているのは zend_is_callable_ex
のようです
zend_is_callable_ex
戻り値になる bool を取得しているのは zend_is_callable_at_frame
ですね
zend_is_callable_at_frame
さて、ここにお目当ての実装があります
C が読めなくても case IS_ARRAY:
はすぐわかりますね
この中で
- 先頭の要素を
obj
に 2つめの要素をmethod
に入れる -
obj
,method
いずれかが NULL なら break -
method
が string じゃなければ break -
obj
が string で-
is_callable(syntax_only: true)
ならtrue
- そうでない時
obj
が Callable なクラスの名前でなければfalse
(以下略)
-
おや?
syntax_only: true
<?php
var_dump(is_callable(['存在しないクラス', 'method'], syntax_only: true)); // bool(true)
var_dump(is_callable(['存在しないクラス', 'method'], syntax_only: false)); // bool(false)
syntax_only
の使い所がわからない…
method
が string ならば
追記その2を参照してください、下記コードはミスってました!! ありがとうございます @SchroSisさん!!
<?php
class Hoge
{
public static function fuga() {}
}
var_dump(is_callable(Hoge::class, 'fuga')); // bool(true) わかる
var_dump(is_callable(Hoge::class, 'piyo')); // bool(true) !?
Callable とは一体…?
php-src をそれなりにちゃんと読み込むってあんまりしないので疲れます
今回は GitHub 上でずっと辿っていたので IDE 使ったらもう少し楽なのかな…?
最後の 存在しないメソッド名を指定しても Callable と判定されるのはなんでなんだろう
追記
[Hoge::class, 'fuga']()
は static じゃないと怒られていたからなんでルートに使えるのかと思ったらそういうことだったのか
似非Callableなるほどなるほど
追記その2
凡ミスすぎる、型は大事ですねえ!!
Discussion