如何在PHP >= 5.3严格模式下向对象添加属性而不产生错误

时间:2022-04-05 19:41:07

This has to be simple, but I can't seem to find an answer....

这是简单的,但我似乎无法找到答案....

I have a generic stdClass object $foo with no properties. I want to add a new property $bar to it that's not already defined. If I do this:

我有一个通用的stdClass对象$foo,没有属性。我想给它添加一个新的属性$bar它还没有定义。如果我这样做:

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

PHP in strict mode complains.

在严格模式下的PHP会报错。

What is the proper way (outside of the class declaration) to add a property to an already instantiated object?

向已实例化的对象添加属性的正确方法(类声明之外)是什么?

NOTE: I want the solution to work with the generic PHP object of type stdClass.

注意:我希望这个解决方案可以使用stdClass类型的通用PHP对象。

A little background on this issue. I'm decoding a json string which is an array of json objects. json_decode() generates an array of StdClass object. I need to manipulate these objects and add a property to each one.

关于这个问题的一些背景知识。我正在解码json字符串,它是json对象的数组。json_decode()生成一个StdClass对象数组。我需要操作这些对象并向每个对象添加一个属性。

7 个解决方案

#1


72  

If you absolutely have to add the property to the object, I believe you could cast it as an array, add your property (as a new array key), then cast it back as an object. The only time you run into stdClass objects (I believe) is when you cast an array as an object or when you create a new stdClass object from scratch (and of course when you json_decode() something - silly me for forgetting!).

如果您必须向对象添加属性,我相信您可以将其转换为数组,添加属性(作为新的数组键),然后将其转换为对象。唯一一次碰到stdClass对象(我相信)是当您将数组转换为对象时,或者当您从头创建一个新的stdClass对象时(当然,当您json_decode()某件事时——我真傻,忘了!)

Instead of:

而不是:

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

You'd do:

你会做的事:

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

Or if you already had an existing stdClass object:

或者如果您已经有一个现有的stdClass对象:

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

Also as a 1 liner:

同样作为一行:

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

#2


44  

Do it like this:

这样做:

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

now try:

现在试一试:

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

#3


11  

If you want to edit the decoded JSON, try getting it as an associative array instead of an array of objects.

如果希望编辑解码后的JSON,请尝试将其作为关联数组而不是对象数组。

$data = json_decode($json, TRUE);

#4


1  

you should use magic methods __Set and __get. Simple example:

您应该使用魔法方法__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];
}

}

Of course, don't use this example as this : no security at all :)

当然,不要用这个例子:完全没有安全可言:)

EDIT : seen your comments, here could be an alternative based on reflection and a decorator :

编辑:看到你的评论,这里可以是一个基于反射和装饰者的选择:

 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 : I didn't test my code, just the general idea...

PS:我没有测试我的代码,只是大意……

#5


0  

I don't know whether its the newer version of php, but this works. I'm using php 5.6

我不知道它是否是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();

This is the result. The save method actually gets the new property

这是结果。save方法实际上获取新属性

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

#6


0  

I always use this way:

我总是这么用:

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

echo $foo->bar; //12345

#7


-3  

Yes, is possible to dynamically add properties to a PHP object.

是的,可以动态地向PHP对象添加属性。

This is useful when a partial object is received from javascript.

当从javascript接收部分对象时,这很有用。

JAVASCRIPT side:

JAVASCRIPT的一面:

var myObject = { name = "myName" };
$.ajax({ type: "POST", url: "index.php",
    data: myObject, dataType: "json",
    contentType: "application/json;charset=utf-8"
}).success(function(datareceived){
    if(datareceived.id >= 0 ) { /* the id property has dynamically added on server side via PHP */ }
});

PHP side:

PHP的一面:

$requestString = file_get_contents('php://input');
$myObject = json_decode($requestString); // same object as was sent in the ajax call
$myObject->id = 30; // This will dynamicaly add the id property to the myObject object

OR JUST SEND A DUMMY PROPERTY from javascript that you will fill in PHP.

或者只需要从javascript中发送一个虚拟属性,就可以填充PHP。

#1


72  

If you absolutely have to add the property to the object, I believe you could cast it as an array, add your property (as a new array key), then cast it back as an object. The only time you run into stdClass objects (I believe) is when you cast an array as an object or when you create a new stdClass object from scratch (and of course when you json_decode() something - silly me for forgetting!).

如果您必须向对象添加属性,我相信您可以将其转换为数组,添加属性(作为新的数组键),然后将其转换为对象。唯一一次碰到stdClass对象(我相信)是当您将数组转换为对象时,或者当您从头创建一个新的stdClass对象时(当然,当您json_decode()某件事时——我真傻,忘了!)

Instead of:

而不是:

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

You'd do:

你会做的事:

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

Or if you already had an existing stdClass object:

或者如果您已经有一个现有的stdClass对象:

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

Also as a 1 liner:

同样作为一行:

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

#2


44  

Do it like this:

这样做:

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

now try:

现在试一试:

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

#3


11  

If you want to edit the decoded JSON, try getting it as an associative array instead of an array of objects.

如果希望编辑解码后的JSON,请尝试将其作为关联数组而不是对象数组。

$data = json_decode($json, TRUE);

#4


1  

you should use magic methods __Set and __get. Simple example:

您应该使用魔法方法__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];
}

}

Of course, don't use this example as this : no security at all :)

当然,不要用这个例子:完全没有安全可言:)

EDIT : seen your comments, here could be an alternative based on reflection and a decorator :

编辑:看到你的评论,这里可以是一个基于反射和装饰者的选择:

 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 : I didn't test my code, just the general idea...

PS:我没有测试我的代码,只是大意……

#5


0  

I don't know whether its the newer version of php, but this works. I'm using php 5.6

我不知道它是否是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();

This is the result. The save method actually gets the new property

这是结果。save方法实际上获取新属性

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

#6


0  

I always use this way:

我总是这么用:

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

echo $foo->bar; //12345

#7


-3  

Yes, is possible to dynamically add properties to a PHP object.

是的,可以动态地向PHP对象添加属性。

This is useful when a partial object is received from javascript.

当从javascript接收部分对象时,这很有用。

JAVASCRIPT side:

JAVASCRIPT的一面:

var myObject = { name = "myName" };
$.ajax({ type: "POST", url: "index.php",
    data: myObject, dataType: "json",
    contentType: "application/json;charset=utf-8"
}).success(function(datareceived){
    if(datareceived.id >= 0 ) { /* the id property has dynamically added on server side via PHP */ }
});

PHP side:

PHP的一面:

$requestString = file_get_contents('php://input');
$myObject = json_decode($requestString); // same object as was sent in the ajax call
$myObject->id = 30; // This will dynamicaly add the id property to the myObject object

OR JUST SEND A DUMMY PROPERTY from javascript that you will fill in PHP.

或者只需要从javascript中发送一个虚拟属性,就可以填充PHP。