SimpleXMLIterator性能PHP

SimpleXMLIterator性能PHP,php,performance,simplexml,Php,Performance,Simplexml,我有以下三个与AmazonAPI交互的函数。当我使用parse_orders_result函数时,似乎需要大约30秒才能完成。我通过运行get_orders函数发现了这一点,并注释掉了parse_orders结果,它在3秒内完成了do while循环的每个迭代。然而,当我运行解析程序时,需要花费我在下面提到的30秒。如何提高此操作的性能 获取订单功能: public function get_orders($date) { $this->throttle =

我有以下三个与AmazonAPI交互的函数。当我使用parse_orders_result函数时,似乎需要大约30秒才能完成。我通过运行get_orders函数发现了这一点,并注释掉了parse_orders结果,它在3秒内完成了do while循环的每个迭代。然而,当我运行解析程序时,需要花费我在下面提到的30秒。如何提高此操作的性能

获取订单功能:

public function get_orders($date)
        {
        $this->throttle = amazon_throttle::list_orders_throttle();
        $this->endpoint = "mws.amazonservices.com";
        $this->url = "https://mws.amazonservices.com/Orders/$date";
        $this->action = "ListOrders";
        $this->version = '2011-01-01';
        $this->api = "/Orders/$date\n"; 
        $this->options = array( 
                                'Action' => 'ListOrders',
                                'OrderStatus.Status.1'=>'Unshipped',
                                'OrderStatus.Status.2'=>'PartiallyShipped', 
                                'OrderStatus.Status.3'=>'Shipped',
                                'OrderStatus.Status.4'=>'Canceled',//Get all unshipped, partially shipped, shipped, and canceled orders. This will update these types of orders if their status changes on Amazon
                                'LastUpdatedAfter'=> date("c", strtotime('-1 Month')) //FIXME update this to reflect our download interval later
                               );
        $this->create_signature();
        try 
            {       
            $results = $this->send_request(); //commented out for testing
            }
        catch (Exception $e)
            {
             echo $e->getMessage();
             return false;
            } 

        //$results = sql::value("SELECT api_response from dhs.dbo.api_response where id = 444");
        $xml = new SimpleXMLIterator($results); //make the iterator here so we can check for a nexttoken
        $orders = $this->parse_orders_result($xml->ListOrdersResult->Orders);
        if ($xml->ListOrdersResult->NextToken)
            {
            $next_token = (string)$xml->ListOrdersResult->NextToken;
            do 
                {
                $results = $this->get_orders_next_token($next_token);
                $xml = new SimpleXMLIterator($results);
                $returned = $this->parse_orders_result($xml->ListOrdersByNextTokenResult->Orders);
                $orders = array_merge($orders, $returned);
                if ($xml->ListOrdersByNextTokenResult->NextToken)
                    $next_token = (string) $xml->ListOrdersByNextTokenResult->NextToken;
                else
                    $next_token = null;
                }
            while($next_token);
            }
        //this stored procedure creates patient_ids for each order (if the patient doesn't already exist) and updates the orders table with with their patient_id
        sql::query('EXEC dhs.dbo.sp_create_patients');
        return $orders;
        }
$xml->registerXPathNamespace('amz', 'https://mws.amazonservices.com/Orders/2011-01-01');
            $orders = array();

            foreach ($xml->Order as $order)
            {
                $last = null;
                $name = explode(' ', preg_replace('/[^A-z ]/', '', (string) $order->BuyerName)); //remove all special characters
                if (!isset($name[1]) || !$name[1])
                {
                    $attn_last = explode(' ', preg_replace('/[^A-z ]/', '',$order->ShippingAddress->Name)); //remove all special characters
                    $pos = count($attn_last) - 1;
                    $last = $attn_last[$pos];
                }
                $phone = preg_replace('/[^0-9]/', '', (string) $order->ShippingAddress->Phone); //remove everything that is not an int
                $phone = "(" . substr($phone, 0,3) . ")" . substr($phone,3, 3) . "-" . substr($phone, 6); //format phone number

                //order and ship status are both int values tied to information in the db
                $ship_method = array_search(strtoupper((string) $order->ShipmentServiceLevelCategory),
                        sql::two_column_array("SELECT id, description FROM dhs.dbo.shipping_method WHERE site IS NULL or site = 'AMAZON' "));
                $order_status = array_search(strtoupper((string) $order->OrderStatus),
                        sql::two_column_array("SELECT id, description FROM dhs.dbo.order_status WHERE site IS NULL or site = 'AMAZON' "));
                //you have to cast found elements as string or they are returned as SimpleXMLIterator objects and you can't get the value
                $arr = array(
                        'order_code'=> (string) $order->AmazonOrderId,
                        'shipping_method'=>$ship_method,
                        'amount'=> (string) $order->OrderTotal->Amount,
                        'purchased_on' => date('Y-m-d H:i:s', strtotime($order->PurchaseDate)),
                        'market_id' => (string) $order->MarketplaceId[0],
                        'status'=> $order_status,
                        'site'=> 'AMAZON',
                        'last_update' => date('Y-m-d H:i:s'),
                        'employee_id'=>login::$id,
                        'addr1'=> (string) $order->ShippingAddress->AddressLine1,
                        'addr2'=>(string) $order->ShippingAddress->AddressLine2,
                        'city'=>(string) $order->ShippingAddress->City,
                        'state'=>(string) $order->ShippingAddress->StateOrRegion,
                        'zip'=>(string) $order->ShippingAddress->PostalCode,
                        'attention'=>(string) $order->ShippingAddress->Name,
                        'email'=>(string) $order->BuyerEmail,
                        'phone'=>$phone,
                        'first'=>array_shift($name), //remove the 0 element, use array shift so we can glue the rest of the array together for last name
                        'last'=>(implode(' ', $name)) ? implode(' ', $name): $last,
                        'fullname'=>(string) $order->BuyerName,
                        'unshipped_items'=> (string) $order->NumberOfItemsUnshipped
                );
                foreach ($arr as $k => $v)
                    $arr[$k] = strtoupper($v);

                $id = sql::merge('dhs', 'dbo', 'orders', array('order_code', 'site'), $arr, 'id');
                $arr['order_id'] = $id;
                sql::merge('dhs', 'dbo', 'order_shipping', array('order_id'), $arr);

                $orders[] = $arr;
            }
            return $orders;
        }
