Edited at

PHPの型宣言(タイプヒンティング)


型宣言(タイプヒンティング)とは

関数に渡すパラメータ(引数)が、特定の型であることを関数の宣言時に要求できるようになります。

型宣言をするには、引数名の前に型名を追加するだけです。

$userList = ['user1', 'user2'];

function test(array $list) // タイプヒンティング
{
echo $list;
}

test($userList); // OK
test('hoge'); // Catchable fatal error: Argument 1 passed to test() must be of the type array, string given

この場合はわかり易いですが、$listは配列でなければエラーが発生します。

arrayだと思ってたのにstringじゃんって怒られます。


すべての型を指定できるのか

PHP5.4まではself,array,callable,クラス名・インターフェイス名のみで

PHP7からbool,float,int,stringの指定ができます。


クラス名・インターフェイス名の指定

class Test

{
private $hoge;

public function __construct(Hoge $hoge = null) // タイプヒンティング
{
$this->hoge = $hoge ?: new Hoge();
}
}

この場合$hogeはHogeクラスのインスタンスなければエラーが発生します。


デフォルト値をnullにしている場合

function test(array $array = null)

{
var_dump($array);
}

test(); // NULL
test('hoge'); // PHP Fatal error:

引数のデフォルト値にnullを指定している場合には、タイプヒンティングと相違が生まれるが問題ありません。

この場合には引数の値がnullもしくはarrayであればエラーは発生しません。


タイプヒンティングのメリット

1.phpdocよりも厳密で引数の型がわかり易い

メソッドの上にコメントで型が書いてあることも多いですが、引数の隣に明示的に型が書いてあるためわかりやすいです。(個人的には)

コメントはあくまで補足のため、実際の型と相違があってもエラーにはなりません。

<?php

function hoge(string $string)
{
var_dump($string);
}

// string型を宣言している引数にarrayを指定するとfatal errorになる
hoge(['hoge']);
// PHP Fatal error: Uncaught TypeError: Argument 1 passed to hoge() must be of the type string, array given

/**
* @param $string
*/

function fuga($string)
{
var_dump($string);
}

// 型宣言はせずにphpdocでstring型を指定したメソッドの引数にarrayを渡す
fuga(['fuga']);
/*
array(1) {
[0]=>
string(4) "fuga"
}
*/

2.エラー検知

違う型を引数に渡した場合、関数宣言時にCatchable fatal errorが発生するため、原因の特定が楽なのとcatch可能です。

3.無駄な型判定のコードなどを書かなくて済む

タイプヒンティングをしているとその関数の宣言時に判定が行われます。

function hoge($fuga)

{
// array $fuga と書けばこの判定のコードは不要になる
if (!is_array($fuga)) {
return false;
}

// 処理
}


注意点


強い型付けと弱い型付け

マニュアルにこのような記載があったので、違う型を渡しても変換されてしまうことがあるそうです。


デフォルトでは、間違った型を渡された場合でも、可能な限りは来されている型に変換します。 たとえば、string を想定している関数のパラメータに integer が渡された場合は、その値を string 型として受け取ります。


実際に書いてみるとたしかに 1 → "1" となりました。(弱い型付け)

厳密な型チェック(強い型付け)をするには、 declare(strict_types=1); の記載が必要だそうです。

<?php

//declare(strict_types=1);

function test(string $string)
{
return $string;
}

var_dump(test("hoge")); // string(4) "hoge"
var_dump(test(1)); // string(1) "1"