如何访问数组/对象?阵 列对象数组和对象不要让PHP恶搞你!

2022-08-30 08:14:49

我有以下数组,当我这样做时,我得到: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];

但这向我展示了:

未定义 0

注意:

我从Facebook SDK 4获得这个数组,所以我不知道原始数组结构。

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


答案 1

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

阵 列

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

echo $array[0];

在较旧的 PHP 版本上,还允许使用其他语法:{}

echo $array{0};

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

定义数组和访问数组元素是两回事。所以不要把它们混为一谈。

要定义数组,您可以使用 或 用于 PHP >=5.4,并分配/设置一个数组/元素。当您访问如上所述的数组元素时,您将获得数组元素的值,而不是设置元素。array()[][]

//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;

对象

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

echo $object->property;

如果另一个对象中有一个对象,则只需使用多个对象即可访问对象属性。->

echo $objectA->objectB->property;

注意:

  1. 此外,如果您有无效的属性名称,则必须小心!因此,要查看所有问题,您可以使用无效的属性名称来看待这个问题/答案。特别是这个,如果你在属性名称的开头有数字。

  2. 您只能从类外部访问具有公共可见性的属性。否则(私有或受保护),您需要一个方法或反射,您可以使用它来获取属性的值。

数组和对象

现在,如果数组和对象相互混合,则只需查看现在是否访问数组元素或对象属性,并为其使用相应的运算符即可。

//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]是一个数组,即使它内部有(嵌套的)对象,$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)

这意味着在第一个维度中,您只有 1 个带有 key() 和 value() 的元素:$keydata$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 个元素,其中包含 keys() 、 和 values():$key012$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个调试函数都输出相同的数据,只是以另一种格式或一些元数据(例如类型,大小)输出。所以在这里,我想展示你如何阅读这些函数的输出,以了解/了解如何从数组/对象访问某些数据。

输入数组:

$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,因为该值的键/索引为 1。[]

2. 接下来我们看到,数组被分配给具有对象 name 属性的属性

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

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

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

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

所以直到现在,我们知道我们必须使用->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. “隐藏”字符

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

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

    Array ( [key] => HERE ) 
    

    然后,您正在尝试通过以下方式访问该元素:

    echo $arr["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. 永远不要信任的输出,或者如果您查看 XMLprint_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
        )
    
    )
    

    因此,如您所见,您看不到标题的属性。因此,正如我所说,永远不要信任的输出,或者当你有一个XML对象时。始终使用 asXML() 查看完整的 XML 文件/字符串。var_dump()print_r()

    因此,只需使用下面显示的方法之一:

    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>
    

有关详细信息,请参阅:

常规(符号、错误)

属性名称问题


答案 2

从问题中我们看不到输入数组的结构。也许.因此,当您询问$demo[0]时,您使用的是未定义的索引。array ('id' => 10499478683521864, 'date' => '07/22/1983')

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

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

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