private function parse_orders_result(SimpleXMLIterator $xml)
        {
            $shipping_methods = sql::two_column_array("SELECT id, description FROM dhs.dbo.shipping_method WHERE site IS NULL or site = 'AMAZON' ");
            $order_statuses = sql::two_column_array("SELECT id, description FROM dhs.dbo.order_status WHERE site IS NULL or site = 'AMAZON' ");
            $xml->registerXPathNamespace('amz', 'https://mws.amazonservices.com/Orders/2011-01-01');
            $orders = array();

            foreach ($xml->Order as $order)
            {
                $last = null;
                $name = explode(' ', preg_replace('/[^A-z ]/', '', (string) $order->BuyerName)); //remove all special characters
                if (!isset($name[1]) || !$name[1])
                {
                    $attn_last = explode(' ', preg_replace('/[^A-z ]/', '',$order->ShippingAddress->Name)); //remove all special characters
                    $pos = count($attn_last) - 1;
                    $last = $attn_last[$pos];
                }
                $phone = preg_replace('/[^0-9]/', '', (string) $order->ShippingAddress->Phone); //remove everything that is not an int
                $phone = "(" . substr($phone, 0,3) . ")" . substr($phone,3, 3) . "-" . substr($phone, 6); //format phone number

                //order and ship status are both int values tied to information in the db
                $ship_method = array_search(strtoupper((string) $order->ShipmentServiceLevelCategory), $shipping_methods);
                $order_status = array_search(strtoupper((string) $order->OrderStatus), $order_statuses);
                //you have to cast found elements as string or they are returned as SimpleXMLIterator objects and you can't get the value
                $arr = array(
                        'order_code'=> (string) $order->AmazonOrderId,
                        'shipping_method'=>$ship_method,
                        'amount'=> (string) $order->OrderTotal->Amount,
                        'purchased_on' => date('Y-m-d H:i:s', strtotime($order->PurchaseDate)),
                        'market_id' => (string) $order->MarketplaceId[0],
                        'status'=> $order_status,
                        'site'=> 'AMAZON',
                        'last_update' => date('Y-m-d H:i:s'),
                        'employee_id'=>login::$id,
                        'addr1'=> (string) $order->ShippingAddress->AddressLine1,
                        'addr2'=>(string) $order->ShippingAddress->AddressLine2,
                        'city'=>(string) $order->ShippingAddress->City,
                        'state'=>(string) $order->ShippingAddress->StateOrRegion,
                        'zip'=>(string) $order->ShippingAddress->PostalCode,
                        'attention'=>(string) $order->ShippingAddress->Name,
                        'email'=>(string) $order->BuyerEmail,
                        'phone'=>$phone,
                        'first'=>array_shift($name), //remove the 0 element, use array shift so we can glue the rest of the array together for last name
                        'last'=>(implode(' ', $name)) ? implode(' ', $name): $last,
                        'fullname'=>(string) $order->BuyerName,
                        'unshipped_items'=> (string) $order->NumberOfItemsUnshipped
                );
                foreach ($arr as $k => $v)
                    $arr[$k] = strtoupper($v);

                $orders[] = $arr;
            }
            sql::bulk_merge('dhs', 'dbo', 'orders', array('order_code', 'site'), $orders, 'id');
            sql::bulk_merge('dhs', 'dbo', 'order_shipping', array('order_code', 'site'), $orders);
            return $orders;
        }
