web-dev-qa-db-ja.com

エラーを生成せずにPHP> = 5.3 strictモードでオブジェクトにプロパティを追加する方法

これはシンプルでなければなりませんが、答えが見つからないようです。

プロパティを持たない汎用stdClassオブジェクト$fooがあります。まだ定義されていない新しいプロパティ$barを追加したい。これを行う場合:

$foo = new StdClass();
$foo->bar = '1234';

厳格モードのPHPで問題が発生します。

既にインスタンス化されたオブジェクトにプロパティを追加する適切な方法(クラス宣言以外)は何ですか?

注:stdClass型の汎用PHPオブジェクトを使用してソリューションを動作させたい。

この問題の背景。 JSONオブジェクトの配列であるJSON文字列をデコードしています。 json_decode()は、StdClassオブジェクトの配列を生成します。これらのオブジェクトを操作し、各オブジェクトにプロパティを追加する必要があります。

63
Ray

プロパティをオブジェクトに絶対に追加する必要がある場合は、配列としてキャストし、プロパティを(新しい配列キーとして)追加してから、オブジェクトとしてキャストし直すことができると思います。 stdClassオブジェクトに遭遇するのは、配列をオブジェクトとしてキャストするとき、または新しいstdClassオブジェクトを最初から作成するとき(そしてもちろんjson_decode()何か-忘れてばかげている!)。

の代わりに:

$foo = new StdClass();
$foo->bar = '1234';

あなたがするだろう:

$foo = array('bar' => '1234');
$foo = (object)$foo;

または、既存のstdClassオブジェクトが既にある場合:

$foo = (array)$foo;
$foo['bar'] = '1234';
$foo = (object)$foo;

1ライナーとして:

$foo = (object) array_merge( (array)$foo, array( 'bar' => '1234' ) );
97
Crontab

次のようにします:

$foo = new StdClass();
$foo->{"bar"} = '1234';

今試してください:

echo $foo->bar; // should display 1234
70
jmnerd

デコードされたJSONを編集する場合は、オブジェクトの配列ではなく連想配列として取得してみてください。

$data = json_decode($json, TRUE);
11
Rocket Hazmat

私はいつもこの方法を使用します:

$foo = (object)null; //create an empty object
$foo->bar = "12345";

echo $foo->bar; //12345
2
Ragnar

マジックメソッド__Setおよび__getを使用する必要があります。簡単な例:

class Foo
{
    //This array stores your properties
private $content = array();

public function __set($key, $value)
{
            //Perform data validation here before inserting data
    $this->content[$key] = $value;
    return $this;
}

public function __get($value)
{       //You might want to check that the data exists here
    return $this->$content[$value];
}

}

もちろん、この例をこのように使用しないでください。セキュリティはまったくありません:)

編集:あなたのコメントを見ました、ここに反射とデコレータに基づいた代替案があります:

 class Foo
 {
private $content = array();
private $stdInstance;

public function __construct($stdInstance)
{
    $this->stdInstance = $stdInstance;
}

public function __set($key, $value)
{
    //Reflection for the stdClass object
    $ref = new ReflectionClass($this->stdInstance);
    //Fetch the props of the object

    $props = $ref->getProperties();

    if (in_array($key, $props)) {
        $this->stdInstance->$key = $value;
    } else {
        $this->content[$key] = $value;
    }
    return $this;
}

public function __get($value)
{
    //Search first your array as it is faster than using reflection
    if (array_key_exists($value, $this->content))
    {
        return $this->content[$value];
    } else {
        $ref = new ReflectionClass($this->stdInstance);

        //Fetch the props of the object
        $props = $ref->getProperties();

        if (in_array($value, $props)) {

        return $this->stdInstance->$value;
    } else {
        throw new \Exception('No prop in here...');
    }
}
 }
}

PS:私は自分のコードをテストしませんでした、ただの一般的なアイデア...

1
Benjamin Dubois

Phpの新しいバージョンかどうかはわかりませんが、これは動作します。私はPHP 5.6を使用しています

    <?php
    class Person
    {
       public $name;

       public function save()
       {
          print_r($this);
       }
    }

   $p = new Person;
   $p->name = "Ganga";
   $p->age = 23;

   $p->save();

これが結果です。 saveメソッドは実際に新しいプロパティを取得します

    Person Object
    (
       [name] => Ganga
       [age] => 23
    )
0
Ganga