2015-04-17 15 views
13

Gần đây tôi đã gặp sự cố trong đó các cuộc gọi SOAP đến dịch vụ ID3Global/địa chỉ đột nhiên ngừng hoạt động (trước đây họ đã làm việc tốt). Tôi tin rằng nó có một cái gì đó để làm với các nhà cung cấp lưu trữ tắt allow_url_fopen trên máy chủ của chúng tôi mà bây giờ có nghĩa là dịch vụ không hoạt động.Làm thế nào để hoán đổi các cuộc gọi SOAP sang cURL, để làm việc trong giới hạn allow_url_fopen?

Tôi đã được thông báo rằng tôi cần phải chuyển sang sử dụng cURL để lấy tệp (WSDL) là file_get_contents yêu cầu 'allow_url_fopen' được đặt trong tệp php.ini để làm việc này. Tuy nhiên tôi dường như không sử dụng file_get_contents trong tệp của tôi để lấy tệp WSDL.

Tôi làm cách nào để chuyển sang sử dụng cURL?

Dưới đây là file PHP của tôi thực hiện cuộc gọi địa chỉ SOAP:

<?php 
ini_set("soap.wsdl_cache_enabled", "0"); 

$username = '[email protected]'; 
$password = 'xxxxxxx'; 

$profile_id = 'xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx'; 

// Live WSDL 
$wsdl = 'https://id3global.com/ID3gWS/ID3global.svc?wsdl'; 

$postcode = $_POST['ZipPostcode']; 

/** 
* Method to arrange the address into a sane 
* order for displaying back to the user 
* 
* @param $item 
* @param $key 
* @internal param $address 
*/ 
function sortAddress(&$item, $key) 
{ 
    // Convert the object to an array 
    $address = (array) $item; 

    // Reorder the address lines 
    $addressLines = array(
     'Company' => $address['Company'], 
     'Building' => $address['Building'], 
     'SubBuilding' => $address['SubBuilding'], 
     'Premise' => $address['Premise'], 
     'SubStreet' => $address['SubStreet'], 
     'Street' => $address['Street'], 
     'City' => $address['City'], 
     'StateDistrict' => $address['StateDistrict'], 
     'ZipPostcode' => $address['ZipPostcode'], 
     'Country' => $address['Country'], 
    ); 

    // Remove blank address lines 
    // $item = array_filter($addressLines); 
    $item = $addressLines; 

} 

class clsWSSEAuth { 
    private $Username; 
    private $Password; 
    function __construct($username, $password) { 
     $this->Username=$username; 
     $this->Password=$password; 
    } 
} 

class clsWSSEToken { 
    private $UsernameToken; 
    function __construct ($UsernameToken){ 
     $this->UsernameToken = $UsernameToken; 
    } 
} 

$strWSSENS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; 

//Auth 
$objSoapVarUser = new SoapVar($username, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS); 
$objSoapVarPass = new SoapVar($password, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS); 
$objWSSEAuth = new clsWSSEAuth($objSoapVarUser, $objSoapVarPass); 

//Token 
$objSoapVarWSSEToken = new SoapVar($objWSSEAuth, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS); 
$objWSSEToken = new clsWSSEToken($objSoapVarWSSEToken); 

//Header 
$objSoapVarWSSEAuth = new SoapVar($objWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS); 
$objSoapVarHeaderVal = new SoapVar($objSoapVarWSSEAuth, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'Security', $strWSSENS); 
$objSoapVarWSSEHeader = new SoapHeader($strWSSENS, 'Security', $objSoapVarHeaderVal, true); 

//Client 
$client = new SoapClient($wsdl, array(
    'soap_version' => SOAP_1_1, 
    'trace' => 1, 
    'exception' => true, 
)); 

$client->__setSoapHeaders($objSoapVarWSSEHeader); 

$results = $client->AddressLookup(array(
    'InputData' => array('ZipPostcode' => strtoupper($postcode)), 
)); 

$addresses = $results->AddressLookupResult->GlobalAddress; 


array_walk($addresses, 'sortAddress'); 
//var_dump($addresses); 

echo json_encode($addresses); 

này được kích hoạt sử dụng AJAX và đây là tệp JavaScript/jQuery:

jQuery(document).ready(function($) { 

    var addresses = []; 

    $("body").on('click', '.find-address', function(e){ 
     e.preventDefault(); 
     url = '/wp-content/themes/Cornhill/gbgroup-address-lookup_2.php'; 
     postode_id = $(this).data('postcode'); 
     address_id = $(this).data('address'); 
     postcode = $('#'+postode_id).val(); 
     console.log('Stage 1'); 

     if (postcode != '') 
     { 
      var addressList = $('#'+address_id); 
      addressList.find('option').remove(); 
      opt = $('<option>').html('Loading...'); 
      opt.val(''); 
      addressList.append(opt); 
      console.log('stage 2'); 

      $.ajax({ 
       url: url, 
       dataType: 'json', 
       type: 'post', 
       data: { 
        'ZipPostcode': postcode 
       }, 
       success: function(response){ 
        addressList.find('option').remove(); 
        addresses[address_id] = response; 

        opt = $('<option>').html('Please select'); 
        opt.val(''); 
        addressList.append(opt); 

        for(x=0; x<addresses[address_id].length; x++){ 

         addressArray = new Array(); 
         addressArray.push(addresses[address_id][x].Building); 
         addressArray.push(addresses[address_id][x].Street); 
         addressArray.push(addresses[address_id][x].City); 
         addressArray.push(addresses[address_id][x].ZipPostcode); 

         addressString = addressArray.join(', '); 

         opt = $('<option>').attr('value', x); 
         opt.html(addressString); 

         addressList.append(opt); 
        } 
       } 
      }); 
     } 
     else 
     { 
      return; 
     } 
    }); 

    $("body").on('change', '.select-address', function(){ 
     address_id = $(this).attr('id'); 
     street_id = $(this).data('street'); 
     town_id = $(this).data('town'); 
     postcode_id = $(this).data('postcode'); 

     value = $(this).val(); 
     if(value != ''){ 
      address = addresses[address_id][value]; 

      if (address.Building != '') 
      { 
       $('#'+street_id).val(address.Building+' '+address.Street); 
      } 
      else 
      { 
       $('#'+street_id).val(address.Street); 
      } 
      $('#'+town_id).val(address.City); 
      $('#'+postcode_id).val(address.ZipPostcode); 
     } 

    }); 

}); 

trước đây tôi đã cố gắng chuyển đổi bằng cách sử dụng sau đây mã để lấy tệp WSDL nhưng không thực sự chắc chắn những gì khác tôi phải làm với nó:

$ch = curl_init('https://id3global.com/ID3gWS/ID3global.svc?wsdl'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
$resultSuper = curl_exec($ch); 
+0

Nếu máy chủ lưu trữ của bạn thực hiện những thay đổi đáng kể mà không đưa ra cảnh báo trước và cho phép bạn thử nghiệm trên các máy chủ mới, tôi sẽ xem xét thay đổi máy chủ là ưu tiên quan trọng. – halfer

+0

Cảm ơn, chúng tôi đang tìm kiếm để thay đổi khá sớm nhưng trong thời gian có nghĩa là chúng ta cần phải làm cho dịch vụ này hoạt động trở lại.Bạn có bất cứ gợi ý nào về cách sử dụng cURL trong tập tin gbgroup-address-lookup_2.php đó không? –

+0

(Tôi đã chuyển mã của bạn vào câu hỏi của bạn - chúng tôi có xu hướng không khuyến khích các bảng chữ cái bên ngoài ở đây, vì các liên kết đôi khi bị hỏng và chúng tôi thích các câu hỏi cuối cùng). – halfer

Trả lời

3

Tham số allow_url_fopen không ảnh hưởng đến cách SOAP hoạt động. Bạn có thể dễ dàng kiểm tra điều này với các kịch bản sau đây:

<?php 

echo "allow_url_fopen status is: " . ini_get('allow_url_fopen') . "\n"; 

$wsdl = 'https://id3global.com/ID3gWS/ID3global.svc?wsdl'; 

file_get_contents($wsdl); 

$client = new SoapClient($wsdl, array(
    'soap_version' => SOAP_1_1, 
    'trace' => 1, 
    'cache_wsdl' => WSDL_CACHE_NONE, // this is important for the purpose of the test 
    'exception' => true, 
)); 

print_r($client); 

?> 

Khi allow_url_fopen được kích hoạt, bạn sẽ thấy những kết quả sau:

allow_url_fopen status is: 1 SoapClient Object ([trace] => 1 [_soap_version] => 1 [sdl] => Resource id #11) 

Khi allow_url_fopen bị vô hiệu hóa, bạn sẽ thấy kết quả như sau:

allow_url_fopen status is: 0 
Warning: file_get_contents(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /var/www/test.php on line 9 

Warning: file_get_contents(https://id3global.com/ID3gWS/ID3global.svc?wsdl): failed to open stream: no suitable wrapper could be found in /var/www/test.php on line 9 
SoapClient Object ([trace] => 1 [_soap_version] => 1 [sdl] => Resource id #10) 

Lưu ý rằng không có lỗi SOAP nào được báo cáo.

Lý do cho hành vi này là đoạn mã sau vào tập tin ext/soap/php_xml.c trong mã nguồn của PHP:

old_allow_url_fopen = PG(allow_url_fopen); 
PG(allow_url_fopen) = 1; 
ctxt = xmlCreateFileParserCtxt(filename); 
PG(allow_url_fopen) = old_allow_url_fopen; 

Vì vậy, allow_url_fopen được kích hoạt cho việc tải xuống WSDL. Nếu bạn nhận xét các dòng như sau:

/* old_allow_url_fopen = PG(allow_url_fopen); 
PG(allow_url_fopen) = 1; */ 
ctxt = xmlCreateFileParserCtxt(filename); 
/* PG(allow_url_fopen) = old_allow_url_fopen; */ 

Và biên dịch PHP với nguồn thay đổi, bạn sẽ thấy kết quả như sau:

Enabled allow_url_fopen:

allow_url_fopen status is: 1 SoapClient Object ([trace] => 1 [_soap_version] => 1 [sdl] => Resource id #11) 

allow_url_fopen Disabled:

allow_url_fopen status is: 0 
Warning: file_get_contents(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /var/www/test.php on line 9 

Warning: file_get_contents(https://id3global.com/ID3gWS/ID3global.svc?wsdl): failed to open stream: no suitable wrapper could be found in /var/www/test.php on line 9 

Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://id3global.com/ID3gWS/ID3global.svc?wsdl' : failed to load external entity "https://id3global.com/ID3gWS/ID3global.svc?wsdl" in /var/www/test.php:16 Stack trace: #0 /var/www/test.php(16): SoapClient->SoapClient('https://id3glob...', Array) #1 {main} thrown in /var/www/test.php on line 16 

Bạn có thể thấy rằng lần này chúng tôi có lỗi SOAP gây tử vong và WSDL không thể ot được nạp. Tôi quan sát hành vi này với PHP 5.4.40 và PHP 5.6.8.

Các vấn đề liên quan