## 型の相互変換

PHP は変数宣言時に明示的な型定義を必要としません。 型を定義しない場合、変数の型は保存する値によって決まります。 これは、変数 $var に文字列を代入した場合、 $var の型は文字列 (string) になることを意味しています。 その後、整数値を $var に代入すると、 その変数の型は整数 (int) になります。

コンテクスト(文脈)によっては、 PHP が値を別の型に自動変換しようとすることがあります。 自動変換が行われる異なるコンテクストが存在するのは、以下のとおりです:

- 数値のコンテクスト
- 文字列のコンテクスト
- 論理コンテクスト
- 整数と文字列のコンテクスト
- 比較のコンテクスト
- 関数のコンテクスト

> 注意: 値を別の型として解釈する必要がある場合でも、 値そのものの型は 変わりません。

変数を強制的にある特定の型として評価させたい場合は、 型キャスト のセクションを参照ください。 ある変数の型を変更したい場合は、settype() を参照ください。

### 数値のコンテクスト

これは、 算術演算子 を使った場合です。

このコンテクストでは、 オペランドのどちらかが float (または整数と解釈できない場合) の場合、 両方のオペランドが float として解釈され、 結果の型は float になります。 そうでない場合、オペランドは整数として解釈され、 結果の型も整数になります。 PHP 8.0.0 以降では、いずれかのオペランドが解釈できない場合、 TypeError がスローされます。

### 文字列のコンテクスト

これは、 echo, print や 文字列中の変数のパース、または 文字列演算子 を使った場合です。

値は文字列として解釈されます。 文字列として解釈できない場合、 TypeError がスローされます。 PHP 7.4.0 より前のバージョンでは、 `E_RECOVERABLE_ERROR` が発生していました。

### 論理コンテクスト

これは、 制御構文や 三項演算子, 論理演算子 を使った場合です。

値は論理値 (bool) として解釈されます。

### 整数と文字列のコンテクスト

これは、 ビット演算子 を使った場合です。

全てのオペランドが文字列の場合、 結果の型も文字列になります。 そうでない場合、 オペランドは整数として解釈され、 結果の型も整数になります。 PHP 8.0.0 以降では、いずれかのオペランドが解釈できない場合、 TypeError がスローされます。

### 比較のコンテクスト

これは、 比較演算子 を使った場合です。

このコンテクストで発生する型変換については、 さまざまな型の比較表 に説明があります。

### 関数のコンテクスト

これは、値が型付きのパラメータ、型付きプロパティに渡された場合や、 戻り値の型を宣言している関数から値が返される場合です。

このコンテクストでは、値はその型の値でなければなりません。 これにはふたつ例外があります。 ひとつめは値の型が int で、 宣言されている型が float の場合、 整数が浮動小数点に変換されることです。 ふたつめは型が スカラー型、 値がスカラー型に変換可能な場合で、 かつ型の自動変換モードが有効な場合(デフォルト)、 スカラー型の値が別の変換可能なスカラー型に変換される可能性があることです。 この振る舞いに関する詳細は、以下を参照ください:

警告

内部関数 は、`null` を自動的にスカラー型に変換します。 この振る舞いは PHP 8.1.0 以降は 推奨されなくなっています。

#### 単一の型宣言における、型の自動変換

- 論理型(bool) が宣言されている場合: 値は bool として解釈されます。
- 整数型 (int) が宣言されている場合: int への変換が定義されている場合は、int として解釈されます。たとえば、文字列が 数値形式 である場合です。
- float が宣言されている場合: float への変換が定義されている場合は、float として解釈されます。たとえば、文字列が 数値形式 である場合です。
- 文字列 (string) 型として宣言されている場合: 値は文字列として解釈されます。

#### union 型と型の自動変換

`strict_types` が有効になっていない場合、 スカラー型の宣言は、限られた暗黙の型変換が行われます。 値の正確な型が union の一部に指定されていない場合、 次の順に対象となる型が選択されます:

1. int
2. float
3. string
4. bool

正確な型が union の中に存在し、 かつ値が PHP の既存の型チェックのセマンティクスによって型変換できる場合、 その型が選択されます。 そうでない場合、次の型を試そうとします。
警告

例外として、値が文字列で、int と float が union に含まれていた場合、 型は既存の 数値形式の文字列 を解釈するセマンティクスによって決まります。 たとえば、`"42"` の場合、 int が選ばれますし、 `"42.0"` の場合、float が選ばれます。

> 注意:

> 上のリストに入っていない型については、 暗黙の型変換が行われる対象ではありません。 特に、暗黙のうちに null, false, true に変換されることはありません。

例1 union の型のひとつに変換される例

    <?php
    // int|string
    42    --> 42          // 正確に型が一致
    "42"  --> "42"        // 正確に型が一致
    new ObjectWithToString --> "Result of __toString()"
                          // オブジェクトは int と互換性がないので、文字列にフォールバック
    42.0  --> 42          // float は int と互換性がある
    42.1  --> 42          // float は int と互換性がある
    1e100 --> "1.0E+100"  // int には大きすぎる float なので、文字列にフォールバック
    INF   --> "INF"       // int には大きすぎる float なので、文字列にフォールバック
    true  --> 1           // bool は int と互換性がある
    []    --> TypeError   // 配列はint, string と互換性はない。
    // int|float|bool
    "45"    --> 45        // int の数値形式の文字列
    "45.0"  --> 45.0      // float の数値形式の文字列
    "45X"   --> true      // 数値形式の文字列ではない。boolにフォールバック
    ""      --> false     // 数値形式の文字列ではない。boolにフォールバック
    "X"     --> true      // 数値形式の文字列ではない。boolにフォールバック
    []      --> TypeError // 配列はint, float, bool と互換性はない。
    ?>

### 型キャスト

型キャストは、変換しようとする型の名前を括弧で括り、 キャストする変数の前に置くことで、値を別の型に変換するものです。

例2 型キャストの例

    <?php
    $foo = 10;          // $foo は整数です
    $bar = (bool) $foo; // $bar は boolean です

    var_dump($bar);
    ?>

使用可能なキャストを以下に示します:

- `(int)` - 整数(int) へのキャスト
- `(bool)` - 論理値(bool) へのキャスト
- `(float)` - float へのキャスト
- `(string)` - 文字列(string) へのキャスト
- `(array)` - 配列(array) へのキャスト
- `(object)` - オブジェクト(object) へのキャスト
- `(unset)` - NULL へのキャスト

PHP 8.5.0 以降では `(void)` キャストも使用できますが、これは値の変換ではありません。 式の結果を明示的に破棄する文として使用します。

警告

`(integer)` は、`(int)` のエイリアスです。 `(boolean)` は、`(bool)` のエイリアスです。 `(binary)` は、`(string)` のエイリアスです。 `(double)` と `(real)` は、`(float)` のエイリアスです。 これらのキャストは、正規化された型の名前を使っていません。 そのため PHP 8.5.0 以降では推奨されなくなりました。

警告

キャストのエイリアス `(real)` を使うことは、PHP 7.4.0 以降は推奨されなくなり、PHP 8.0.0 で削除されました。

警告

`(unset)` によるキャストは、 PHP 7.2.0 以降推奨されなくなりました。 `(unset)` によるキャストは、 値に NULL 値を代入することと同じです。 `(unset)` によるキャストは、PHP 8.0.0 で削除されました。

警告

将来サポートされることを見越して、`(binary)` によるキャストと `b` プレフィックスが存在しています。 `(binary)` と `(string)` は現状は等価ですが、将来変更される可能性があります。そのため、現状等価であることに依存すべきではありません。

> 注意:

> キャストの括弧内のホワイトスペースは無視されます。 よって、以下のふたつのキャストは等価です:

>     <?php
>     $foo = (int) $bar;
>     $foo = ( int ) $bar;
>     ?>

以下の例は、リテラル文字列や変数を、バイナリ文字列にキャストします:

    <?php
    $binary = (binary) $string;
    $binary = b"binary string";
    ?>

ある変数を文字列にキャストする代わりに、 二重引用符で括ることもできます。

例3 異なるキャストの仕組み

    <?php
    $foo = 10;            // $foo は整数です
    $str = "$foo";        // $str は文字列です
    $fst = (string) $foo; // $fst も文字列です

    // これは、"they are the same"を出力します
    if ($fst === $str) {
        echo "they are the same", PHP_EOL;
    }
    ?>

型の間でキャストを行う際の動作は、必ずしも明確ではありません。 詳細については、以下の節を参照ください:

- 論理値への変換
- 整数への変換
- 浮動小数点数への変換
- 文字列への変換
- 配列への変換
- オブジェクトへの変換
- リソース型への変換
- NULL への変換
- `(void)` による値の破棄
- 型の比較表

> 注意: PHP では配列の添字と同じ構文を使用した文字列へのアクセスをサポートしているので、次の例はあらゆるバージョンの PHP で成立します:

> 例4 文字列で配列の添字を使う

>     <?php
>     $a    = 'car'; // $a は文字列です
>     $a[0] = 'b';   // $a はここでも文字列です
>     echo $a;       // bar
>     ?>

> 詳細は、 文字列への文字単位のアクセス を参照ください。

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open