简体   繁体   English

自定义模块减慢Drupal

[英]custom module slowing drupal

I have worked on a custom shipping module to match my commerce module shipping needs. 我已经开发了一个自定义的运输模块,以满足我的商务模块运输需求。 I have noticed that the module is slowing drupal a lot on a lot the pages even-though I am basically my module should only be hooking to drupal commerce checkout. 我注意到,即使在很多页面上,该模块也使很多Drupal变慢了,尽管我基本上是将我的模块仅挂接到Drupal Commerce Checkout。

Here is my module code: 这是我的模块代码:

function myips_commerce_shipping_method_info() {

  $shipping_methods = array();

  $shipping_methods['IPS'] = array(
    'title' => t('IPS'),
    'description' => t('Quote rates from IPS'),
  );

  return array($shipping_methods);
}  

function myips_commerce_shipping_service_info() {

  $shipping_services = array();
  $shipping_services['myips_shipping_service'] = array( //arbitrary name w/ 'service' in there
      'title' => t('Custom Shipping Service'),  //title for the interface
      'description' => t('Variable rates based on the book origin '),
      'display_title' => t('IPS Shipping'),
      'shipping_method' => 'IPS',
      'price_component' => 'shipping',  //from commerce_shipping
      'callbacks' => array(
      'rate' => 'myips_service_rate_order'),
  );

  return $shipping_services;

}

function myips_service_rate_order($shipping_service, $order) {

    $order_number=$order->order_number;
    $currency_code='USD';
    $shipping_total=getordershipmentvalue($order_number);
    $rates['myips_shipping_service']=array(
    'amount' => commerce_currency_decimal_to_amount($shipping_total, $currency_code),
    'currency_code' =>$currency_code,
    'data' => array(),                                         
    );
    return $rates[$shipping_service['name']];
}

function getcustomershippingcountry($order_id) {

     $order=commerce_order_load($order_id);
     $profile_id=$order->commerce_customer_shipping['und']['0']['profile_id']; 
     $profile=commerce_customer_profile_load($profile_id);
     $country= $profile->commerce_customer_address[LANGUAGE_NONE]['0']['country'];

     return $country;
}

function getordershipmentvalue($order_id) {

    $order=commerce_order_load($order_id);
    $total=0;
    foreach($order->commerce_line_items[LANGUAGE_NONE] as $line) {
        $line_item_id=$line['line_item_id'];
        $total=$total+getitemshipmentvalue($line_item_id);
    }
    return $total;
}

function getitemshipmentvalue($line_item_id){

    $line_item=commerce_line_item_load($line_item_id);
    $line_quantity=$line_item->quantity;
    $order_id= $line_item->order_id;

    $destination= getcustomershippingcountry($order_id);
    $product_id=$line_item->commerce_product[LANGUAGE_NONE]['0']['product_id'];
    $product=commerce_product_load($product_id);
    $product_weight=$product->field_book_weight[LANGUAGE_NONE]['0']['weight'];
    $product_origin=$product->field_book_origin[LANGUAGE_NONE]['0']['value'];
    $line_total=getshippingrates($destination, $product_origin, $product_weight*$line_quantity);
    return $line_total;
}

function calculateshippment($shipping_type, $zone, $product_weight) {

    $query=new EntityFieldQuery();
    $query->entityCondition('entity_type', 'node');
    $query->entityCondition('bundle', $shipping_type);
    $query->fieldCondition('field_up_to_weight', 'value',$product_weight,'>=');
    $query->fieldCondition('field_zone_number', 'value',$zone);
    $query->fieldorderby('field_up_to_weight','value','ASC');
    $query->range(0,1);
    $result=$query->execute();
    if(!empty($result)){
        $nodes=node_load_multiple(array_keys($result['node']));

        foreach($nodes as $node) {
            $price=$node->field_shipment_price[LANGUAGE_NONE][0]['value'];
        }
    }

    return $price;
}


function getdestinationzone($destination, $shipping_type) {

    $query=new EntityFieldQuery();
    $query->entityCondition('entity_type', 'node');
    $query->entityCondition('bundle', 'countries_zones');
    $query->fieldCondition('field_country_abbreviation', 'value',$destination);
    $result=$query->execute();
    if(!empty($result)) {
        $nodes=node_load_multiple(array_keys($result['node']));

        foreach($nodes as $node) {
            if($shipping_type=='out_us_zone_prices') {
                $zone=$node->field_us_zone[LANGUAGE_NONE]['0']['value'];
            }elseif($shipping_type=='mail_zone_prices') {
                $zone=$node->field_mail_zone[LANGUAGE_NONE]['0']['value'];
            }elseif($shipping_type=='dhl_zone_prices') {
                $zone=$node->field_dhl_zone[LANGUAGE_NONE]['0']['value'];
            }
        }
    }

    return $zone;
}

function getshippingrates($destination, $product_origin, $product_weight) {

  if($product_origin=='US') {
    if($destination==$product_origin) {
        $shipping_type='us_zone_prices';  
    }else {
        $shipping_type='out_us_zone_prices';
    }

  /* End of Product Origin US */  
  }elseif($product_origin=='LB'){

    if($destination==$product_origin) {
        $shipping_type='mail_zone_prices';
    }else {
        $shipping_type='dhl_zone_prices';
    }
  }
  $zone=getdestinationzone($destination,$shipping_type);
  return calculateshippment($shipping_type, $zone, $product_weight);

}

Why would my module slowing drupal performance? 为什么我的模块会降低Drupal性能?

I think the main problem of your module is that your database queries are in a foreach-loop (in getordershipmentvalue() ) 我认为您模块的主要问题是数据库查询位于foreach循环中(在getordershipmentvalue()

Ok you maybe can't see it immediately, but if you look behind the getitemshipmentvalue() -call, you can see, that there are many other function calls there. 好的,您也许无法立即看到它,但是如果您查看getitemshipmentvalue() call的背后,您会看到那里还有许多其他函数调用。

And over multiple corners the functions calculateshippment() and getdestinationzone() will be called. 并在多个角落调用了calculateshippment()getdestinationzone()函数。 In these functions there are database-queries. 在这些功能中,有数据库查询。

Thats the reason, why your module is so slow: Because over multiple corners you query the database in a loop. 这就是为什么模块如此缓慢的原因:因为您在多个角落中循环查询数据库。 This is similar to a DOS-Attack on the database-server (A bigger problem with great arrays of "commerce_line_items"). 这类似于数据库服务器上的DOS攻击(较大的“ commerce_line_items”数组问题更大)。

The solution: Think about your code-design. 解决方案:考虑您的代码设计。 Try to put your database-query-code outside of the foreach-loop. 尝试将数据库查询代码放在foreach循环之外。

I would also prefer to cache the data after the first request. 我也希望在第一个请求之后缓存数据。 (For example with variable_set() ) (例如,使用variable_set()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM