如何访问 array/object?

How can I access an array/object?

我有以下数组,当我执行 print_r(array_values($get_user)); 时,我得到:

Array (
          [0] => 10499478683521864
          [1] => 07/22/1983
          [2] => email@saya.com
          [3] => Alan [4] => male
          [5] => Malmsteen
          [6] => https://www.facebook.com  app_scoped_user_id/1049213468352864/
          [7] => stdClass Object (
                   [id] => 102173722491792
                   [name] => Jakarta, Indonesia
          )
          [8] => id_ID
          [9] => El-nino
          [10] => Alan El-nino Malmsteen
          [11] => 7
          [12] => 2015-05-28T04:09:50+0000
          [13] => 1
        ) 

我尝试按如下方式访问数组:

echo $get_user[0];

但这显示我:

undefined 0

注:

我从Facebook SDK 4中得到这个数组,所以我不知道原来的数组结构。

如何从数组中访问值 email@saya.com 作为示例?

要访问一个 arrayobject 你如何使用两个不同的运算符。

Arrays

要访问数组元素,您必须使用 []

echo $array[0];

在旧的 PHP 版本中,还允许使用 {} 的替代语法:

echo $array{0};

声明数组和访问数组元素的区别

定义数组和访问数组元素是两件不同的事情。所以不要混淆它们。

要定义数组,您可以使用 array() 或 for PHP >=5.4 [] 并且您 assign/set 和 array/-element。如上所述,当您使用 [] 访问数组元素时,您将获得与设置元素相对的数组元素的值。

//Declaring an array
$arrayA = array ( /*Some stuff in here*/ );
$arrayB = [ /*Some stuff in here*/ ]; //Only for PHP >=5.4

//Accessing an array element
echo $array[0];

访问数组元素

要访问数组中的特定元素,您可以使用 []{} 中的任何表达式,然后计算出您要访问的键:

$array[(Any expression)]

所以请注意您使用什么表达式作为键以及它如何被 PHP 解释:

echo $array[0];            //The key is an integer; It accesses the 0's element
echo $array["0"];          //The key is a string; It accesses the 0's element
echo $array["string"];     //The key is a string; It accesses the element with the key 'string'
echo $array[CONSTANT];     //The key is a constant and it gets replaced with the corresponding value
echo $array[cOnStAnT];     //The key is also a constant and not a string
echo $array[$anyVariable]  //The key is a variable and it gets replaced with the value which is in '$anyVariable'
echo $array[functionXY()]; //The key will be the return value of the function

访问多维数组

如果彼此之间有多个数组,那么您只需要一个多维数组。要访问子数组中的数组元素,您只需使用多个 [].

echo $array["firstSubArray"]["SecondSubArray"]["ElementFromTheSecondSubArray"]
         // ├─────────────┘  ├──────────────┘  ├────────────────────────────┘
         // │                │                 └── 3rd Array dimension;
         // │                └──────────────────── 2d  Array dimension;
         // └───────────────────────────────────── 1st Array dimension;

Objects

要访问对象 属性,您必须使用 ->

echo $object->property;

如果您在另一个对象中有一个对象,您只需使用多个 -> 即可到达您的对象 属性。

echo $objectA->objectB->property;

注:

  1. 此外,如果您的 属性 名称无效,您也必须小心!因此,如果您在 属性 名称的开头有数字,请查看此 question/answer. And especially this one 无效 属性 名称可能遇到的所有问题。

  2. 您只能从 class 外部使用 public visibility 访问属性。否则(私有或受保护)您需要一种方法或反射,您可以使用它来获取 属性.

    的值

数组和对象

现在,如果您将数组和对象混合在一起,则只需查看您现在访问的是数组元素还是对象 属性 并为其使用相应的运算符。

//Object
echo $object->anotherObject->propertyArray["elementOneWithAnObject"]->property;
    //├────┘  ├───────────┘  ├───────────┘ ├──────────────────────┘   ├──────┘
    //│       │              │             │                          └── property ; 
    //│       │              │             └───────────────────────────── array element (object) ; Use -> To access the property 'property'
    //│       │              └─────────────────────────────────────────── array (property) ; Use [] To access the array element 'elementOneWithAnObject'
    //│       └────────────────────────────────────────────────────────── property (object) ; Use -> To access the property 'propertyArray'
    //└────────────────────────────────────────────────────────────────── object ; Use -> To access the property 'anotherObject'


