PHP

戻り値の型宣言とdeclare(strict_types=1)の関係

declare(strict_types=1)の効力範囲について - Qiita

前回の記事と関連しますが、戻り値の型宣言の挙動もややこしそうなのでメモします。

非strict で 非strictを呼び出す

B.php(非strict) -> A.php(非strict)

A.php
<?php
function add($a, $b): int
{
    return $a + $b;
}
B.php
<?php
require_once 'A.php';
var_dump(add(1.0, 2.0));
$ php B.php 
int(3)

なるべくキャストで型を合わせるような挙動になりますので、戻り値はintという宣言によってキャストされ、int(3)となります。double型では返ってきません。

strict で 非strictを呼び出す

B.phpの先頭に declare(strict_types=1); を追記すると、、

B.php(strict) -> A.php(非strict)

$ php B.php
int(3)

実行できてしまいました。つまり、戻り値の型宣言の挙動は、その関数の実行時に含まれるので、呼び出し元ではなく定義時のstrictモードに依存するということです。

非strict で strictを呼び出す

B.php(非strict) -> A.php(strict)

$ php B.php 
PHP Fatal error:  Uncaught TypeError: Return value of add() must be of the type integer, float returned in /Users/hiraku/sandbox/stricttypes/return/A.php:5
Stack trace:
#0 /Users/hiraku/sandbox/stricttypes/return/B.php(3): add(1, 2)
#1 {main}
  thrown in /Users/hiraku/sandbox/stricttypes/return/A.php on line 5