5

PHPでクラス名プレフィックスなしでオブジェクトを配列に変換(キャスト)する方法は?

class Teste{

    private $a;
    private $b;

    function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

}

var_dump((array)(new Teste('foo','bar')));

結果:

array
  '�Teste�a' => string 'foo' (length=3)
  '�Teste�b' => string 'bar' (length=3)

期待される:

array (
a => 'foo'
b => 'bar' )
4

4 に答える 4

14

マニュアルから:

オブジェクトが配列に変換されると、結果は、要素がオブジェクトのプロパティである配列になります。キーはメンバー変数名ですが、いくつかの注目すべき例外があります。整数プロパティにはアクセスできません。プライベート変数には、変数名の前にクラス名が付加されます。保護された変数には、変数名の前に「*」が付いています。これらの付加値には、両側にnullバイトがあります。これにより、予期しない動作が発生する可能性があります。

したがって、次のように問題を回避できます。

$temp = (array)(new Teste('foo','bar'));
$array = array();
foreach ($temp as $k => $v) {
  $k = preg_match('/^\x00(?:.*?)\x00(.+)/', $k, $matches) ? $matches[1] : $k;
  $array[$k] = $v;
}
var_dump($array);

衝突のリスクがないため、この動作を制御/無効にする方法がないのは奇妙に思えます。

于 2012-08-07T14:10:22.700 に答える
3

「クラス名プレフィックス」は、プロパティの(内部)名前の一部です。PHPは、これをプロパティやサブクラスとprivate区別するために何かが必要であると宣言したためです。$a$b

それを回避する最も簡単な方法:それらを作らないでくださいprivate。代わりにそれらを宣言することができますprotected

ただし、これはすべての場合の解決策ではありません。通常private、意図的なものとして何かを宣言するためです。変換を行うメソッドを実装することをお勧めします。これにより、結果の配列がどのように見えるかをさらに細かく制御できます

public function toArray() {
  return array(
    'a' => $this->a,
    'b' => $this->b
  );
}
于 2012-08-07T14:11:43.727 に答える
2

私の知る限り、PHPにはあなたが望むことをする簡単な方法がありません。ほとんどの言語はそうではありません。振り返りを調べる必要があります。このドキュメントをご覧ください:http ://www.php.net/manual/en/reflectionclass.getproperties.php

期待どおりに機能する関数を作成しました。

function objectToArr($obj)
{
    $result = array();
    ReflectionClass $cls = new ReflectionClass($obj);
    $props = $cls->getProperties();
    foreach ($props as $prop)
    {
        $result[$prop->getName()] = $prop->getValue($obj);
    }
}
于 2012-08-07T14:16:24.870 に答える
1

Reflectionを使用して、このタスクを解決できます。しかし、いつものように、これはクラスの設計がやや壊れていることを示す強力な指標です。でも:

function objectToArray($obj) {
    // Create a reflection object
    $refl = new ReflectionClass($obj);

    // Retrieve the properties and strip the ReflectionProperty objects down
    // to their values, accessing even private members.
    return array_map(function($prop) use ($obj) {
        $prop->setAccessible(true);
        return $prop->getValue($obj);
    }, $refl->getProperties());
}

// Usage:
$arr = objectToArray( new Foo() );
于 2012-08-07T14:18:31.890 に答える