PHPの型一覧　変数の型とタイプヒンティングできる型は別

#型の分類

PHPの型の分類として下記の３種類があります。

* スカラー型
* 複合型
* 特殊型

この3つの分類の中にいろいろな型があるので
それぞれ説明していきます。

#スカラー型（分類）

スカラー型とは、配列などと異なり
より小さな部分に分割することができない値のことです。

スカラー型には下記の4種類の型があります。

| データ型（日本語） | データ型（英語） | 概要 |
|:-:|:-:|:-:|
| 論理型 | bool、boolean | trueまたはfalseのみ。 |
| 整数型 | int、integer | -1、0、1などの整数。<br> 10進数以外も表現可能。  |
| 浮動小数点型 | float、double | 3.14のような小数点数。<br> また指数表現も可能。  |
| 文字列型 | string | クォートで囲まれた文字列。  |

##論理型（bool、boolean）

論理型は、true（正しい）かfalse（間違い）のいずれかの状態のみを持ちます。

```php
$bool = true;

var_dump($bool);
// bool(true)
```

##整数型（int、integer）

整数型は、[...-2、-1、0、1、2...]のような整数をを表現できます。
また、10進数以外にも2進数、8進数、16進数を表現することが可能です。

2進数、8進数、16進数を表現するには
それぞれ決められたプレフィックスを付ける必要があります。

2進数→「0b」
8進数→「0」
16進数→「0x」

```php
$int10 = 125;
var_dump($int10);
// int(125)

$int2 = 0b1111101;
var_dump($int2);
// int(125)

$int8 = 0175;
var_dump($int8);
// int(125)

$int16 = 0x7D;
var_dump($int16);
// int(125)
```

##浮動小数点型（float、double）

浮動小数点型は、`0.03`や`12.58`のような小数点数を表現できます。
また、`2.34e8`や`5.67e-6`のような指数表現を使うことも可能です。

```php
$float = 1.23;
var_dump($float);
// float(1.23)

$pow = 1.23e4;
var_dump($pow);
// float(12300)
```

ちなみに、float型の変数を`gettype()`すると
floatではなくdoubleと出力されるという点に注意します。

```php
$float = 1.23;

var_dump($float);
// float(1.23)

echo gettype($float);
// double
```

これについて
公式マニュアルには
>歴史的な理由により、float の場合には "double"が返されます。"float" とはなりません

とあります。
https://www.php.net/manual/ja/function.gettype.php


##文字列型（string）

文字列型は、
シングルクォートまたはダブルクォートで囲まれた`0文字以上`の文字列を表します。

`0文字以上`と書いた通り、
`$empty = ''`のような空文字も文字列型となります。

```php
$string = 'aaa';
var_dump($string);
// string(3) "aaa"

$empty = '';
var_dump($empty);
// string(0) ""
```


#複合型（分類）

複合型とは、スカラー型とは対照的に、
複数の値をまとめて扱う型の分類です。

複合型には下記の2種類の型があります。

| データ型（日本語） | データ型（英語） | 概要 |
|:-:|:-:|:-:|
| 配列型 | array | 複数のデータの集合 |
| オブジェクト型 | object | データと手続きの集合  |

##配列型

配列型は、
複数のデータを並べて格納した型です。

通常の配列だけでなく、
連想配列や多次元配列、値が1つもない空配列も配列型となります。

```php
$array1 = ['a', 'b'];
var_dump($array1);
// array(2) {
//   [0]=>
//   string(1) "a"
//   [1]=>
//   string(1) "b"
// }

$array2 = ['key' => 'value'];
var_dump($array2);
// array(1) {
//   ["key"]=>
//   string(5) "value"
// }

$array3 = [];
var_dump($array3);
// array(0) {
// }
```


##オブジェクト型

オブジェクト型とは、
データと手続きをまとめたもので、
クラスをnewして作ったインスタンスはオブジェクト型になります。

```php
class MyClass {}
$object = new MyClass();
var_dump($object);
// object(MyClass)#1 (0) {
// }
```

#特殊型（分類）

