【问题标题】:php looping through multidimentional array is slowphp循环遍历多维数组很慢
【发布时间】:2015-07-31 18:45:16
【问题描述】:

我正在使用 WooCommerce API 开发一个小型 Web 应用程序。此应用程序需要从 wordpress/woocommerce 中提取订单信息。

我能够很好地提取其中一些信息,但在其他方面遇到问题(这完全是另一个问题。)

woocommerce REST api 中的数据以多维数组的形式返回。

这是一个单一订单的例子:

    array (size=2)
  'order' => 
    array (size=30)
      'id' => int 22
      'order_number' => int 22
      'created_at' => string '2015-07-30T14:01:54Z' (length=20)
      'updated_at' => string '2015-07-30T14:01:54Z' (length=20)
      'completed_at' => string '2015-07-30T13:01:54Z' (length=20)
      'status' => string 'on-hold' (length=7)
      'currency' => string 'GBP' (length=3)
      'total' => string '3.84' (length=4)
      'subtotal' => string '3.84' (length=4)
      'total_line_items_quantity' => int 2
      'total_tax' => string '0.00' (length=4)
      'total_shipping' => string '0.00' (length=4)
      'cart_tax' => string '0.00' (length=4)
      'shipping_tax' => string '0.00' (length=4)
      'total_discount' => string '0.00' (length=4)
      'shipping_methods' => string '' (length=0)
      'payment_details' => 
        array (size=3)
          'method_id' => string 'bacs' (length=4)
          'method_title' => string 'Direct Bank Transfer' (length=20)
          'paid' => boolean false
      'billing_address' => 
        array (size=11)
          'first_name' => string 'Chris' (length=5)
          'last_name' => string '#' (length=5)
          'company' => string '' (length=0)
          'address_1' => string '#' (length=4)
          'address_2' => string '' (length=0)
          'city' => string '#' (length=7)
          'state' => string '' (length=0)
          'postcode' => string '#' (length=7)
          'country' => string 'GB' (length=2)
          'email' => string '#' (length=20)
          'phone' => string '#' (length=11)
      'shipping_address' => 
        array (size=9)
          'first_name' => string 'Chris' (length=5)
          'last_name' => string '#' (length=5)
          'company' => string '' (length=0)
          'address_1' => string '#' (length=4)
          'address_2' => string '' (length=0)
          'city' => string '#' (length=7)
          'state' => string '' (length=0)
          'postcode' => string '#' (length=7)
          'country' => string 'GB' (length=2)
      'note' => string '' (length=0)
      'customer_ip' => string '#' (length=15)
      'customer_user_agent' => string 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H143 Safari/600.1.4' (length=134)
      'customer_id' => int 1
      'view_order_url' => string '#' (length=58)
      'line_items' => 
        array (size=2)
          0 => 
            array (size=12)
              ...
          1 => 
            array (size=12)
              ...
      'shipping_lines' => 
        array (size=0)
          empty
      'tax_lines' => 
        array (size=0)
          empty
      'fee_lines' => 
        array (size=0)
          empty
      'coupon_lines' => 
        array (size=0)
          empty
      'customer' => 
        array (size=14)
          'id' => int 1
          'created_at' => string '2015-07-29T16:12:13Z' (length=20)
          'email' => string '#' (length=20)
          'first_name' => string '' (length=0)
          'last_name' => string '' (length=0)
          'username' => string '#' (length=6)
          'role' => string '#' (length=13)
          'last_order_id' => string '26' (length=2)
          'last_order_date' => string '2015-07-30T22:22:42Z' (length=20)
          'orders_count' => int 5
          'total_spent' => string '7.96' (length=4)
          'avatar_url' => string '#' (length=34)
          'billing_address' => 
            array (size=11)
              ...
          'shipping_address' => 
            array (size=9)
              ...
  'http' => 
    array (size=2)
      'request' => 
        array (size=7)
          'headers' => 
            array (size=3)
              ...
          'method' => string 'GET' (length=3)
          'url' => string '#' (length=290)
          'params' => 
            array (size=5)
              ...
          'data' => 
            array (size=0)
              ...
          'body' => null
          'duration' => float 5.01302
      'response' => 
        array (size=3)
          'body' => string '{"order":{"id":22,"order_number":22,"created_at":"2015-07-30T14:01:54Z","updated_at":"2015-07-30T14:01:54Z","completed_at":"2015-07-30T13:01:54Z","status":"on-hold","currency":"GBP","total":"3.84","subtotal":"3.84","total_line_items_quantity":2,"total_tax":"0.00","total_shipping":"0.00","cart_tax":"0.00","shipping_tax":"0.00","total_discount":"0.00","shipping_methods":"","payment_details":{"method_id":"bacs","method_title":"Direct Bank Transfer","paid":false},"billing_address":{"first_name":"Chris","last_na'... (length=2349)
          'code' => int 200
          'headers' => 
            array (size=5)
              ...