解析\u顺序\u结果函数:

public function get_orders($date)
        {
        $this->throttle = amazon_throttle::list_orders_throttle();
        $this->endpoint = "mws.amazonservices.com";
        $this->url = "https://mws.amazonservices.com/Orders/$date";
        $this->action = "ListOrders";
        $this->version = '2011-01-01';
        $this->api = "/Orders/$date\n"; 
        $this->options = array( 
                                'Action' => 'ListOrders',
                                'OrderStatus.Status.1'=>'Unshipped',
                                'OrderStatus.Status.2'=>'PartiallyShipped', 
                                'OrderStatus.Status.3'=>'Shipped',
                                'OrderStatus.Status.4'=>'Canceled',//Get all unshipped, partially shipped, shipped, and canceled orders. This will update these types of orders if their status changes on Amazon
                                'LastUpdatedAfter'=> date("c", strtotime('-1 Month')) //FIXME update this to reflect our download interval later
                               );
        $this->create_signature();
        try 
            {       
            $results = $this->send_request(); //commented out for testing
            }
        catch (Exception $e)
            {
             echo $e->getMessage();
             return false;
            } 

        //$results = sql::value("SELECT api_response from dhs.dbo.api_response where id = 444");
        $xml = new SimpleXMLIterator($results); //make the iterator here so we can check for a nexttoken
        $orders = $this->parse_orders_result($xml->ListOrdersResult->Orders);
        if ($xml->ListOrdersResult->NextToken)
            {
            $next_token = (string)$xml->ListOrdersResult->NextToken;
            do 
                {
                $results = $this->get_orders_next_token($next_token);
                $xml = new SimpleXMLIterator($results);
                $returned = $this->parse_orders_result($xml->ListOrdersByNextTokenResult->Orders);
                $orders = array_merge($orders, $returned);
                if ($xml->ListOrdersByNextTokenResult->NextToken)
                    $next_token = (string) $xml->ListOrdersByNextTokenResult->NextToken;
                else
                    $next_token = null;
                }
            while($next_token);
            }
        //this stored procedure creates patient_ids for each order (if the patient doesn't already exist) and updates the orders table with with their patient_id
        sql::query('EXEC dhs.dbo.sp_create_patients');
        return $orders;
        }
