NULLへのキャストって……?

PHPの型キャストは(array)とか(object)とか変態的なのがあるけど、最近(unset)なるものが存在することに気づいた。
unset($var)のことではない。(unset)$varだ。


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

  • (int), (integer) - 整数へのキャスト
  • (bool), (boolean) - 論理値へのキャスト
  • (float), (double), (real) - float へのキャスト
  • (string) - 文字列へのキャスト
  • (array) - 配列へのキャスト
  • (object) - オブジェクトへのキャスト
  • (unset) - NULL へのキャスト (PHP 5)

(binary) によるキャストや b プレフィックスのサポートは、PHP 5.2.1 で追加されました。

NULLへのキャスト?

<?php
$foo = 'test';
$bar = (unset)$foo;
var_dump($bar);                   // NULL

var_dump((unset)'string');        // NULL
var_dump((unset)12345);           // NULL
var_dump((unset)true);            // NULL
var_dump((unset)null);            // NULL
var_dump((unset)(new StdClass));  // NULL
?>

なるほど、NULLになるな。
で、これ何に使うの??

<?php
$bar = NULL;
?>

じゃだめなんですか!?


ググってもunset()のことばかり出てきて調べるのが大変なんだけど、Stack Overflowで2件ほど同様の疑問を投げかける投稿が見つかった。

回答の中にはこんな例が出ていたけど、わざわざこう書く理由がわからないし、回答者自身も含めて「うーん」な感じで終わってる模様。

<?php
$foo = bar((unset) baz());
?>
<?php
function fallback()
{
    // some stuff here
    return 'zoo';
}

var_dump(false ? 'foo' : fallback()); // zoo
var_dump(false ? 'foo' : (unset) fallback()); // null
?>


ソースコードをちらっと見てみたけど、型(?)の分だけ*1とりあえずキャスト用意しておきました感しかなくて意図がよくわからなかった。

(array)$var

ちなみに(array)はこんな感じ。
オブジェクトとNULLを除いて、自身を要素に持つ配列になる。

<?php
class Foo {
    public    $x = 10;
    protected $y = 20;
    private   $z = 30;
    function foo() {}
}
$foo = new Foo;

var_dump((array)'string');                    // (1)
var_dump((array)123);                         // (2)
var_dump((array)true);                        // (3)
var_dump((array)array(10, 20, 30));           // (4)
var_dump((array)array('x' => 10, 'y' => 20)); // (5)
var_dump((array)$foo);                        // (6)
var_dump((array)null);                        // (7)
?>
array(1) {                      // (1)
  [0] => string(6) "string"
}
array(1) {                      // (2)
  [0] => int(123)
}
array(1) {                      // (3)
  [0] => bool(true)
}
array(3) {                      // (4)
  [0] => int(10)
  [1] => int(20)
  [2] => int(30)
}
array(2) {                      // (5)
  'x' => int(10)
  'y' => int(20)
}
array(3) {                      // (6)
  'x'        => int(10)
  '\0*\0y'   => int(20)
  '\0Foo\0z' => int(20)
}
array(0) { }                    // (7)

NULLは自身を値に持つ配列ではなくて、空配列になる。
オブジェクトはなんか面倒なことになるので避けたほうがいい。


こういう感じで、1個の時はスカラ値でも渡せる関数…みたいなやつで時折見かける。

<?php
function do_something($item) {
    foreach ((array)$item as $x) {
        echo $x;
    }
}

do_something('foo');
do_something(array('foo', 'bar', 'baz'));
?>

(object)$var

(object)はこんな感じ。

<?php
var_dump((object)'string');                     // (1)
var_dump((object)123);                          // (2)
var_dump((object)true);                         // (3)
var_dump((object)array(10, 20, 30));            // (4)
var_dump((object)array('x' => 10, 'y' => 20));  // (5)
var_dump((object)$foo);                         // (6)
var_dump((object)null);                         // (7)
?>
class stdClass#1 (1) {                  // (1)
  public $scalar => string(6) "string"
}
class stdClass#1 (1) {                  // (2)
  public $scalar => int(123)
}
class stdClass#1 (1) {                  // (3)
  public $scalar => bool(true)
}
class stdClass#1 (3) {                  // (4)
    int(10)
    int(20)
    int(30)
}
class stdClass#2 (2) {                  // (5)
  public $x => int(10)
  public $y => int(20)
}
class Foo#1 (3) {                       // (6)
  public    $x => int(10)
  protected $y => int(20)
  private   $z => int(30)
}
class stdClass#1 (0) { }                // (7)

stdClassのインスタンスになる。
オブジェクトはそのまま。
連想配列はわかるけど、普通の配列はどういう状況なのかよくわからない。
というか連想配列もキーによってはやばい感じがある。

<?php
var_dump((object)array('x a b' => 10, 'てすと' => 20));
?>
class stdClass#2 (2) {
  public $x a b  => int(10)
  public $てすと => int(20)
}



オブジェクトがオブジェクトに変換される場合、それは修正されません。 他の型の値がオブジェクトに変換される場合、ビルトインクラスである stdClass の新しいインスタンスが生成されます。 値が null の場合、新しいインスタンスは空となります。 配列がオブジェクトに変換される場合、配列のキーがプロパティ名となり、 配列の値がプロパティの値となります。他の値の場合、 scalar という名前のメンバ変数が値を格納します。

*1:resource型などはなかった。