Проблемы с объектом stdClass

Я изо всех сил пытаюсь проанализировать приведенные ниже данные с помощью PHP. API возвращает его, и я пробовал разные синтаксисы. Как вернуть данные необъектным способом? Или какой синтаксис для вызова данных с использованием stdClass?

Могу ли я преобразовать это в один массив на основе данных или даже в два? Я теряюсь, когда дело доходит до наборов данных на основе объектов.

stdClass Object
(
    [0] => stdClass Object
        (
            [district] => stdClass Object
                (
                    [state] => NY
                    [number] => 29
                )

        )

    [1] => stdClass Object
        (
            [district] => stdClass Object
                (
                    [state] => NY
                    [number] => 26
                )

        )

)

Когда я создаю объект самостоятельно, а затем делаю var_dump, я получаю это:

object(stdClass)#8 (2) {
  [0]=>
  object(stdClass)#4 (1) {
    ["district"]=>
    object(stdClass)#5 (2) {
      ["state"]=>
      string(2) "NY"
      ["number"]=>
      string(2) "29"
    }
  }
  [1]=>
  object(stdClass)#6 (1) {
    ["district"]=>
    object(stdClass)#7 (2) {
      ["state"]=>
      string(2) "NY"
      ["number"]=>
      string(2) "26"
    }
  }
}

person ader    schedule 14.10.2009    source источник
comment
Откуда этот объект?   -  person Ivan Nevostruev    schedule 14.10.2009
comment
Из этого API emmense.com/sunlight-labs-php-library ‹? php include('class.sunlightlabs.php'); $sf = новый район солнечного света; $sf-›api_key = '[ключ API]'; эхо '‹pre›'; print_r($sf-›districtsByZipCode(14485)); эхо '‹/pre›'; ?›   -  person ader    schedule 14.10.2009


Ответы (6)


Они, вероятно, преобразуют массивы в объекты в своем коде ($object = (object) $array). Это имеет то преимущество, что с этого момента он будет передаваться по ссылке (как это делается по умолчанию для объектов), и недостаток, заключающийся в том, что объект совершенно бесполезен (члены не могут начинаться с цифр - см. регулярное выражение в документации PHP), пока вы не вернете его обратно (PHP допускает некоторые очень загадочные вещи):

$array = (array) $bogusObject;
$array[0]->district->state === 'NY';
person soulmerge    schedule 14.10.2009
comment
Ах ха! У меня была аналогичная проблема однажды с кем-то, кто использовал теги XML, такие как ad-text - загрузка его в объект SimpleXML и попытка доступа к $ad->ad-text не сработала. - person ceejayoz; 14.10.2009
comment
На самом деле нет необходимости приводить к массиву... можно также использовать $object-›{0}-›district... - person null; 14.10.2009

Использовать:

$object->{'0'}->district->state

По сути, вы быстро назначаете строку переменной, а затем используете эту переменную в качестве средства доступа к объекту.

$zero = "0";
$object->$zero; /* or */ $object->{$zero};
person null    schedule 14.10.2009

Сейчас я смотрю на их код, и, к сожалению, они не предоставили в своем классе возможность запрашивать данные в виде дерева ассоциативного массива по сравнению с деревом объектов stdClass.

«Проблема» находится в строке 96 в class.sunlightlabs.php.

return json_decode( $data );

У вас есть пара вариантов.

  1. Просто используйте синтаксис stdClass.
  2. Преобразуйте возвращенное дерево stdClass в ассоциативный массив

№1 в действии

// echo the state of the 2nd object in the result
echo $result->{0}->district->state;

№2 в действии

$result = toArray( $result );

function toArray( $data )
{
  if ( is_object( $data ) )
  {
    $data = get_object_vars( $data );
  }
  return is_array($data) ? array_map(__FUNCTION__, $data) : $data;
}

Вы также можете работать с их классом напрямую с помощью некоторого творческого применения шаблонов, но они уже активно используют подклассы, что немного усложняет его, поэтому я бы придерживался одного из этих двух решений.

person Peter Bailey    schedule 14.10.2009
comment
Если вы можете изменить json_decode($data); в json_decode($data, TRUE); Тогда функция вернет массив. - person null; 14.10.2009
comment
спасибо за предложение get_object_vars, которое работает, однако предложение json_decode($data, TRUE) является лучшим решением этой проблемы. Благодарность! - person William Denniss; 23.08.2010

Вы можете перебирать объект следующим образом:

foreach ($obj as $each) {
    echo $each->district->state . ' - ' . $each->district->number . '<br />';
}
person GZipp    schedule 14.10.2009
comment
Это работает, но это не совсем то, что я ищу. Однако, спасибо. - person ader; 14.10.2009
comment
Я рад, что это помогло. Я не пытался точно соответствовать вашим потребностям, а скорее помочь ответить на ваш вопрос, каков синтаксис для вызова данных с использованием stdClass? (а также для демонстрации того, что stdClass является итерируемым). - person GZipp; 14.10.2009

Пользователь «null» предложил это в комментариях, но хочу поместить это здесь, чтобы его не так легко пропустить.

Лучший вариант — передать TRUE вторым параметром в json_decode, т. е. json_decode($data, TRUE), что заставляет возвращать ассоциативные массивы вместо классов. Так что если у вас есть доступ к исходному коду — внесите это изменение.

person William Denniss    schedule 23.08.2010

Это решение от soulmerge отлично сработало для меня:

$array = (array) $bogusObject;
$array[0]->district->state === 'NY';

Большое спасибо!!

person mayavi    schedule 24.07.2010