$xml->registerXPathNamespace('amz', 'https://mws.amazonservices.com/Orders/2011-01-01');
            $orders = array();

            foreach ($xml->Order as $order)
            {
                $last = null;
                $name = explode(' ', preg_replace('/[^A-z ]/', '', (string) $order->BuyerName)); //remove all special characters
                if (!isset($name[1]) || !$name[1])
                {
                    $attn_last = explode(' ', preg_replace('/[^A-z ]/', '',$order->ShippingAddress->Name)); //remove all special characters
                    $pos = count($attn_last) - 1;
                    $last = $attn_last[$pos];
                }
                $phone = preg_replace('/[^0-9]/', '', (string) $order->ShippingAddress->Phone); //remove everything that is not an int
                $phone = "(" . substr($phone, 0,3) . ")" . substr($phone,3, 3) . "-" . substr($phone, 6); //format phone number

                //order and ship status are both int values tied to information in the db
                $ship_method = array_search(strtoupper((string) $order->ShipmentServiceLevelCategory),
                        sql::two_column_array("SELECT id, description FROM dhs.dbo.shipping_method WHERE site IS NULL or site = 'AMAZON' "));
                $order_status = array_search(strtoupper((string) $order->OrderStatus),
                        sql::two_column_array("SELECT id, description FROM dhs.dbo.order_status WHERE site IS NULL or site = 'AMAZON' "));
                //you have to cast found elements as string or they are returned as SimpleXMLIterator objects and you can't get the value
                $arr = array(
                        'order_code'=> (string) $order->AmazonOrderId,
                        'shipping_method'=>$ship_method,
                        'amount'=> (string) $order->OrderTotal->Amount,
                        'purchased_on' => date('Y-m-d H:i:s', strtotime($order->PurchaseDate)),
                        'market_id' => (string) $order->MarketplaceId[0],
                        'status'=> $order_status,
                        'site'=> 'AMAZON',
                        'last_update' => date('Y-m-d H:i:s'),
                        'employee_id'=>login::$id,
                        'addr1'=> (string) $order->ShippingAddress->AddressLine1,
                        'addr2'=>(string) $order->ShippingAddress->AddressLine2,
                        'city'=>(string) $order->ShippingAddress->City,
                        'state'=>(string) $order->ShippingAddress->StateOrRegion,
                        'zip'=>(string) $order->ShippingAddress->PostalCode,
                        'attention'=>(string) $order->ShippingAddress->Name,
                        'email'=>(string) $order->BuyerEmail,
                        'phone'=>$phone,
                        'first'=>array_shift($name), //remove the 0 element, use array shift so we can glue the rest of the array together for last name
                        'last'=>(implode(' ', $name)) ? implode(' ', $name): $last,
                        'fullname'=>(string) $order->BuyerName,
                        'unshipped_items'=> (string) $order->NumberOfItemsUnshipped
                );
                foreach ($arr as $k => $v)
                    $arr[$k] = strtoupper($v);

                $id = sql::merge('dhs', 'dbo', 'orders', array('order_code', 'site'), $arr, 'id');
                $arr['order_id'] = $id;
                sql::merge('dhs', 'dbo', 'order_shipping', array('order_id'), $arr);

                $orders[] = $arr;
            }
            return $orders;
        }
