Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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
Hiraku
PHP, Go界隈をうろうろしています。最近はgRPCと戦ってる。 特に明示していなければ、記事中のソースコード片は `CC-0 1.0` とします。出典表示無しで自由にコピペして頂いて構いません。 ただ、記事自体をコピペされるのは嫌なので、ソースコード部分以外の文章は通常通り全ての著作権を私が保持するものとします。 引用を超える範囲のコピペは止めて下さい。
http://blog.tojiru.net/
mercari
フリマアプリ「メルカリ」を、グローバルで開発しています。
https://tech.mercari.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away