복붙노트

정수와 같은 이름을 가진 객체 속성에 액세스하는 방법?

PHP

정수와 같은 이름을 가진 객체 속성에 액세스하는 방법?

출력이 다음과 같은 PHP Associative 배열 요소에 접근하는 방법 :

[highlighting] => stdClass Object
        (
            [448364] => stdClass Object
                (
                    [Data] => Array
                        (
                            [0] => Tax amount liability is ....... 

키 [0]의 문자열 값에 액세스하려고합니다. 나는 다음과 같이하고 싶다.

print myVar->highlighting->448364->Data->0

그러나 두 숫자 / 정수 거기에 문제가있는 것 같습니다.

편집하다:

나는 여기에서 약간의 역사를 제공 할 것이다. 여기에서 myVar는 어디에서 얻을 수 있는가? json_decode () 같은 것을 사용하고 있습니다 :

$myVar = json_decode(url)

해결법

  1. ==============================

    1.

    PHP 7.2에서는 객체와 배열 캐스트의 숫자 키 변환에 대한 동작 변경이 도입되었습니다.이 특정 불일치가 수정되어 다음 예제가 모두 예상대로 동작합니다.

    한 가지 더 혼란스러워하는 일!

    PHP는 여러분이 정말로 자신을 발견하고 싶지 않은 어두운 골목길을 가지고 있습니다. 이름이 숫자 인 객체 속성은 그 중 하나입니다.

    사실 1 : 합법적 인 변수 이름이 아닌 속성을 쉽게 액세스 할 수 없습니다.

    $a = array('123' => '123', '123foo' => '123foo');
    $o = (object)$a;
    echo $o->123foo; // error
    

    사실 2 : 중괄호 구문을 사용하여 이러한 속성에 액세스 할 수 있습니다.

    $a = array('123' => '123', '123foo' => '123foo');
    $o = (object)$a;
    echo $o->{'123foo'}; // OK!
    

    사실 # 3 : 그러나 속성 이름이 모두 자릿수 인 경우!

    $a = array('123' => '123', '123foo' => '123foo');
    $o = (object)$a;
    echo $o->{'123foo'}; // OK!
    echo $o->{'123'}; // error!
    

    실례 예.

    사실 # 4 : 객체가 처음부터 배열에서 오지 않았다면 그렇지 않습니다.

    $a = array('123' => '123');
    $o1 = (object)$a;
    $o2 = new stdClass;
    $o2->{'123'} = '123'; // setting property is OK
    
    echo $o1->{'123'}; // error!
    echo $o2->{'123'}; // works... WTF?
    

    실례 예.

    꽤 직관적인데 동의하지 않니?

    옵션 # 1 : 수동으로 수행하십시오.

    가장 실용적인 접근법은 관심있는 객체를 배열로 캐스팅하여 속성에 액세스 할 수 있도록하는 것입니다.

    $a = array('123' => '123', '123foo' => '123foo');
    $o = (object)$a;
    $a = (array)$o;
    echo $o->{'123'}; // error!
    echo $a['123']; // OK!
    

    불행하게도 이것은 재귀 적으로 작동하지 않습니다. 따라서 귀하의 경우에는 다음과 같이해야합니다.

    $highlighting = (array)$myVar->highlighting;
    $data = (array)$highlighting['448364']->Data;
    $value = $data['0']; // at last!
    

    옵션 # 2 : 핵 옵션

    다른 방법은 객체를 재귀 적으로 배열로 변환하는 함수를 작성하는 것입니다.

    function recursive_cast_to_array($o) {
        $a = (array)$o;
        foreach ($a as &$value) {
            if (is_object($value)) {
                $value = recursive_cast_to_array($value);
            }
        }
    
        return $a;
    }
    
    $arr = recursive_cast_to_array($myVar);
    $value = $arr['highlighting']['448364']['Data']['0'];
    

    그러나, 이것이 당신이 관심있는 것이 아닌 속성의 모든 배열에 불필요하게 캐스팅 할 것이기 때문에 이것이 전체적으로 더 나은 옵션이라고 확신하지는 않습니다.

    옵션 # 3 : 영리한 플레이

    이전 옵션의 대안은 내장 된 JSON 함수를 사용하는 것입니다.

    $arr = json_decode(json_encode($myVar), true);
    $value = $arr['highlighting']['448364']['Data']['0'];
    

    JSON 함수는 외부 함수를 정의 할 필요없이 배열에 대한 재귀 적 변환을 유용하게 수행합니다. 그러나이 옵션은 바람직하지만 옵션 # 2의 "핵"단점을 가지고 있으며 객체 내부에 문자열이있는 경우 해당 문자열을 UTF-8로 인코딩해야한다는 단점이 있습니다 (json_encode의 요구 사항).

  2. ==============================

    2.

    Jon의 웅변적인 설명에 실패한 이유를 추가하고 싶었습니다. 배열을 만들 때 php는 키를 정수로 변환하기 때문에 숫자 키가 보존되어 있기 때문에 객체에 캐스트 된 배열에서 조회 문제를 발생시킵니다. 이는 모든 속성 액세스 옵션이 문자열을 예상하거나 변환하기 때문에 문제가됩니다. 다음을 수행하여이를 확인할 수 있습니다.

    $arr = array('123' => 'abc');
    $obj = (object) $arr;
    $obj->{'123'} = 'abc';
    print_r( $obj );
    

    어떤 출력 :

    stdClass Object ( 
      [123] => 'abc', 
      [123] => 'abc'
    )
    

    그래서 객체에는 두 개의 속성 키, 하나의 숫자 (액세스 할 수 없음) 및 하나의 문자열 기반이 있습니다. Jon의 #Fact 4가 작동하는 이유는 중괄호를 사용하여 속성을 설정하면 숫자가 아닌 문자열 기반 키를 항상 정의하기 때문입니다.

    Jon의 솔루션을 사용하면서 머리를 돌리면 배열에서 항상 다음을 수행하여 문자열 기반 키가있는 객체를 생성 할 수 있습니다.

    $obj = json_decode(json_encode($arr));
    

    지금부터는 다음 방법 중 하나를 사용할 수 있습니다.이 방식으로 액세스하면 항상 중괄호 안의 값이 문자열로 변환되기 때문입니다.

    $obj->{123};
    $obj->{'123'};
    

    좋은 오래된 비논리적 인 PHP ...

  3. ==============================

    3.

    나는 그물에서이 기능을 복사했다. 그것이 ( "stdClass 객체를 다차원 배열로 변환하는 기능"이라고) 작동하면 다음을 시도하십시오.

    <?php
    
        function objectToArray($d) {
            if (is_object($d)) {
                // Gets the properties of the given object
                // with get_object_vars function
                $d = get_object_vars($d);
            }
    
            if (is_array($d)) {
                /*
                * Return array converted to object
                * Using __FUNCTION__ (Magic constant)
                * for recursive call
                */
                return array_map(__FUNCTION__, $d);
            }
            else {
                // Return array
                return $d;
            }
        }
    
    ?>
    

    출처 : stdClass를 배열과 배열로 stdClass로 stdClass

  4. ==============================

    4.

    Jon의 포괄적 인 대답에 대한 최종 대안 :

    true로 설정된 두 번째 매개 변수로 json_decode ()를 사용하기 만하면됩니다.

    $array = json_decode($url, true);
    

    이렇게하면 객체가 아닌 연관 배열이 반환되므로 사실을 변환 할 필요가 없습니다.

    이것은 모든 애플리케이션에 적합하지 않을 수 있지만 오르간 객체의 속성을 쉽게 참조하는 데 정말로 도움이되었습니다.

    이 튜토리얼에서 해결책을 찾았습니다 - http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/

    문안 인사

  5. ==============================

    5.

    숫자로 시작하는 객체의 이름을 지정하는 것이 허용되지 않습니다. 편지로 시작하는 첫 번째 단어 "448364"의 이름을 변경하십시오.

    두 번째 배열은 배열이며, 대괄호로 액세스 할 수 있습니다.

    print myVar->highlighting->test_448364->Data[0]
    

    대신에

  6. ==============================

    6.

    객체가 @ like로 시작하면 :

    SimpleXMLElement Object (
        [@attributes] => Array (
            [href] => qwertyuiop.html
            [id] => html21
            [media-type] => application/xhtml+xml
        )
    )
    

    당신은 사용해야합니다 :

    print_r($parent_object->attributes());
    

    왜냐하면 $ parent_object -> { '@ attributes'} 또는 $ parent_object [ '@ attributes']가 작동하지 않기 때문입니다.

  7. from https://stackoverflow.com/questions/10333016/how-to-access-object-properties-with-names-like-integers by cc-by-sa and MIT lisence