private function parse_orders_result(SimpleXMLIterator $xml)
        {
            $shipping_methods = sql::two_column_array("SELECT id, description FROM dhs.dbo.shipping_method WHERE site IS NULL or site = 'AMAZON' ");
            $order_statuses = sql::two_column_array("SELECT id, description FROM dhs.dbo.order_status WHERE site IS NULL or site = 'AMAZON' ");
            $xml->registerXPathNamespace('amz', 'https://mws.amazonservices.com/Orders/2011-01-01');
            $orders = array();

            foreach ($xml->Order as $order)
            {
                $last = null;
                $name = explode(' ', preg_replace('/[^A-z ]/', '', (string) $order->BuyerName)); //remove all special characters
                if (!isset($name[1]) || !$name[1])
                {
                    $attn_last = explode(' ', preg_replace('/[^A-z ]/', '',$order->ShippingAddress->Name)); //remove all special characters
                    $pos = count($attn_last) - 1;
                    $last = $attn_last[$pos];
                }
                $phone = preg_replace('/[^0-9]/', '', (string) $order->ShippingAddress->Phone); //remove everything that is not an int
                $phone = "(" . substr($phone, 0,3) . ")" . substr($phone,3, 3) . "-" . substr($phone, 6); //format phone number

                //order and ship status are both int values tied to information in the db
                $ship_method = array_search(strtoupper((string) $order->ShipmentServiceLevelCategory), $shipping_methods);
                $order_status = array_search(strtoupper((string) $order->OrderStatus), $order_statuses);
                //you have to cast found elements as string or they are returned as SimpleXMLIterator objects and you can't get the value
                $arr = array(
                        'order_code'=> (string) $order->AmazonOrderId,
                        'shipping_method'=>$ship_method,
                        'amount'=> (string) $order->OrderTotal->Amount,
                        'purchased_on' => date('Y-m-d H:i:s', strtotime($order->PurchaseDate)),
                        'market_id' => (string) $order->MarketplaceId[0],
                        'status'=> $order_status,
                        'site'=> 'AMAZON',
                        'last_update' => date('Y-m-d H:i:s'),
                        'employee_id'=>login::$id,
                        'addr1'=> (string) $order->ShippingAddress->AddressLine1,
                        'addr2'=>(string) $order->ShippingAddress->AddressLine2,
                        'city'=>(string) $order->ShippingAddress->City,
                        'state'=>(string) $order->ShippingAddress->StateOrRegion,
                        'zip'=>(string) $order->ShippingAddress->PostalCode,
                        'attention'=>(string) $order->ShippingAddress->Name,
                        'email'=>(string) $order->BuyerEmail,
                        'phone'=>$phone,
                        'first'=>array_shift($name), //remove the 0 element, use array shift so we can glue the rest of the array together for last name
                        'last'=>(implode(' ', $name)) ? implode(' ', $name): $last,
                        'fullname'=>(string) $order->BuyerName,
                        'unshipped_items'=> (string) $order->NumberOfItemsUnshipped
                );
                foreach ($arr as $k => $v)
                    $arr[$k] = strtoupper($v);

                $orders[] = $arr;
            }
            sql::bulk_merge('dhs', 'dbo', 'orders', array('order_code', 'site'), $orders, 'id');
            sql::bulk_merge('dhs', 'dbo', 'order_shipping', array('order_code', 'site'), $orders);
            return $orders;
        }
更新 不幸的是,我无法安装XDebugger(它是一个公司服务器,我没有权限)。但是,我可以提供更多的见解:

  • $xml->Orders最多为100个订单(因此只有100次迭代),每个订单大约有1000个字符
  • 尽管我们在每次迭代中都会执行多个数据库请求(我将删除这些请求),但在任何时候,最多只有150个用户访问服务器(可能少于70个)
  • 服务器环境:IIS 6、PHP 5.3、MSSQL Server 2008 R2、48GB RAM、16个2.7ghz处理器核(超线程复制32个处理器)

问题肯定与我们针对数据库运行的查询数量有关。我创建了一个新的merge语句,它接受多维数组,并从foreach循环中删除了不必要的查询,并且将执行时间减少到24秒(通过do-while循环进行5次迭代)。以下是修订后的parse orders函数:

public function get_orders($date)
        {
        $this->throttle = amazon_throttle::list_orders_throttle();
        $this->endpoint = "mws.amazonservices.com";
        $this->url = "https://mws.amazonservices.com/Orders/$date";
        $this->action = "ListOrders";
        $this->version = '2011-01-01';
        $this->api = "/Orders/$date\n"; 
        $this->options = array( 
                                'Action' => 'ListOrders',
                                'OrderStatus.Status.1'=>'Unshipped',
                                'OrderStatus.Status.2'=>'PartiallyShipped', 
                                'OrderStatus.Status.3'=>'Shipped',
                                'OrderStatus.Status.4'=>'Canceled',//Get all unshipped, partially shipped, shipped, and canceled orders. This will update these types of orders if their status changes on Amazon
                                'LastUpdatedAfter'=> date("c", strtotime('-1 Month')) //FIXME update this to reflect our download interval later
                               );
        $this->create_signature();
        try 
            {       
            $results = $this->send_request(); //commented out for testing
            }
        catch (Exception $e)
            {
             echo $e->getMessage();
             return false;
            } 

        //$results = sql::value("SELECT api_response from dhs.dbo.api_response where id = 444");
        $xml = new SimpleXMLIterator($results); //make the iterator here so we can check for a nexttoken
        $orders = $this->parse_orders_result($xml->ListOrdersResult->Orders);
        if ($xml->ListOrdersResult->NextToken)
            {
            $next_token = (string)$xml->ListOrdersResult->NextToken;
            do 
                {
                $results = $this->get_orders_next_token($next_token);
                $xml = new SimpleXMLIterator($results);
                $returned = $this->parse_orders_result($xml->ListOrdersByNextTokenResult->Orders);
                $orders = array_merge($orders, $returned);
                if ($xml->ListOrdersByNextTokenResult->NextToken)
                    $next_token = (string) $xml->ListOrdersByNextTokenResult->NextToken;
                else
                    $next_token = null;
                }
            while($next_token);
            }
        //this stored procedure creates patient_ids for each order (if the patient doesn't already exist) and updates the orders table with with their patient_id
        sql::query('EXEC dhs.dbo.sp_create_patients');
        return $orders;
        }
