2015-04-17 54 views
13

我最近有一個問題,SOAP調用ID3Global /地址服務突然停止工作(他們以前工作正常)。我認爲這與託管服務提供商在我們的服務器上關閉allow_url_fopen有關,現在這意味着該服務不起作用。如何將SOAP調用交換到cURL,以在allow_url_fopen限制內工作?

我被告知我需要切換到使用cURL來抓取文件(WSDL),因爲file_get_contents要求在php.ini文件中設置'allow_url_fopen'以使其工作。不過,我似乎沒有在我的文件中使用file_get_contents來獲取WSDL文件。

如何切換到使用cURL?

這是我的PHP文件使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); 

這是使用AJAX觸發,這裏的的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); 
     } 

    }); 

}); 

我以前嘗試過使用開關以下代碼來獲取WSDL文件,但我不確定我應該怎麼處理它:

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

如果您的主機發生了如此巨大的變化而未提前發出警告並讓您在新服務器上測試,我會考慮將主機更改爲重要優先事項。 – halfer

+0

謝謝,我們期待很快改變,但同時我們需要再次使用此服務。你有沒有關於如何在gbgroup-address-lookup_2.php文件中使用cURL的建議? –

+0

(我已將您的代碼移到您的問題中 - 我們傾向於在此阻止外部粘貼板,因爲鏈接有時會中斷,而我們喜歡持續的問題)。 – halfer

回答

3

參數allow_url_fopen對SOAP的工作方式沒有影響。

<?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); 

?> 

當allow_url_fopen已被激活,你會看到下面的輸出:

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

當了allow_url_fopen被禁用,你將看到以下的輸出:

您可以輕鬆地與以下腳本測試此
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) 

請注意,沒有報告SOAP錯誤。

其原因行爲在文件ext/soap/php_xml.c在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; 

所以,allow_url_fopen選項爲WSDL下載啓用。如果你對此有何評論線路如下:

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

並與改變源代碼編譯PHP,你會看到下面的結果:

啓用了allow_url_fopen:

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

禁用了allow_url_fopen:

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 

你可以看到,這次我們有致命的SOAP錯誤,WSDL cann不被加載。我用PHP 5.4.40和PHP 5.6.8觀察了這種行爲。