11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【PHP8.0】gettypeとget_classの悪魔合体

Last updated at Posted at 2020-03-23

ワレハget_debug_type、コンゴトモヨロシク…

PHPにはプリミティブ型名を取得するgettypeと、オブジェクトのクラス名を返すget_classという関数が存在します。
_があったりなかったりと命名の不統一も気になりますが、それよりgettypeはオブジェクトに使うとobjectしか返さず、get_classをプリミティブ型に使うとE_WARNINGが発生します。
いや、プリミティブ型であればintとかの型が欲しいし、オブジェクトならPDOとかの型が欲しいんだ、という問題に対する答えはありませんでした。

というわけで両者を合体させたget_debug_typeというRFCが提出されました。

PHP RFC: get_debug_type

proposal

このRFCは、指定された変数の型を返す新しい関数、get_debug_typeを追加する提案です。

これは、配列で来る値など、変数の型に基づいた既存のチェック方法では対応できないパターンを置き換えるためのものです。

$bar = $arr['key'];

if (!($bar instanceof Foo)) {
  // もっとも単純な例。しかしgettypeは"integer"を返すので、正しい型にしたいなら"int"に変換するなどが必要。
  throw new TypeError('Expected ' . Foo::class . ' got ' . (is_object($bar) ? get_class($bar) : gettype($bar)));
}
 
// 今後はこう書ける
if (!($bar instanceof Foo)) { 
  throw new TypeError('Expected ' . Foo::class . ' got ' . get_debug_type($bar));
}
 
$bar->someFooMethod();

この関数は、正しい型名を返すという点でgettypeと異なります。
"integer"ではなく"int"を返し、クラスもクラス名に変換します。
次の表は、いくつかの値に対してgettypeget_debug_typeが返す値を比較したものです。

get_debug_type() gettype()
0 int integer
0.1 float double
true bool boolean
false bool boolean
"hello" string
[] array
null null NULL
Foo\Bar Foo\Bar object
無名クラス class@anonymous object
リソース resource (xxx) resource
閉じたリソース resource (closed)

Backward Incompatible Changes

なし。

Proposed PHP Version(s)

PHP8.0

Implementation

投票

投票は2020/03/26まで、2/3の賛成で受理されます。
このRFCは賛成42、反対3で受理されました。

感想

Mark Randallは最初はgettypeがクラス名も返すようにしようとしたものの、Nikitaから「新しい関数にしてくれ」と言われてget_debug_typeを作ったようです。
まあ、これまでobjectとしか言わなかったgettypeがいきなり色々な型を喋り出したら困るところも出そうですからね。

ということで、今後は型の取得はget_debug_typeに一本化できそうです。

手間を省くための定型処理を言語機能に取り込むことは、他の言語でも多々起きていることです。
たとえばJavaScriptのasync/awaitPromiseの糖衣にすぎず、async/awaitができることは全てPromiseでもできるので、究極的にはasync/awaitは不要です。
しかし非同期処理を楽に書けるようにするために言語仕様に取り込まれました。
糖衣構文の取り込み自体は、このようにさほど珍しいことでもありません。

しかし、str_containsとかis_countableとか、他言語であれば「自分で書け」と言われそうな極端に簡単な構文まで言語仕様に取り込んでしまう言語は、PHP以外にはそうそう無いのいではないかと思います。

11
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?