出于安全原因,我刚刚删除了带有哈希的任何地方的数据。

所以我需要遍历所有订单以输出特定信息。通过使用此循环,我可以轻松访问主“订单”数组中的字符串:

$orders = $connect->orders->get(22);

            foreach( $orders as $order ) {
              foreach( $order as $value ) {


                    echo $value["order_number"];
                    $value["total"];

              }
            }

这个循环在几秒钟内运行并输出数据。

但是,当我从主订单数组中的“line_items”数组中输出数据时:

1) 如果不指定订单 ID,我似乎无法做到这一点,否则我会得到一个未定义的索引:订单和为每个循环的订单项提供的无效参数。

为了克服我已将此行添加到主循环以从“line_items”数组中获取数据:

$line_items = $connect->orders->get($value["order_number"]);

                        $line_items = $orders['order']['line_items'];

然后我对此运行 foreach 以输出“line_items 数组”中的值

foreach($line_items as $item) {
                echo $item['name'];
                echo $item['quantity']';

             }

这样可以,但是以这种方式输出“line_items”会使页面加载速度非常慢。循环 6 个订单大约需要 40 秒。

如果没有这一行:

$line_items = $connect->orders->get($value["order_number"]);

页面在大约 5 秒内呈现。

我的问题是:这是访问“line_items”数组的最佳方式吗?

以下是输出订单信息的完整代码,包括订单项。

$orders = $connect->orders->get(22);

            foreach( $orders as $order ) {
              foreach( $order as $value ) {


                    echo $value["order_number"];
                    $value["total"];

                    //get line items based on current order id - this is the slow bit!
                    $line_items = $connect->orders->get($value["order_number"]);
                    $line_items = $orders['order']['line_items'];

                    //loop through line items
                    foreach($line_items as $item) {
                        echo $item['name'];
                        echo $item['quantity']';

                     }

              }
            }

【问题讨论】:

  • 页面输出了多少数据? 2K 还是 40M 字节?
  • 这听起来真的很愚蠢。如何准确地告诉您输出了多少数据?
  • 一种方法是查看网页的源代码(Mozilla 系列浏览器中的 ctrl-U),将其复制并粘贴到编辑器中,然后保存并查看文件大小。
  • 页面大小为 18KB。是的,get 方法正在调用来自 wordpress 站点的订单列表。它来自 woocommerce rest api:woothemes.github.io/woocommerce-rest-api-docs/…

标签: php arrays wordpress loops


【解决方案1】:

问题是您的顶级数组有两个元素httporder,而http 部分中没有order_number

所以基本上你在做

echo $array['order']['order_number']; // works
echo $array['http']['order_number'];  // doesn't work.

你可能想要一个单循环:

foreach($orders['order'] as $order)
   echo $order['order_number'];
}

【讨论】:

  • 据我了解,我的循环应该如下所示: [code] $orders = $connect->orders->get(); foreach( $orders['order'] as $order ) { } [code] 那么问题是我得到一个未定义的索引顺序错误,除非我在 get 方法中指定一个订单号
  • 然后做一个var_dump($orders) 看看你真正得到了什么。
  • 返回与我的问题中完全相同的数组。如果我没有在 get 方法中指定订单号,那么调用数组就像 $orders['order'] 返回未定义的索引错误
猜你喜欢
  • 2012-04-21
  • 2011-01-02
  • 2016-02-16
  • 2021-09-17
  • 1970-01-01
  • 2010-10-24
相关资源
最近更新 更多