業務でPHPファイルに declare(strict_types=1);
を導入するにあたり調べたことをまとめます。
declare(strict_types=1); の意味を解く
declare
あるコードブロックに対して、何らかの設定をするための構文。
declare(ディレクティブ)
のように書いて使う。
現在のところ使用できるディレクティブは ticks, encoding, strict_types
の3つ。
strict_types=1
PHPの暗黙の型変換を禁止して、型指定に厳密にチェックする設定のこと。
PHPのデフォルトでは自動変換モード(詳しくは後述)になっているが、 declare(strict_types=1);
をファイル先頭に書くことでそのファイルはstrictモードに設定することができる。
スカラー 型宣言 には二つの方式があります。デフォルトの自動変換 (coercive) モードと、 厳密に判断する strict モードです。
strict モードを有効にするには、declare 文を
strict_types
宣言と一緒に使います。
strict モードでは、型宣言に正確に対応する値のみを受け入れ、 そうでない場合、TypeError がスローされます。 このルールに関する唯一の例外は、int の値が float 型の宣言に渡せることだけです。
coerciveモードとstrictモードの違い
PHPのデフォルトでは、与えられた値の型を期待される型に自動的に変換する。(coercive モード)。
たとえば関数の引数に int が与えられたが、 引数には文字列が期待されていた場合、int を文字列型に変換した値を取得する。(戻り値も同様に、自動で型変換される。)
strictモードを有効にすると、与えられた型が期待する型と異なる場合TypeErrorになる。
↓ PHPのプレイグラウンドのようなサイトで書いたサンプルコードです。
何かコードを編集して、青い eval();
というボタンを押すと実行できます。
int と float の例
// declare(strict_types=1); が無い場合
<?php
function int(int $a){ return $a; }
function float(float $b) { return $b; }
print_r([int(2.5), float(2.5)]);
// 結果
Array
(
[0] => 2
[1] => 2.5
)
// declare(strict_types=1); がある場合
<?php
declare(strict_types=1);
function int(int $a): int { return $a; }
function float(float $b): float { return $b; }
print_r([int(2.5), float(2.5)]);
// 結果
Fatal error: Uncaught TypeError: int(): Argument #1 ($a) must be of type int, float given, called in /in/42G2d on line 10 and defined in /in/42G2d:6
注意点
- 適用したいPHPファイルごとの先頭にセットする必要があり、php.iniに記載したりしてまとめて適用することは出来ない。
-
<?php
の直後に書かなければいけない。(ファイルの途中に記述不可) - declare(strict_types=1); の影響範囲はそのファイルで完結している。
- 関数を定義するファイルと関数を呼び出すファイルが異なる場合は、定義するファイルがstrictモードであるかは動作に影響がなく、関数を実行するファイルがstrictモードかどうかで動作が決まる。
- ファイルをrequireする際も、requireするファイル・requireされるファイルのstrictモードが相互に影響することはない。
- PHPの型宣言でユニオン型(int | float)を使えるのはPHP8から。もしPHP8以前のバージョンであれば、intでもfloatでも良い、もしくはnullも含めたいといった場合にstrictモードが足枷になることも。
参考記事