$xml->registerXPathNamespace('amz', 'https://mws.amazonservices.com/Orders/2011-01-01');
            $orders = array();

            foreach ($xml->Order as $order)
            {
                $last = null;
                $name = explode(' ', preg_replace('/[^A-z ]/', '', (string) $order->BuyerName)); //remove all special characters
                if (!isset($name[1]) || !$name[1])
                {
                    $attn_last = explode(' ', preg_replace('/[^A-z ]/', '',$order->ShippingAddress->Name)); //remove all special characters
                    $pos = count($attn_last) - 1;
                    $last = $attn_last[$pos];
                }
                $phone = preg_replace('/[^0-9]/', '', (string) $order->ShippingAddress->Phone); //remove everything that is not an int
                $phone = "(" . substr($phone, 0,3) . ")" . substr($phone,3, 3) . "-" . substr($phone, 6); //format phone number

                //order and ship status are both int values tied to information in the db
                $ship_method = array_search(strtoupper((string) $order->ShipmentServiceLevelCategory),
                        sql::two_column_array("SELECT id, description FROM dhs.dbo.shipping_method WHERE site IS NULL or site = 'AMAZON' "));
                $order_status = array_search(strtoupper((string) $order->OrderStatus),
                        sql::two_column_array("SELECT id, description FROM dhs.dbo.order_status WHERE site IS NULL or site = 'AMAZON' "));
                //you have to cast found elements as string or they are returned as SimpleXMLIterator objects and you can't get the value
                $arr = array(
                        'order_code'=> (string) $order->AmazonOrderId,
                        'shipping_method'=>$ship_method,
                        'amount'=> (string) $order->OrderTotal->Amount,
                        'purchased_on' => date('Y-m-d H:i:s', strtotime($order->PurchaseDate)),
                        'market_id' => (string) $order->MarketplaceId[0],
                        'status'=> $order_status,
                        'site'=> 'AMAZON',
                        'last_update' => date('Y-m-d H:i:s'),
                        'employee_id'=>login::$id,
                        'addr1'=> (string) $order->ShippingAddress->AddressLine1,
                        'addr2'=>(string) $order->ShippingAddress->AddressLine2,
                        'city'=>(string) $order->ShippingAddress->City,
                        'state'=>(string) $order->ShippingAddress->StateOrRegion,
                        'zip'=>(string) $order->ShippingAddress->PostalCode,
                        'attention'=>(string) $order->ShippingAddress->Name,
                        'email'=>(string) $order->BuyerEmail,
                        'phone'=>$phone,
                        'first'=>array_shift($name), //remove the 0 element, use array shift so we can glue the rest of the array together for last name
                        'last'=>(implode(' ', $name)) ? implode(' ', $name): $last,
                        'fullname'=>(string) $order->BuyerName,
                        'unshipped_items'=> (string) $order->NumberOfItemsUnshipped
                );
                foreach ($arr as $k => $v)
                    $arr[$k] = strtoupper($v);

                $id = sql::merge('dhs', 'dbo', 'orders', array('order_code', 'site'), $arr, 'id');
                $arr['order_id'] = $id;
                sql::merge('dhs', 'dbo', 'order_shipping', array('order_id'), $arr);

                $orders[] = $arr;
            }
            return $orders;
        }
