[PHP]変数、オブジェクトの参照渡しについて

PHP5 において、次のように書いても、変数 $a が書き換えられることはありません

<?php
$a   = "A";
$ref = $a;
$ref = "B";
echo $a;
結果: A

「&」を変数名の前につけると、その変数の別名(エイリアス)のような扱いになり、
別名の変数に加えた変更は元の変数にも影響するようになります。これを「参照渡し」といいます。

<?php
$a   = "A";
$ref = &$a;
$ref = "B";
echo $a;
結果: B

オブジェクト型の場合は、この「参照渡し」が常に行われるので、何も指定しなくても結果が変化します

$obj    = new stdClass();
$obj->a = "A";
$ref    = $obj;
$ref->a = "B";
echo $obj->a;
結果: B

オブジェクトのプロパティを代入した場合は、参照渡しが行われません。

$obj    = new stdClass();
$obj->a = "A";
$ref    = $obj->a;
$ref    = "B";
echo $obj->a;
結果: A

「&」を使えばこちらも同様に参照渡しとなります。

$obj    = new stdClass();
$obj->a = "A";
$ref    = &$obj->a;
$ref    = "B";
echo $obj->a;
結果: B

[PHP]basename() はマルチバイトに対応できない?

ファイルパスから末尾のファイル名だけを取り出してくれる basename() は便利ですが、
ファイル名が日本語の場合などは、文字の一部が文字化けてしまったり、消えてしまったりすることがあります。

その際 setlocale() により適切なロケールを設定すれば正しく動作するようになります。

setlocale(LC_CTYPE, 'ja_JP.UTF-8');
$path = 'テスト.txt';
echo basename($path);

ただし PHP のバージョンによっては正常に動作しないケースも有るようなので、代替として次のような関数を作ってみました。

<?php
$path = 'http://localhost/test/日本語.txt';
header("Content-type: text/html; charset=UTF-8");
echo mb_basename($path, ".txt");

function mb_basename($str, $suffix=null){
	$tmp = preg_split('/[\/\\\\]/', $str);
	$res = end($tmp);
	if(strlen($suffix)){
		$suffix = preg_quote($suffix);
		$res = preg_replace("/({$suffix})$/u", "", $res);
	}
	return $res;
}

区切り文字にはスラッシュ・バックスラッシュ(円マーク)が混在して使えます。
suffix にも対応させてあります。

[PHP]json_decode した stdClass Object を扱う

stdClass Object
(
    ["sample"] => stdClass Object
        (
            ["color"] => red
        )

    ["0"] => stdClass Object
        (
            ["color"] => green
        )

)

json_decode をすると第2引数を指定しない限り上のようになることがあります。
sample の color を取り出すなら、「$foo->sample->color」で良いのですが、
[0] のほうを取り出そうとして「$foo->0->color」とやってもエラーになります。
かといって $foo->item(0) みたいなものがあるわけでもないようなので、
素直に Array にキャストするのが普通ですが、もし強引にそのまま扱いたいのであれば

$foo->{'0'}->color

のようにすればとりあえず取れます。

とは言え扱いにくいので json_decode($foo, true) として連想配列にしておいたほうがいいと思います。


2012/11/24 追記:
この方法はキーがString型の場合のみ使用できます。