resourceは型宣言できない
code:php
<?php
function read(resource $res): void {}
read(fopen('php://temp', 'rw'));
PHP 7
Fatal error: Uncaught TypeError: Argument 1 passed to read() must be an instance of resource, resource given
「resourceのインスタンスが必要なのにresourceを渡してるぞ」って怒られてる
型宣言ではresourceって型宣言してるんだが…?
PHP 8
Warning: "resource" is not a supported builtin type and will be interpreted as a class name. Write "\resource" to suppress this warning in /in/S7GRg on line 3
「resourceは型宣言がサポートしてる組み込み型じゃないし、クラス名として解釈すんぞ」って言ってる 説明通り\resourceって書いたからって型宣言できるわけじゃなくクラス名として扱われる
なぜresourceは型宣言できないのか
PHP 7.0で型宣言が追加された提案で明言されています。
Type declaration choices
No type declaration for resources is added, as this would prevent moving from resources to objects for existing extensions, which some have already done (e.g. GMP).
かつてGMPがresourceからオブジェクトに移行したときと同じことをやるのでresource型に依存するなということ
ちなみにGMPがresourceだったのは5.5だけで、5.6で既にオブジェクト化している
resource型の肩身は年々狭くなっている
実際にPHP 8.0と8.1で結構移動された
8.0
https://gyazo.com/748981f95637232ce23bb518e5b9c757
8.1
https://gyazo.com/3d56da09683729f5c1af8f041b1bd13d
あまり直接は使われないものが多いが、そのなかでも使われる可能性があるのは以下あたりだろうか
fopen()が影響範囲めちゃくちゃ大きそうだけど将来的にどうするんだろ 現実的にファイルを扱うにはどうすればいいか
PHPDocには書ける
code:php
<?php
/**
* @param resource|File
*/
function read($res): void {}
read(fopen('php://temp', 'rw'));
resourceを使わない
将来的のPHPでファイルハンドラが廃止された暁にはPSR-7自体のバージョンは上げなければいけなくが、自前で直接やらなくても各ライブラリでいい感じにしてくれるだろう それが抽象化というものだ