特殊型とは、スカラー型でも複合型でもない特殊な型の分類ことです。

特殊型には下記の2種類の型があります。

| データ型（日本語） | データ型（英語） | 概要 |
|:-:|:-:|:-:|
| リソース型 | resource | 外部リソースへの参照。 |
| ヌル型 | null | 値を持たないことを表す。  |

##リソース型

リソース型は特殊な型で、
外部リソースへの参照を保持しています。

例えば、
`fopen()`でファイルを参照したり
`mysql_connect()`でDBへ接続した状態を変数に入れると
それはリソース型になります。

```php
$resource = fopen('test.txt', 'r');
var_dump($resource);
// resource(470) of type (stream)
```

##ヌル型

ヌル型は、
ある変数が値を持たないことを表します。

```php
$null = null;
var_dump($null);
// NULL
```

#補足
[PHP: 型 - Manual](https://www.php.net/manual/ja/language.types.php)
このPHP公式マニュアルの型のページでは
上記8種類の型に加えて
[Iterable](https://www.php.net/manual/ja/language.types.iterable.php)と[Callable](https://www.php.net/manual/ja/language.types.callable.php)という型も記述されています。


　
　

いろいろな書籍やブログ記事などを読んでも、
上記8種類をPHPの型一覧として紹介しているものがあったり
Iterable、Callableも加えて紹介しているものがあったりして
少し混乱しました。

　
　
私なりに調べて整理しましたが、
`PHPの型`というものを
`変数の型`と`型宣言（タイプヒンティング）できる型`とに分けて考えたほうがよさそうです。

　
　
`変数の型`とは
ある変数を`gettype()`や`var_dump()`したときに
出力される型のことです。
[PHP: gettype - Manual](https://www.php.net/manual/ja/function.gettype.php#refsect1-function.gettype-returnvalues)

これまで紹介した8種類の型は、
すべて変数の型になります。
　
　
　


`型宣言（タイプヒンティング）できる型`とは
その名の通り型宣言（タイプヒンティング）で指定できる型のことです。
[PHP: 関数の引数 - Manual](https://www.php.net/manual/ja/functions.arguments.php#functions.arguments.type-declaration)

IterableやCallableは変数の型ではないが、
型宣言（タイプヒンティング）できる型です。

　
　
　
例えば、クロージャを変数に入れて`var_dump()`すると
オブジェクト型として出力されます。

```php
$closure = function(){};
var_dump($closure);
// object(Closure)#1 (0) {
// }
```
　
　
このクロージャを`callable`としてタイプヒンティングされた関数に渡しても
エラーとはなりません。

```php
$closure = function(){};

typeCallable($closure);

function typeCallable(callable $closure){};
// エラーにならない
```
　
　
　

Iterableに関しても同じような話で、
arrayやTraversableインターフェイスを実装したオブジェクトを
`gettype()`や`var_dump()`しても`Iterable`とは出力されず、
`array`や`object`として出力されますが、
タイプヒンティングで`iterable`を指定しても
それらの変数はエラーになりません。
　
　
　
　
このように、`PHPの型`と一言で言っても、
変数の型と型宣言（タイプヒンティング）できる型が
それぞれあるということを認識しておいたほうがよさそうです。
※`変数の型`と`型宣言できる型`という分類、言葉は僕が勝手にそう呼んでいるだけで、公式の言葉ではありません

　
さらに、それらに加えて
[ドキュメント上でのみ使われる疑似的な型](https://www.php.net/manual/ja/language.pseudo-types.php)というのもあるので
それも認識しておきましょう。
（mixedやnumberなど）


#参考
[独習PHP](https://www.amazon.co.jp/dp/B01FH3KVNU/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
[PHPの基本構文「変数の型」 - PHP入門 - Webkaru](https://webkaru.net/php/variable-types/)
[PHPの型について](https://qiita.com/shosho/items/266b87b42ef55c8cd139)
[PHPの型と型安全について(PHP7からのPHPプログラミング)](https://qiita.com/bokotomo/items/1ead446ef689dc45b487)