web-gelistirme-sc.com

İçindeki nesneye özellik nasıl eklenir PHP > = 5.3 hata üretmeden katı mod

Bu basit olmalı, ama bir cevap bulamıyorum ...

Hiçbir özellik olmayan genel bir stdClass nesnesi $foo var. Henüz tanımlanmamış yeni bir özellik $bar eklemek istiyorum. Bunu yaparsam:

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

PHP sıkı modda şikayet ediyor. 

Zaten başlatılmış bir nesneye bir özellik eklemenin (sınıf bildiriminin dışında) uygun yolu nedir?

NOT: Çözümün stdClass türündeki genel PHP nesnesiyle çalışmasını istiyorum.

Bu konuda biraz arka plan. Json nesnelerinin bir dizisi olan bir json dizisinin kodunu çözüyorum. json_decode(), bir StdClass nesnesi dizisi oluşturur. Bu nesneleri değiştirmem ve her birine bir özellik eklemem gerekiyor.

60
Ray

Özelliği kesinlikle nesneye eklemeniz gerekirse, onu bir dizi olarak atayabileceğinizi, mülkünüzü (yeni bir dizi anahtarı olarak) ekleyebileceğinizi ve ardından bir nesne olarak geri alabileceğinizi düşünüyorum. stdClass nesnelerine rastladığınız tek zaman (inanıyorum) bir diziyi nesne olarak attığınızda veya sıfırdan yeni bir stdClass nesnesi oluşturduğunuzda (ve tabii ki json_decode() - bir şey unutmak için aptal!.

Yerine:

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

Yapardın:

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

Veya zaten bir stdClass nesnesine sahipseniz:

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

Ayrıca 1 astar olarak:

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

Böyle yapın:

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

şimdi dene:

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

Kodu çözülmüş JSON'u düzenlemek istiyorsanız, onu bir nesne dizisi yerine ilişkisel bir dizi olarak almayı deneyin.

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

Her zaman bu şekilde kullanırım:

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

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

sihirli yöntemleri __Set ve __get kullanmalısınız. Basit örnek: 

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];
}

}

Elbette, bu örneği şu şekilde kullanmayın: Güvenlik yok :) 

EDIT: Yorumlarınızı gördüm, burada yansıma ve bir dekoratör dayalı bir alternatif olabilir:

 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: Kodumu test etmedim, sadece genel fikir ...

1
Benjamin Dubois

PHP'nin yeni sürümü olup olmadığını bilmiyorum, ama bu işe yarıyor. 5.6 php kullanıyorum

    <?php
    class Person
    {
       public $name;

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

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

   $p->save();

Sonuç bu. Kaydetme yöntemi aslında yeni özellik alır

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