php pthreads 获取货运号代码实例

来源:互联网 发布:手机优先网络列表设置 编辑:程序博客网 时间:2024/04/29 09:48

首先安装php pthreads

安装参看:http://blog.csdn.net/terry_water/article/details/50252611

安装完成后就可以使用多线程了

1. 多线程方法,继承\Thread ,构造方法中new好下面要使用的对象,run方法写好要执行的代码。

<?php/*  根据国家和订单金额,选择货运公司,此功能是通过console跑的脚本*/namespace myapp\code\core\Erp\Sales\helper;use Yii; use myapp\code\core\Erp\Sales\helper\Shippingpthreads;use myapp\code\core\Erp\Sales\helper\shipping_pthreads\Bilishi;use myapp\code\core\Erp\Sales\helper\shipping_pthreads\DHL;use myapp\code\core\Erp\Sales\helper\shipping_pthreads\Eyoubao;use myapp\code\core\Erp\Sales\helper\shipping_pthreads\SahprShip;use myapp\code\core\Erp\Sales\helper\shipping_pthreads\Sf;use common\models\core\CSFAU;use backend\models\core\XML2Array;use backend\models\core\Array2XML;class TrackOrderPthreads extends \Thread   {public $order;  public $data;public $Shippingpthreads;public $bilishi;public $dhl;public $eyoubao;public $SahprShip;public $sf;public $csfau;public $XML2Array;public $Array2XML;  public function __construct($order)  {  # 下面程序使用的对象,必须在构造方法中实例化,不可以在调用的对象中new对象,会报错$this->order = $order;  $this->Shippingpthreads = new Shippingpthreads; $this->bilishi = new bilishi; $this->dhl = new DHL; $this->eyoubao = new Eyoubao; $this->SahprShip = new SahprShip; $this->sf = new Sf; $this->csfau = new CSFAU; $this->XML2Array = new XML2Array; $this->Array2XML = new Array2XML; }    public function run()  {  if(($order = $this->order)){   #初始化对象$bilishi = $this->bilishi;$dhl = $this->dhl ;$eyoubao = $this->eyoubao; $SahprShip = $this->SahprShip; $sf = $this->sf;$Shippingpthreads = $this->Shippingpthreads;$csfau = $this->csfau;$XML2Array = $this->XML2Array;$Array2XML = $this->Array2XML;$BilishiAccount = 'sns:dfdost';$shipping_company = $order['shipping_company'];if($shipping_company == $Shippingpthreads::SF_PINGYOU_A2){# 在sf对象中使用的所有对象,必须在本类的构造方法new好,并传递过去,不能再$sf这个对象中进行new# 对于静态方法,只有new之后才能使用,不可以使用没有new的类静态方法$this->data = $result = $sf->getSfShippingNoByOrder($order,'A2',$csfau,$Shippingpthreads,$XML2Array);}else if($shipping_company == $Shippingpthreads::SF_GUOJI_A1){$this->data = $result = $sf->getSfShippingNoByOrder($order,'A1',$csfau,$Shippingpthreads,$XML2Array);}else if($shipping_company == $Shippingpthreads::SF_PINGYOU_A6){$this->data = $result = $sf->getSfShippingNoByOrder($order,'A6',$csfau,$Shippingpthreads,$XML2Array);}else if($shipping_company == $Shippingpthreads::DHL){$this->data = $result = $dhl->getDHLShippingNoByOrder($order,$Shippingpthreads);}else if($shipping_company == $Shippingpthreads::PX_EMS_C1){# wish 需要把onfancy 改成wish#$order['shipping_company'] = $Shippingpthreads::PX_EMS_C1;//$this->data = $result = $SahprShip->getSahprTrackNum($order,"onfancy",$Shippingpthreads);}else if($shipping_company == $Shippingpthreads::PX_XJP_B1){#$order['shipping_company'] = $Shippingpthreads::PX_XJP_B1;$this->data = $result = $SahprShip->getSahprTrackNum($order,"onfancy",$Shippingpthreads);# 判断是否是比利时}else if($shipping_company == $Shippingpthreads::BILISHI){$this->data = $bilishi->getBilishiShippingNoByOrder($order,$BilishiAccount,$Shippingpthreads);}else if($shipping_company == $Shippingpthreads::E_YOUBAO){$this->data = $result = $eyoubao->getEyoubaoShippingNoByOrder($order,$Shippingpthreads,$XML2Array,$Array2XML);}}  }  }

3. 对象sf的文件代码:(其他货运方式,不展示了):

<?php/*顺丰产品重量使用的是product weight 75行总重量用的 self::ORDER_WEIGHT 97行价格用的是产品的价格 74行*/namespace myapp\code\core\Erp\Sales\helper\shipping_pthreads;use Yii; use backend\block\Blockbase;use backend\models\core\XML2Array;use myapp\code\core\Erp\Sales\models\Salesorderitem;use myapp\code\core\Erp\Sales\helper\Shipping;use common\models\core\CSFAU;class Sf{const CHECK_PASS = '503FD8BD72BEFF';const HEAD = '7552';const ORDER_WEIGHT= 0.8;const PRODUCT_NO= 1111;//const EXPRESS_TYPE= 'A1';const ORDER_EXITST_SF_CODE = '9002';public $XML2Array;public function __construct(){}# 1.根据订单返回货运号,先通过生成订单号方式,如果返回# 返回的值: ["status"]=> string(2) "OK" #["orderid"]=> string(9) "800055829" #["mailno"]=> string(12) "994018593449" #["agent_mailno"]=> string(13) "RS281099136NL" #["method"]=> string(18) "OrderSearchService"    # public  function getSfShippingNoByOrder($order,$shipping_type,$csfau,$Shippingpthreads,$XML2Array){$this->XML2Array = $XML2Array;$csArr = false;if($shipping_type == "A6"){$zip = $order['customer_address_zip'];$csArr = $csfau::getCityStateByZip($zip);}$xmlArray = $this->generalSfGetXmlByOrder($order,$shipping_type,$csArr,$Shippingpthreads);$searchxmlArray = $this->searchSfGetXmlByOrder($order,$shipping_type);$result = $this->getSfShippingNo($xmlArray,$searchxmlArray);if(isset($result['agent_mailno'])){return ['ack' =>  'success','trackingNumber'=>$result['agent_mailno'] ? $result['agent_mailno'] : $result['mailno'],'orderNo'=>$result['orderid'],'mailno' =>  $result['mailno'],];}else{return ['ack' => 'fail','content'=> $result['code'],];}}# 2.1根据订单生成获取订单号的api xml(soap)-这个传递的xml为生成订单号的xml requestpublic  function generalSfGetXmlByOrder($order,$shipping_type,$csArr,$shipping){$increment_id = $order['increment_id'];$now_city = '';$now_state = '';if($csArr){$now_city = $csArr['city'];$now_state = $csArr['state'];}$items = $order['items'];$Cargo = [];$items_count = $order['items_count'];$sigle_price = $shipping::getSingleProductBasePriceByOrderCount($items_count);if(is_array($items) && !empty($items)){foreach($items as $item){$Cargo[] = ['@attributes' => ['hscode'=>$this::PRODUCT_NO, //$item['sku'],'ename'=> 'clothing',  //substr($item['name'],0,48),'count'=>(int)$item['qty'],'amount'=> $sigle_price, 'weight'=>$item['weight'] ? $item['weight'] : 0.1,],];}}$xmlArray = array('@attributes' => array('service' => 'OrderService','lang' => 'zh-CN'),'Head' => $this::HEAD,'Body' => ["Order" => ['@attributes' => ['orderid' => $increment_id,'express_type'=> $shipping_type,'d_contact'=>$order['customer_firstname'].' '.$order['customer_lastname'],'d_mobile'=>$order['customer_telephone'] ,'d_address'=>$order['customer_address_street1'].' '.$order['customer_address_street2'],'parcel_quantity'=>$order['items_count'],'d_country'=>$order['customer_address_country'],'d_province'=>$now_state ? $now_state : $order['customer_address_state'],'d_city'=>$now_city ? $now_city : $order['customer_address_city'],'d_post_code'=>$order['customer_address_zip'],'j_country ' => 'CN','j_province ' => 'guangdong','j_city ' => 'shenzhen','j_address ' => 'shenzhen','j_company' => 'Grandbing Tech','j_contact  ' => 'Boxing chen','j_post_code  ' => '518131','j_tel ' => '15818680093','cargo_total_weight'=>$this::ORDER_WEIGHT,'returnsign'=>'Y', 'operate_flag'=>1   # 新增并确认订单//'d_email'=>$order['customer_email'],],'Cargo' =>$Cargo,]]);return $xmlArray;}# 2.2如果订单号存在,获取订单号失败后,需要通过查询的方式获取订单号public  function searchSfGetXmlByOrder($order,$shipping_type){$increment_id = $order['increment_id'];$xmlArray = array('@attributes' => array('service' => 'OrderSearchService','lang' => 'zh-CN'),'Head' => $this::HEAD,'Body' => array("OrderSearch" => array('@attributes' => array('orderid' => $increment_id,))));return $xmlArray ;}# 3.通过xml request 获取返回数据public  function getSfShippingNo($xmlArray,$searchxmlArray,$checkword=''){$result = $this->EncryptionData($xmlArray,$checkword);$reponseStatus = $result['Response']['Head'];//如果返回的结果成功,那么通过返回的数据,获取货运号等一些信息if(strtolower($reponseStatus) === 'ok'){$data = $this->getSfGeneralShippingNo($result);return $data;}else if(strtolower($reponseStatus) === 'err'){$error = $result['Response']['ERROR'];$code = $error['@attributes']['code'];$codeArr = explode(",",$code);foreach($codeArr as $ce){$ce = trim($ce);if($ce == $this::ORDER_EXITST_SF_CODE){return $this->OrderSearch($searchxmlArray,$checkword);}}return ['status'=>'error','code' =>$code,];}}public  function base64($str){ // base64转码return base64_encode($str);}public  function _md5($str){ // md5加密并转大写return strtoupper(md5($str));}#4.1 查询订单的方式返回的xml数据,解析出来想要的数据。public  function OrderSearch($searchxmlArray,$checkword=''){$result = $this->EncryptionData($searchxmlArray,$checkword);$reponseStatus = $result['Response']['Head'];$body = $result['Response']['Body'];$attributes = $body["OrderSearchResponse"]["@attributes"];$orderId = $attributes["orderid"];$mailno = $attributes["mailno"];$agent_mailno =$attributes["coservehawbcode"];$oscode = $attributes["oscode"];$destcode = $attributes["destcode"];return ['status'=>$reponseStatus,'orderid' =>$orderId,'mailno' => $mailno,'agent_mailno'=>$agent_mailno,'method'=>'OrderSearchService','oscode'=>$oscode,'destcode'=>$destcode,];}#4.1 生成订单的方式返回的xml数据,解析出来想要的数据。public  function getSfGeneralShippingNo($result){$reponseStatus = $result['Response']['Head'];$body = $result['Response']['Body'];$attributes = $body["OrderResponse"]["@attributes"];$orderId = $attributes["orderid"];$mailno = $attributes["mailno"];$agent_mailno =$attributes["agent_mailno"];return ['status'=>$reponseStatus,'orderid' =>$orderId,'mailno' => $mailno,'agent_mailno'=>$agent_mailno,'method'=>'OrderService',];}/** * 加密方法 * @param $xml XML字符串 * @param $checkword 密钥 */ public  function EncryptionData($xmlArray,$checkword=''){if(!$checkword){$checkword = $this::CHECK_PASS;}$xml = $this->array2xml($xmlArray,"Request");$md5Data = $this->_md5($xml.$checkword); $verifyCode = $this->base64($md5Data);$result = $this->callWebServer($xml,$verifyCode); // 调用webserver$XML2Array = $this->XML2Array;$array = $XML2Array::createArray($result); return $array;}/** * 调用webserver * @param $xml XML字符串 * @param $verifyCode 加密后的字符串 * 返回xml格式 */ public  function callWebServer($xml,$verifyCode){ $client = new \SoapClient("http://www.sfb2c.com:8003/CBTA/ws/sfexpressService?wsdl");$result = $client->__soapCall('sfexpressService', array("xml" => $xml, "verifyCode"=> $verifyCode));return  $result; //返回xml格式}public  function array2xml($var, $type = 'root', $tag = '') {$ret = '';if (!is_int($type)) {if ($tag)   return $this->array2xml(array($tag => $var), 0, $type); else {   $tag .= $type;   $type = 0;}}$level = $type;$indent = str_repeat("\t", $level);if (!is_array($var)) {$ret .= $indent . '<' . $tag;$var = strval($var);if ($var == '') {$ret .= ' />';} else if (!preg_match('/[^0-9a-zA-Z@\._:\/-]/', $var)) {$ret .= '>' . $var . '</' . $tag . '>';} else {$ret .= "><![CDATA[{$var}]]></{$tag}>";}$ret .= "\n";} else if (!(is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) && !empty($var)) {  foreach ($var as $tmp)   $ret .= $this->array2xml($tmp, $level, $tag);} else {$ret .= $indent . '<' . $tag;if ($level == 0)$ret .= '';if (isset($var['@attributes'])) {foreach ($var['@attributes'] as $k => $v) {if (!is_array($v)) {$ret .= sprintf(' %s="%s"', $k, $v);}}unset($var['@attributes']);}$ret .= ">\n";foreach ($var as $key => $val) {$ret .= $this->array2xml($val, $level + 1, $key);}$ret .= "{$indent}</{$tag}>\n";}return $ret;}}

这个方法只是个sf获取货运号的对象类,里面的逻辑可以大致看看结构。

3. 开始多线程操作,注意,上面我们搞了一个多线程的执行类,我们需要通过调用的方式让他执行:

<?php/*  根据国家和订单金额,选择货运公司,此功能是通过console跑的脚本*/namespace myapp\code\core\Erp\Sales\helper;use Yii; use backend\block\Blockbase;use backend\models\core\Date;use myapp\code\core\Erp\Sales\helper\Orderstatus;use myapp\code\core\Erp\Sales\models\Salesorderitem;use myapp\code\core\Erp\Sales\models\Salesorder;use myapp\code\core\Erp\Sales\helper\shipping\DHL;use myapp\code\core\Erp\Sales\helper\shipping\Sf;use myapp\code\core\Erp\Sales\helper\shipping\PXdsf;use myapp\code\core\Erp\Sales\helper\shipping\Bilishi;use myapp\code\core\Erp\Sales\helper\shipping\Eyoubao;use myapp\code\core\XPublic\Shipping\TrackingNo;class Shippingpthreads{# 顺丰平邮const SF_PINGYOU_A2 = "SF_PINGYOU_A2";# 顺丰国际 const SF_GUOJI_A1 = "SF_GUOJI_A1";# 顺丰澳洲a6const SF_PINGYOU_A6 = "SF_PINGYOU_A6";# DHLconst DHL = "DHL";# ****************XXXXX---->4PX 中国邮政EMS# 已经更改为夏普 中国邮政EMSconst PX_EMS_C1 = "4PX_EMS_C1";# ****************XXXXX---->4PX 新加坡邮政# 已经更改为夏普 新加坡邮政const PX_XJP_B1 = "4PX_XJP_B1";# 比利时邮政const BILISHI = "BILISHI";# E邮宝const E_YOUBAO = "E_YOUBAO";public static function getShippingCompanyArray(){return [self::SF_PINGYOU_A2 => '顺丰平邮-A2',self::SF_GUOJI_A1 => '顺丰国际-A1',self::SF_PINGYOU_A6=> '顺丰平邮-A6',self::DHL => 'DHL',self::PX_EMS_C1 => '4PX-中国邮政EMS',self::PX_XJP_B1 => '4PX-新加坡邮政',self::BILISHI => '比利时邮政',self::E_YOUBAO => 'E邮宝',];}# 得到货运追踪号失败的最大次数。const GET_TRACKING_NUMBER_MAX_FAIL_COUNT = 5;# 开始货运号追踪,并更新public static function getOrdersTrackNumber(){$orders = self::getOrders();#$orders = self::getDOrders();//var_dump($orders);exit;$thread_array = [];//var_dump($orders);exit;echo "Get TrackNumber By Pthreads begin ...\n";# 多线程获取订单货运号   Pthreadsforeach($orders as $order){$increment_id = $order['increment_id'];$thread_array[$increment_id] = new TrackOrderPthreads($order);$thread_array[$increment_id]->start();}$track_arr = [];foreach($thread_array as $increment_id=>$thread_ob){while($thread_array[$increment_id]->isRunning()){#失败的沉睡3秒。sleep(3);$thread_array[$increment_id]->kill();break;}if($thread_array[$increment_id]->join()){$track_arr[] = $thread_array[$increment_id]->data;}}echo "Get TrackNumber By Pthreads end ...\n";foreach($track_arr as $track){if($track){var_dump($track);echo "\n";$content = $track['content'];$tracking_number = $track['trackingNumber'];$mailno = $track['mailno'];$orderNo = $track['orderNo'];$content = $track['content'];$ack = $track['ack'];//echo  $orderNo.'-'.$tracking_number."<br/>";//$tracking_number_status = $track['tracking_number_status'];# 重新获取$order = Salesorder::find()->where(['increment_id'=>$orderNo])->one();if( $ack == 'success' && $order && $tracking_number){if($order->erp_global_status == Orderstatus::ORDER_GLOBAL_STATUS_GET_FREIGHT_COMPLETE){//echo "##";$increment_id = $order['increment_id'];$one_order = Salesorder::find()->where(" increment_id != '".$increment_id."' and  tracking_number = '".$tracking_number."' ")->one();# 如果这个货运号,在其他订单中存在,则这个货运号不允许被保存。if($one_order['increment_id']){echo "tracking_number is alreay exit\n";$order->get_tracking_number_status = 2;$order->get_tracking_number_return_code = 'tracking_number is alreay exit,can not save to this order';$order->get_tracking_number_datetime= Date::getCurrentDateTime();$order->erp_global_status = Orderstatus::ORDER_GLOBAL_STATUS_GET_FREIGHT_COMPLETE;//$order->erp_order_get_freight_company_datetime= date::getCurrentDateTime();$order->get_tracking_number_fail_count= $order->get_tracking_number_fail_count + 1;$order->save();}else{echo "save ".$increment_id." success \n";$order->tracking_number = $tracking_number;$order->mail_no= $mailno;$order->get_tracking_number_status = 1;$order->get_tracking_number_return_code = $content;$order->get_tracking_number_datetime= Date::getCurrentDateTime();//$order->erp_order_get_freight_company_datetime= date::getCurrentDateTime();$order->erp_global_status = Orderstatus::ORDER_GLOBAL_STATUS_GET_CARGO_NO_COMPLETE;$order->save();}}}else if($order){echo "Get Track Number Ack : Fail \n";if($order->erp_global_status == Orderstatus::ORDER_GLOBAL_STATUS_GET_FREIGHT_COMPLETE){$order->tracking_number = $tracking_number;$order->get_tracking_number_status = 2;$order->get_tracking_number_return_code = $content;$order->get_tracking_number_datetime= Date::getCurrentDateTime();$order->erp_global_status = Orderstatus::ORDER_GLOBAL_STATUS_GET_FREIGHT_COMPLETE;//$order->erp_order_get_freight_company_datetime= date::getCurrentDateTime();$order->get_tracking_number_fail_count= $order->get_tracking_number_fail_count + 1;$order->save();}}}else{echo "Return Null \n";}}}public static function getDOrders(){$order1 = Salesorder::find()->asArray()->where(['increment_id'=>'INTOSMILEES000000678'])->one();$order2 = Salesorder::find()->asArray()->where(['increment_id'=>'55c2c0d275e08241edaef6af'])->one();$increment_ids = ['SBxxxx10000000101','SBxxxx10000000102','SBxxxx10000000103','SBxxxx10000000104','SBxxxx10000000105','SBxxxx10000000106','SBxxxx10000000107','SBxxxx10000000108',];$order1 = self::getTrackOrder($order1);$order2 = self::getTrackOrder($order2);$re_order = [];foreach($increment_ids  as $increment_id){$order1['increment_id'] = $increment_id;$re_order[] = $order1;}$re_order[0]['shipping_company'] = 'SF_PINGYOU_A2';$re_order[1]['shipping_company'] = 'SF_GUOJI_A1';$re_order[2]['shipping_company'] = 'SF_PINGYOU_A6';$re_order[3]['shipping_company'] = '4PX_EMS_C1';$re_order[4]['shipping_company'] = '4PX_XJP_B1';$re_order[5]['shipping_company'] = 'DHL';$re_order[6]['shipping_company'] = 'BILISHI';$order2['shipping_company']  = 'E_YOUBAO';$order2['increment_id']  = 'SBxxxx10000000109';$re_order[] = $order2;return $re_order;}/*const SF_PINGYOU_A2 = "SF_PINGYOU_A2";# 顺丰国际 const SF_GUOJI_A1 = "SF_GUOJI_A1";# 顺丰澳洲a6const SF_PINGYOU_A6 = "SF_PINGYOU_A6";# DHLconst DHL = "DHL";# ****************XXXXX---->4PX 中国邮政EMS# 已经更改为夏普 中国邮政EMSconst PX_EMS_C1 = "4PX_EMS_C1";# ****************XXXXX---->4PX 新加坡邮政# 已经更改为夏普 新加坡邮政const PX_XJP_B1 = "4PX_XJP_B1";# 比利时邮政const BILISHI = "BILISHI";# E邮宝const E_YOUBAO = "E_YOUBAO";*/# 得到要处理的订单。public static function getOrders(){$condition = Orderstatus::ORDER_GLOBAL_STATUS_GET_FREIGHT_COMPLETE;$where = " erp_global_status= ".$condition." AND get_tracking_number_fail_count  < ".Shipping::GET_TRACKING_NUMBER_MAX_FAIL_COUNT." AND get_tracking_number_status <> 1";$orders_model = Salesorder::find()->asArray()->where($where)->limit(500);$orders = $orders_model->all();$track_orders = [];foreach($orders  as $order){$order = self::getTrackOrder($order);//$order = self::getTrackingInfo($order);if($order['increment_id']){$track_orders[] = $order;}}return $track_orders;/*$count = $orders_model->count();echo "where:".$where.'\n';echo "count:".$count.'\n';foreach($orders as $order){echo "process:".$order['increment_id']." begin..\n";$noworder = Salesorder::find()->where(['increment_id'=>$order['increment_id']])->andWhere($where)->one();if($noworder['increment_id']){Shipping::settrackingnumber($noworder);}echo "process:".$order['increment_id']." end..\n";}*/}



0 0
原创粉丝点击