PHPの論理値・論理否定・isset()・empty()の比較

実行したコード

```php
$a;
$b = acos(8); // NaNになる
$c = array();
$funcA = function(){return;};
$funcB = function(){return 0;};
$funcC = function(){return 1;};
$DateA = new DateTime('1 January 1970 00:00:00 UTC');
$DateB = new DateTime('1 January 1970 00:00:00');
$vals = array(
    'Boolean（true）' => true,
    'Boolean（false）' => false,
    '数値（0）' => 0,
    '数値（1）' => 1,
    '数値（NaN(非数値)）' => $b,
    '数値（NaN(非数値をis_nanで確認)）' => is_nan($b),
    '数値（0とnull）' => 0 == null,
    '文字列（0）' => '0',
    '文字列（1）' => '1',
    '空の文字列' => '',
    '半角スペース' => ' ',
    'NULL' => null,
    '未定義の変数' => $a,
    '存在しない変数' => $c['a'],
    '$a == null' => $a == null,
    '$a === null' => $a === null,
    '空の配列' => array(),
    '値を返さない関数' => $funcA(),
    '0を返す関数' => $funcB(),
    '1を返す関数' => $funcC(),
    '関数オブジェクト' => $funcA,
    '1970/01/01（UTC）' => $DateA,
    '1970/01/01' => $DateB,
    '1970/01/01（UTC）（getTimestamp()）' => $DateA->getTimestamp(),
    '1970/01/01（getTimestamp()）' => $DateB->getTimestamp(),
    '無効な日付（あ）' => date('U', strtotime('あ')),
    '無効な日付?（a）' => date('U', strtotime('a')),
);

foreach ($vals as $key => $val) {
    echo '|' . $key . '|' . ($val ? '**true**' : 'false') . '|'
        . (!$val ? '**true**' : 'false') .'|'
        . (empty($val) ? '**true**' : 'false') . '|'
        . (isset($val) ? '**true**' : 'false') . '|'
        . PHP_EOL;
}
```

結果

```text
|Boolean（true）|**true**|false|false|**true**|
|Boolean（false）|false|**true**|**true**|**true**|
|数値（0）|false|**true**|**true**|**true**|
|数値（1）|**true**|false|false|**true**|
|数値（NaN(非数値)）|**true**|false|false|**true**|
|数値（NaN(非数値をis_nanで確認)）|**true**|false|false|**true**|
|数値（0とnull）|**true**|false|false|**true**|
|文字列（0）|false|**true**|**true**|**true**|
|文字列（1）|**true**|false|false|**true**|
|空の文字列|false|**true**|**true**|**true**|
|半角スペース|**true**|false|false|**true**|
|NULL|false|**true**|**true**|false|
|未定義の変数|false|**true**|**true**|false|
|存在しない変数|false|**true**|**true**|false|
|$a == null|**true**|false|false|**true**|
|$a === null|**true**|false|false|**true**|
|空の配列|false|**true**|**true**|**true**|
|値を返さない関数|false|**true**|**true**|false|
|0を返す関数|false|**true**|**true**|**true**|
|1を返す関数|**true**|false|false|**true**|
|関数オブジェクト|**true**|false|false|**true**|
|1970/01/01（UTC）|**true**|false|false|**true**|
|1970/01/01|**true**|false|false|**true**|
|1970/01/01（UTC）（getTimestamp()）|false|**true**|**true**|**true**|
|1970/01/01（getTimestamp()）|**true**|false|false|**true**|
|無効な日付（あ）|false|**true**|**true**|**true**|
|無効な日付?（a）|**true**|false|false|**true**|
```

|調べた値|論理値|論理否定「!」|empty()|isset()|
|:-----------|:------------:|:------------:|:-----------:|:-----------:|
|Boolean（true）|**true**|false|false|**true**|
|Boolean（false）|false|**true**|**true**|**true**|
|数値（0）|false|**true**|**true**|**true**|
|数値（1）|**true**|false|false|**true**|
|数値（NaN(非数値)）|**true**|false|false|**true**|
|数値（NaN(非数値をis_nanで確認)）|**true**|false|false|**true**|
|数値（0とnull）|**true**|false|false|**true**|
|文字列（0）|false|**true**|**true**|**true**|
|文字列（1）|**true**|false|false|**true**|
|空の文字列|false|**true**|**true**|**true**|
|半角スペース|**true**|false|false|**true**|
|NULL|false|**true**|**true**|false|
|未定義の変数|false|**true**|**true**|false|
|存在しない変数|false|**true**|**true**|false|
|$a == null|**true**|false|false|**true**|
|$a === null|**true**|false|false|**true**|
|空の配列|false|**true**|**true**|**true**|
|値を返さない関数|false|**true**|**true**|false|
|0を返す関数|false|**true**|**true**|**true**|
|1を返す関数|**true**|false|false|**true**|
|関数オブジェクト|**true**|false|false|**true**|
|1970/01/01（UTC）|**true**|false|false|**true**|
|1970/01/01|**true**|false|false|**true**|
|1970/01/01（UTC）（getTimestamp()）|false|**true**|**true**|**true**|
|1970/01/01（getTimestamp()）|**true**|false|false|**true**|
|無効な日付（あ）|false|**true**|**true**|**true**|
|無効な日付?（a）|**true**|false|false|**true**|

* 数値（NaN(非数値)）は`false`で返して欲しい所ですが`is_nan()`と同じ結果が返ってきています。
* DateTimeで無効な日付は実行できなかったので`date()`で確認した所、`strtotime('a')`の論理値が`true`になってしまう結果に :astonished: 知っている人がいれば何故こうなるのか教えてください :sweat_smile: