PHP> = 5.3 엄격 모드에서 오류를 생성하지 않고 객체에 속성을 추가하는 방법


82

간단해야하는데 답을 찾을 수없는 것 같습니다 ....

$foo속성이없는 일반 stdClass 개체 가 있습니다. $bar아직 정의되지 않은 새 속성을 추가하고 싶습니다 . 이렇게하면 :

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

엄격 모드의 PHP가 불평합니다.

이미 인스턴스화 된 객체에 속성을 추가하는 적절한 방법 (클래스 선언 외부)은 무엇입니까?

참고 : 솔루션이 stdClass 유형의 일반 PHP 개체와 함께 작동하기를 원합니다.

이 문제에 대한 약간의 배경. json 객체의 배열 인 json 문자열을 디코딩하고 있습니다. json_decode()StdClass 객체의 배열을 생성합니다. 이러한 개체를 조작하고 각 개체에 속성을 추가해야합니다.


통과 시도 TRUE에 두번째 매개 변수로 json_decode. 객체 배열 대신 연관 배열을 제공합니다.
Rocket Hazmat 2012

1
엄격 모드의 PHP는 그것에 대해 불평하지 않습니다. 3v4l.org/kn0hi
hakre 2013

3
이것이 완벽하게 유효한 질문이기 때문에 이것이 왜 닫혔는지 모르겠습니다. 지금 바로 비슷한 질문이 있습니다.
Steven

답변:


131

객체에 속성을 절대적으로 추가해야하는 경우에는이를 배열로 캐스팅하고 속성을 새 배열 키로 추가 한 다음 다시 객체로 캐스팅 할 수 있다고 생각합니다. 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' ) );

1
StdClass를 만나는 한 곳은 json을 디코딩 할 때입니다.
Ray

1
@Ray 나는 그것을 언급 할 생각이 없었던 슬픔에 머리를 흔들고 있습니다. =)
Crontab 2012

3
귀하의 솔루션은 작동하지만 내 OO 마음이 아파요 :) 어떤 유형의 화려한 반사 kung foo 또는 무언가를 바라고있었습니다 ... 질문을 조금 더 열어두고 약간 알려진 PHP 마술을 기대합니다.
Ray

1
@Ray hehehe ... 나는 당신을 위해 더 우아한 것을 원했습니다. 덧붙여서 명시 적으로 error_reporting(E_STRICT);on 으로 설정 PHP 5.3.15-1~dotdeb.0 with Suhosin-Patch하면 stdClass 객체에 존재하지 않는 속성을 설정하려고 할 때 오류나 알림이 표시되지 않습니다. 어떤 버전의 PHP를 사용하고 있습니까?
Crontab

하, 거의 3 년 후 나는 어떤 이유에서인지 설명없이 드라이브 바이 다운 투표를 받았다. 감사합니다.
Crontab

112

다음과 같이하십시오.

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

이제 시도해보십시오.

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

2
매력으로 작동합니다. 이것이 허용되는 솔루션이어야합니다.
Tarrakis

이 구문을 사용하여 객체의 필드에 속성을 어떻게 추가합니까?
Big Money

Laravel 오류 '가 아닌 객체의 할당 속성에 시도'
Rejaul

"bar"문자열도 변수에 포함될 수 있습니다. $ foo-> {$ any_variable} = '1234';
Salar

이것은 객체 참조를 그대로 유지하므로 (제 경우에는 중요했습니다) 확실히 받아 들여지는 대답이어야합니다.
Johan Fredrik Varen

11

디코딩 된 JSON을 편집하려면 객체 배열 대신 연관 배열로 가져 오십시오.

$data = json_decode($json, TRUE);

2

나는 항상 이런 식으로 사용합니다.

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

echo $foo->bar; //12345

1

매직 메서드 __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...');
    }
}
 }
}

추신 : 나는 내 코드를 테스트하지 않았고 일반적인 아이디어 만 ...


3
Benjamin, PHP의 일반 객체 클래스 인 StdClass를 사용하고 싶습니다. 이 클래스를 수정할 수 없습니다.
Ray

레이는, 나는 해결책이 당신의 필요에 대응 내 대답을 업데이트,하지만 무거운 : - /
벤자민 뒤부아

1

최신 버전의 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
    )

PHP 버전에서 코드에 대해 여러 테스트를 실행했으며 결과는 PHP 5 이상에서만 작동한다는 것을 보여줍니다. php5 이하의 모든 버전은 오류를 발생시킵니다.
Big Tree

-6

예, PHP 객체에 속성을 동적으로 추가 할 수 있습니다.

이것은 자바 스크립트에서 부분 객체를받을 때 유용합니다.

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 측 :

$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

또는 PHP로 채울 자바 스크립트에서 DUMMY 속성을 보내십시오.


JS에서 더미 속성을 보내고 PHP 측에서 채우는 것이 가장 쉬운 스마트 솔루션이라고 생각합니다. 감사!
Adrian P.

8
O_O O_O O_O O_O
theflowersoftime
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.