//Array
echo $array["arrayElement"]["anotherElement"]->object->property["element"];
    //├───┘ ├────────────┘  ├──────────────┘   ├────┘  ├──────┘ ├───────┘
    //│     │               │                  │       │        └── array element ; 
    //│     │               │                  │       └─────────── property (array) ; Use [] To access the array element 'element'
    //│     │               │                  └─────────────────── property (object) ; Use -> To access the property 'property'
    //│     │               └────────────────────────────────────── array element (object) ; Use -> To access the property 'object'
    //│     └────────────────────────────────────────────────────── array element (array) ; Use [] To access the array element 'anotherElement'
    //└──────────────────────────────────────────────────────────── array ; Use [] To access the array element 'arrayElement'

我希望这能让您大致了解如何访问彼此嵌套的数组和对象。

注:

  1. 是否调用数组或对象取决于你变量的最外层。所以 [new StdClass] 是一个 array 即使它里面有(嵌套的)对象并且 $object->property = array(); 是一个 对象 即使它内部有(嵌套的)数组。

    如果你不确定你有对象还是数组,就用gettype().

  2. 如果有人使用与您不同的编码风格,请不要让自己感到困惑:

     //Both methods/styles work and access the same data
     echo $object->anotherObject->propertyArray["elementOneWithAnObject"]->property;
     echo $object->
            anotherObject
            ->propertyArray
            ["elementOneWithAnObject"]->
            property;
    
     //Both methods/styles work and access the same data
     echo $array["arrayElement"]["anotherElement"]->object->property["element"];
     echo $array["arrayElement"]
         ["anotherElement"]->
             object
       ->property["element"];
    

数组、对象和循环

如果您不想只访问单个元素,您可以遍历嵌套数组/对象并遍历特定维度的值。

为此,您只需访问要循环的维度,然后就可以循环该维度的所有值。

我们以一个数组为例,但它也可以是一个对象:

Array (
    [data] => Array (
            [0] => stdClass Object (
                    [propertyXY] => 1
                )    
            [1] => stdClass Object (
                    [propertyXY] => 2
                )   
            [2] => stdClass Object (
                    [propertyXY] => 3                   
               )    
        )
)

如果您遍历第一个维度,您将获得第一个维度的所有值:

foreach($array as $key => $value)

意味着在第一个维度中,您只有一个元素具有键 ($key) data 和值 ($value):

Array (  //Key: array
    [0] => stdClass Object (
            [propertyXY] => 1
        )
    [1] => stdClass Object (
            [propertyXY] => 2
        )
    [2] => stdClass Object (
            [propertyXY] => 3
        )
)

如果您遍历第二个维度,您将获得第二个维度的所有值:

foreach($array["data"] as $key => $value)

意味着在第二个维度中,您将有 3 个元素,其中包含键 ($key) 012 和值 ($value):

stdClass Object (  //Key: 0
    [propertyXY] => 1
)
stdClass Object (  //Key: 1
    [propertyXY] => 2
)
stdClass Object (  //Key: 2
    [propertyXY] => 3
)

有了这个,你可以遍历任何你想要的维度,无论它是数组还是对象。

分析var_dump() / print_r() / var_export()输出

所有这 3 个调试函数都输出相同的数据,只是采用另一种格式或带有一些元数据(例如类型、大小)。所以在这里我想展示如何将这些函数的输出读取到 know/get 以及如何从 array/object.

访问某些数据的方式

输入数组:

$array = [
    "key" => (object) [
        "property" => [1,2,3]
    ]
];

var_dump() 输出:

array(1) {
  ["key"]=>
  object(stdClass)#1 (1) {
    ["property"]=>
    array(3) {
      [0]=>
      int(1)
      [1]=>
      int(2)
      [2]=>
      int(3)
    }
  }
}

print_r() 输出:

Array
(
    [key] => stdClass Object
        (
            [property] => Array
                (
                    [0] => 1
                    [1] => 2
                    [2] => 3
                )

        )

)

var_export() 输出:

array (
  'key' => 
  (object) array(
     'property' => 
    array (
      0 => 1,
      1 => 2,
      2 => 3,
    ),
  ),
)

如您所见,所有输出都非常相似。如果您现在想要访问值 2,您可以从您想要访问的值本身开始,然后一直到“左上角”。

1。我们首先看到,值 2 在一个数组中,键为 1

// var_dump()
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)    // <-- value we want to access
  [2]=>
  int(3)
}

// print_r()
Array
(
    [0] => 1
    [1] => 2    // <-- value we want to access
    [2] => 3
)

// var_export()
array (
  0 => 1,
  1 => 2,    // <-- value we want to access
  2 => 3,
)

这意味着我们必须使用 [] 通过 [1] 访问值 2,因为该值具有 key/index 1。

2。接下来我们看到,该数组被分配给一个 属性 对象的名称 属性

// var_dump()
object(stdClass)#1 (1) {
  ["property"]=>
  /* Array here */
}

