これはシンプルでなければなりませんが、答えが見つからないようです。
プロパティを持たない汎用stdClassオブジェクト$foo
があります。まだ定義されていない新しいプロパティ$bar
を追加したい。これを行う場合:
$foo = new StdClass();
$foo->bar = '1234';
厳格モードのPHPで問題が発生します。
既にインスタンス化されたオブジェクトにプロパティを追加する適切な方法(クラス宣言以外)は何ですか?
注:stdClass型の汎用PHPオブジェクトを使用してソリューションを動作させたい。
この問題の背景。 JSONオブジェクトの配列であるJSON文字列をデコードしています。 json_decode()
は、StdClassオブジェクトの配列を生成します。これらのオブジェクトを操作し、各オブジェクトにプロパティを追加する必要があります。
プロパティをオブジェクトに絶対に追加する必要がある場合は、配列としてキャストし、プロパティを(新しい配列キーとして)追加してから、オブジェクトとしてキャストし直すことができると思います。 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' ) );
次のようにします:
$foo = new StdClass();
$foo->{"bar"} = '1234';
今試してください:
echo $foo->bar; // should display 1234
デコードされたJSONを編集する場合は、オブジェクトの配列ではなく連想配列として取得してみてください。
$data = json_decode($json, TRUE);
私はいつもこの方法を使用します:
$foo = (object)null; //create an empty object
$foo->bar = "12345";
echo $foo->bar; //12345
マジックメソッド__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:私は自分のコードをテストしませんでした、ただの一般的なアイデア...
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
)