private function parse_orders_result(SimpleXMLIterator $xml)
        {
            $shipping_methods = sql::two_column_array("SELECT id, description FROM dhs.dbo.shipping_method WHERE site IS NULL or site = 'AMAZON' ");
            $order_statuses = sql::two_column_array("SELECT id, description FROM dhs.dbo.order_status WHERE site IS NULL or site = 'AMAZON' ");
            $xml->registerXPathNamespace('amz', 'https://mws.amazonservices.com/Orders/2011-01-01');
            $orders = array();

            foreach ($xml->Order as $order)
            {
                $last = null;
                $name = explode(' ', preg_replace('/[^A-z ]/', '', (string) $order->BuyerName)); //remove all special characters
                if (!isset($name[1]) || !$name[1])
                {
                    $attn_last = explode(' ', preg_replace('/[^A-z ]/', '',$order->ShippingAddress->Name)); //remove all special characters
                    $pos = count($attn_last) - 1;
                    $last = $attn_last[$pos];
                }
                $phone = preg_replace('/[^0-9]/', '', (string) $order->ShippingAddress->Phone); //remove everything that is not an int
                $phone = "(" . substr($phone, 0,3) . ")" . substr($phone,3, 3) . "-" . substr($phone, 6); //format phone number

                //order and ship status are both int values tied to information in the db
                $ship_method = array_search(strtoupper((string) $order->ShipmentServiceLevelCategory), $shipping_methods);
                $order_status = array_search(strtoupper((string) $order->OrderStatus), $order_statuses);
                //you have to cast found elements as string or they are returned as SimpleXMLIterator objects and you can't get the value
                $arr = array(
                        'order_code'=> (string) $order->AmazonOrderId,
                        'shipping_method'=>$ship_method,
                        'amount'=> (string) $order->OrderTotal->Amount,
                        'purchased_on' => date('Y-m-d H:i:s', strtotime($order->PurchaseDate)),
                        'market_id' => (string) $order->MarketplaceId[0],
                        'status'=> $order_status,
                        'site'=> 'AMAZON',
                        'last_update' => date('Y-m-d H:i:s'),
                        'employee_id'=>login::$id,
                        'addr1'=> (string) $order->ShippingAddress->AddressLine1,
                        'addr2'=>(string) $order->ShippingAddress->AddressLine2,
                        'city'=>(string) $order->ShippingAddress->City,
                        'state'=>(string) $order->ShippingAddress->StateOrRegion,
                        'zip'=>(string) $order->ShippingAddress->PostalCode,
                        'attention'=>(string) $order->ShippingAddress->Name,
                        'email'=>(string) $order->BuyerEmail,
                        'phone'=>$phone,
                        'first'=>array_shift($name), //remove the 0 element, use array shift so we can glue the rest of the array together for last name
                        'last'=>(implode(' ', $name)) ? implode(' ', $name): $last,
                        'fullname'=>(string) $order->BuyerName,
                        'unshipped_items'=> (string) $order->NumberOfItemsUnshipped
                );
                foreach ($arr as $k => $v)
                    $arr[$k] = strtoupper($v);

                $orders[] = $arr;
            }
            sql::bulk_merge('dhs', 'dbo', 'orders', array('order_code', 'site'), $orders, 'id');
            sql::bulk_merge('dhs', 'dbo', 'order_shipping', array('order_code', 'site'), $orders);
            return $orders;
        }

请度量每行代码,执行频率,每次执行平均花费的时间以及每行代码的总数。然后,请在问题代码中标出30秒的确切时间。您可以使用Xdebug进行分析。30秒是常见的网络超时(另一个通常为10秒)。如果您有30.5秒的时间来编写一段代码,那么其中可能有一个网络功能失败(例如GET或POST),失败需要30秒,处理需要0.5秒。我认为问题可能出在数据库交互中。它在$shipping_方法中选择相同的数据,在每次迭代中选择$order_状态行,尽管这是相对静态的信息,可以在循环之外选择。此外,我还编写了另一个merge语句函数,它接受多维数组中的所有项,并在单个IO操作中一次性合并它们(而不是在每次迭代中执行单个merge语句)。我将在测试这些更新的效率后进行回复。