// print_r()
stdClass Object
(
    [property] => /* Array here */
)

// var_export()
(object) array(
    'property' => 
  /* Array here */
),

这意味着我们必须使用->来访问对象的属性,例如->property.

所以到现在为止,我们知道我们必须使用->property[1].

3。最后我们看到,最外层是一个数组

// var_dump()
array(1) {
  ["key"]=>
  /* Object & Array here */
}

// print_r()
Array
(
    [key] => stdClass Object
        /* Object & Array here */
)

// var_export()
array (
  'key' => 
  /* Object & Array here */
)

我们知道我们必须使用 [] 访问数组元素,我们在这里看到我们必须使用 ["key"] 来访问对象.我们现在可以将所有这些部分放在一起并写成:

echo $array["key"]->property[1];

输出将是:

2

别让 PHP 欺骗你!

有几件事你必须知道,这样你就不会花几个小时来寻找它们。

  1. “隐藏”字符

    有时您的键中有字符,您在浏览器中的第一眼看不到这些字符。然后你问自己,为什么你不能访问该元素。这些字符可以是:制表符 (\t)、换行符 (\n)、空格或 html 标记(例如 </p><b>)等

    例如,如果您查看 print_r() 的输出,您会看到:

    Array ( [key] => HERE ) 
    

    然后您尝试使用以下方式访问元素:

    echo $arr["key"];
    

    但是您收到了通知:

    Notice: Undefined index: key

    这很好地表明一定有一些隐藏字符,因为您无法访问该元素,即使键看起来很正确。

    这里的诀窍是使用 var_dump() + 查看您的源代码! (选择:highlight_string(print_r($variable, TRUE));

    突然间你可能会看到这样的东西:

    array(1) {
        ["</b>
    key"]=>
        string(4) "HERE"
    }
    

    现在您将看到,您的密钥中有一个 html 标记 + 一个换行符,您一开始没有看到它,因为 print_r() 并且浏览器没有'表明了这一点。

    所以现在如果你尝试做:

    echo $arr["</b>\nkey"];
    

    你会得到你想要的输出:

    HERE
    
  2. 如果您查看 XML

    ,请永远不要相信 print_r()var_dump() 的输出

    您可能已将 XML 文件或字符串加载到对象中,例如

    <?xml version="1.0" encoding="UTF-8" ?> 
    <rss> 
        <item> 
            <title attribute="xy" ab="xy">test</title> 
        </item> 
    </rss>
    

    现在,如果您使用 var_dump()print_r(),您将看到:

    SimpleXMLElement Object
    (
        [item] => SimpleXMLElement Object
        (
            [title] => test
        )
    
    )
    

    如您所见,您没有看到 title 的属性。所以正如我所说,当你有一个 XML 对象时,永远不要相信 var_dump()print_r() 的输出。始终使用 asXML() 查看完整 XML file/string.

    所以只需使用下面显示的方法之一:

    echo $xml->asXML();  //And look into the source code
    
    highlight_string($xml->asXML());
    
    header ("Content-Type:text/xml");
    echo $xml->asXML();
    

    然后你会得到输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <rss> 
        <item> 
            <title attribute="xy" ab="xy">test</title> 
        </item> 
    </rss>
    

有关详细信息,请参阅:

一般(符号、错误)

  • Reference — What does this symbol mean in PHP?
  • Reference - What does this error mean in PHP?
  • PHP parse/syntax errors; and how to solve them

属性 名字问题

  • How can I access a property with an invalid name?
  • How to access object properties with names like integers or invalid property names?

从题中看不出输入数组的结构。可能 array ('id' => 10499478683521864, 'date' => '07/22/1983')。所以当你询问 $demo[0] 时你使用 undefind index.

Array_values 丢失了键和 return 数组,其中有许多键使数组成为 array(10499478683521864, '07/22/1983'...)。我们在问题中看到的结果。

因此,您可以通过相同的方式获取数组项的值

echo array_values($get_user)[0]; // 10499478683521864 

如果 print_r($var) 的输出是例如:

    Array ( [demo] => Array ( [0] => 10499478683521864 [1] => 07/22/1983 [2] => email@saya.com ) )

然后$var['demo'][0]

如果 print_r($var) 的输出是例如:

    Array ( [0] => 10499478683521864 [1] => 07/22/1983 [2] => email@saya.com )

然后$var[0]

我编写了一个小函数来访问数组或对象中的属性。我经常使用它,觉得它非常方便

/**
 * Access array or object values easily, with default fallback
 */
if( ! function_exists('element') )
{
  function element( &$array, $key, $default = NULL )
  {
    // Check array first
    if( is_array($array) )
    {
      return isset($array[$key]) ? $array[$key] : $default;
    }

    // Object props
    if( ! is_int($key) && is_object($array) )
    {
      return property_exists($array, $key) ? $array->{$key} : $default;
    }

    // Invalid type
    return NULL;
  }
}
function kPrint($key,$obj){    
return (gettype($obj)=="array"?(array_key_exists($key,$obj)?$obj[$key]:("<font color='red'>NA</font>")):(gettype($obj)=="object"?(property_exists($obj,$key)?$obj->$key:("<font color='red'>NA</font>")):("<font color='red'><font color='green'>:::Exception Start:::</font><br>Invalid Object/Array Passed at kPrint() Function!!<br> At : Variable => ".print_r($obj)."<br>Key => ".$key."<br> At File: <font color='blue'>".debug_backtrace()[0]['file']."</font><br> At Line : ".debug_backtrace()[0]['line']."<br><font color='green'>:::Exception End:::</font></font>")));}

//只要你想从数组或对象中访问项目,就可以调用这个函数。此函数根据键打印 array/object 中的相应值。

在对响应数据调用 array_values() 之前,我将假设您的数据是关联的,它看起来有点像这样:

[
    'id' => 10499478683521864,
    'birthday' => '07/22/1983',
    'email' => 'email@saya.com',
    'first_name' => 'Alan',
    'gender' => 'male',
    'last_name' => 'Malmsteen',
    'link' => 'https://www.facebook.com/app_scoped_user_id/1049213468352864/',
    'location' => (object) [
        'id' => 102173722491792,
        'name' => 'Jakarta, Indonesia'
    ],
    'locale' => 'id_ID',
    'middle_name' => 'El-nino',
    'name' => 'Alan El-nino Malmsteen',
    'timezone' => 7,
    'updated_time' => '2015-05-28T04:09:50+0000',
    'verified' => 1
]

re-indexing 有效载荷的密钥没有任何好处。如果您打算将数据转换为数组,则可以通过使用 json_decode($response, true) 解码 json 字符串来实现,否则 json_decode($response).

如果您尝试将 $response 作为对象传递给 array_values(),您将从 PHP8 生成 Fatal error: Uncaught TypeError: array_values(): Argument #1 ($array) must be of type array, stdClass given.

在上面提供的数据结构中,有一个带有关联键的数组。

  • 要访问特定的第一级元素,您可以使用带引号的字符串键的“方括号”语法。
    • $response['id'] 访问 10499478683521864
    • $response['gender'] 访问 male
    • $response['location'] 访问 (object) ['id' => 102173722491792, 'name' => 'Jakarta, Indonesia']
  • 要访问嵌套在location(第二层)中的数据,需要“箭头语法”,因为数据是一个对象。
    • $response['location']->id 访问 102173722491792
    • $response['location']->name 访问 Jakarta, Indonesia

在您的响应中调用 array_values() 后,该结构是一个索引数组,因此使用方括号和不带引号的整数。

  • $response[0] 访问 10499478683521864
  • $response[4] 访问 male
  • $response[7] 访问 (object) ['id' => 102173722491792, 'name' => 'Jakarta, Indonesia']
  • $response[7]->id 访问 102173722491792
  • $response[7]->name 访问 Jakarta, Indonesia

当您不确定正在使用的数据类型时,请使用 var_export() or var_dump()


如果对象 属性(键)包含非法字符或紧跟尾随的字符与键冲突(参见:1, 2, 3),请将键用引号和大括号括起来(或仅对整数使用大括号)以防止语法损坏。


如果您想遍历数组或对象中的所有元素,foreach() 两者都适用。

代码:(Demo)

foreach ($response as $key1 => $value1) {
    if (is_scalar($value1)) {
        echo "Key1: $key1, Value1: $value1\n";
    } else {
        foreach ($value1 as $key2 => $value2) {
            echo "Key1: $key1, Key2: $key2, Value2: $value2\n";
        }
    }
}

输出:

Key1: id, Value1: 10499478683521864
Key1: birthday, Value1: 07/22/1983
Key1: email, Value1: email@saya.com
Key1: first_name, Value1: Alan
Key1: gender, Value1: male
Key1: last_name, Value1: Malmsteen
Key1: link, Value1: https://www.facebook.com/app_scoped_user_id/1049213468352864/
Key1: location, Key2: id, Value2: 102173722491792
Key1: location, Key2: name, Value2: Jakarta, Indonesia
Key1: locale, Value1: id_ID
Key1: middle_name, Value1: El-nino
Key1: name, Value1: Alan El-nino Malmsteen
Key1: timezone, Value1: 7
Key1: updated_time, Value1: 2015-05-28T04:09:50+0000
Key1: verified, Value1: 1