[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