引数を「ひきすう」とわかっていても「いんすう」と読み続けて1年が経ちました。ちょうど1年前に引数と読んでしまった夜…昨日のことのように今はっきりと思い出す。なんでもないようなことが、幸せだったと思う。さてさて!PHPタイプヒンティングの深い話の始まりです。
PHP5:タイプヒンティングと呼ばれていた。→PHP7:型宣言という呼び名に統一された。PHP7で機能拡張されスカラー型の宣言が可能に、PHP7.2からobject型も扱えるようになっている。
型宣言「タイプヒンティング」とは
タイプヒンティングとは、関数に渡すパラメータ(引数)が、特定の型(どのオブジェクトなのか?なんのインターフェースを備えるか?配列なのか?コールバックなのか?クラスか?など)であることを関数の宣言時に指定することが出来る機能です。型宣言をするには、引数名の前に型名を追加します。
array
function type_test(array $array) { タイプヒントがarrayなので、配列以外の型はエラー
}
type_test(1); int型なのでエラーになる。
オブジェクト
class myClass{
}
class otherClass{
}
function type_test(myClass $class) {
}
type_test(new myClass); タイプヒントと同じクラス名なのでOK!!
type_test(new otherClass); タイプヒントとパラメータのクラスの型が違うのでエラー
class myClass {
}
class childOfMyClass extends myClass { 継承も可能。
}
function type_test(myClass $class) { タイプヒントが親クラス。
}
type_test(new childOfMyClass); 実行時のパラメータが子クラスでもOK!!
インターフェイス
interface MyInterface{
}
class myClass implements MyInterface{ MyInterfaceを実装している。
}
class otherClass{
}
function type_test(MyInterface $class) { タイプヒント!!
}
type_test(new myClass); これはOK!!
type_test(new otherClass); これはエラー!!
callable
function func() {
}
function type_test(callable $func) { callable:呼び出し可能。(存在していないとエラー)
}
type_test('func') 存在するので(呼び出し可能なので)OK!!
type_test('not_exists_func'); 存在しない関数なのでエラー!!
戻り値の型宣言(タイプヒンティング)
PHPでは、何も指定しなければ関数から返却される値の型は決まってません。
<?php
function test ($val)
{
if ($val == 1) {
return 0;
} else if ($val == 2) {
return '0';
} else {
return false;
}
}
var_dump(test(1)); 結果 int(0)
var_dump(test(2)); 結果 string(1) "0"
var_dump(test(3)); 結果 bool(false)
関数の戻り値を指定すると…
<?php
function test ($val): int : intで関数の戻り値の型を指定すると…
{
if ($val == 1) {
return 0;
} else if ($val == 2) {
return '0';
} else {
return false;
}
}
var_dump(test(1)); 結果 int(0)
var_dump(test(2)); 結果 int(0) 関数の定義内の返却値が、戻り値の型宣言と異なる場合には
var_dump(test(3)); 結果 int(0) 型宣言に合わせた形で返されます。
型宣言に合わせようとしてうまくいかない場合は…TypeErrorがスローされる。
<?php
function test(): int
{
return 'a';
}
var_dump(test()); タイプエラーになります。 Fatal error:Uncaught TypeError........
PHPではデフォルトでは弱い動的型付けと呼ばれています。例えばstringで想定した関数にintが渡されても、その値をstringとして受け取ってしまう。このように関数が実行されてしまうのを避けるために厳密な型チェックを指定し、TypeErrorを発生させるようにする。
<?php
declare(strict_type=1); 厳密な型チェック
function exam1($userId): int
{
return 22; これはOK!!
}
function exam2($userId): int
{
return 'にじゅうに'; これはエラー(TypeError)
}
※PHP7.1からnullableが指定できる。nullもしくはintを許容させるには次のように記述する。
function exam3($userId): ?int
{
return '22'; 強い型付けではこれもエラー!!(TypeError)
}
※厳密な型チェックを有効にしていないファイルから、厳密な型チェックを有効にしたファイル内で定義された関数を呼び出した場合は、呼び出し元(有効にしていない)のファイルの設定が適応されてしまうので注意が必要です。
最後まで読んでいただきありがとうございました。