KDJ
KDJ

Reputation: 292

php issues returning an array from a function

I'm pulling information through curl from Fedex Rate Quote Sytem. I am getting the necessary information. The curl functions correctly. The results are accurate. But, when I try to add the results to an array, it wont pass them from the function to the page. Its like the results arent being stored in the function.

foreach($result->SOAPENVBody->RateReply->RateReplyDetails as $value) {
    $number = ++$number;
    $key1 = $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->ServiceType;
    $value1 = $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount;


    $options[$key1] = $value1;
}

    return $options;

I know that the function WILL pass the array set up like this as I tested it with

$key1 = '1';
$value1 = 'Hello';

It passed that information to the page.

When I echo out the curl results through $key1 and $value1 (echo $key1 . $value1;) it displays the correct information on the page as well. IT just wont pass it through to the array.

Below I am pasting the results from the echo to show what information is being retrieved

FIRST_OVERNIGHT: 194.35
PRIORITY_OVERNIGHT: 147.83
STANDARD_OVERNIGHT: 133.77
FEDEX_2_DAY_AM: 111.54
FEDEX_2_DAY: 99.78
FEDEX_EXPRESS_SAVER: 89.71
FEDEX_GROUND: 20.92

And I'm figuring someone will want to see how I am calling the function...here it is from the main page where the function is being called.

include_once('inc/functions/fedex_rate.php');
          $fedex_options = array();
         $fedex_options = fedex_rate($totalweight);

          foreach ($fedex_options as $key => $value) {
              echo '<tr><td colspan="2"><div class="margin10">'. $key .'</div></td><td colspan="2"><div class="margin10">'. $value .'</div></td></tr>'; 
          }

I even tried just using $options as well in the foreach loop on the main page; however, that didnt work either. I finally saw an example where someone set up a new array using array details from the function and so that is where I stopped.


Below is the fedex rate quote complete function minus sensitive information

<?

function getProperty($var) {
if ($var == 'key') return 'xxxxxxxxx';
if ($var == 'password') return 'xxxxxxxxx';
if ($var == 'account') return 'xxxxxx';
if ($var == 'meter') return 'xxxxx';
}


function fedex_rate($totalweight) {
//your account details here
$key = getProperty('key');
$password = getProperty('password');;
$account_number = getProperty('account');
$meter_number = getProperty('meter');
$residential = '1'; // 1 = true, 0 = false
    if ($residential == 1) { $residential = 'true'; }
    if ($residential == 0) { $residential = 'false'; }
if($residential == 1) { $servicetype = 'GROUND_HOME_DELIVERY'; }
if ($residential == 0) { $servicetype = ''; }



$recipient_address = 'xxxxxxx';
$recipient_city = 'xxxxxx';
$recipient_state = 'xx';
$recipient_zip = 'xxxxx';
$recipient_county = 'xx';



$xml = '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://fedex.com/ws/rate/v13"><SOAP-ENV:Body><ns1:RateRequest>
<ns1:WebAuthenticationDetail>
<ns1:UserCredential>
<ns1:Key>'.$key.'</ns1:Key>
<ns1:Password>'.$password.'</ns1:Password>
</ns1:UserCredential></ns1:WebAuthenticationDetail>
<ns1:ClientDetail>
<ns1:AccountNumber>'.$account_number.'</ns1:AccountNumber>
<ns1:MeterNumber>'.$meter_number.'</ns1:MeterNumber>
</ns1:ClientDetail>
<ns1:TransactionDetail><ns1:CustomerTransactionId> *** Rate Request v13 using PHP ***</ns1:CustomerTransactionId></ns1:TransactionDetail><ns1:Version><ns1:ServiceId>crs</ns1:ServiceId><ns1:Major>13</ns1:Major><ns1:Intermediate>0</ns1:Intermediate><ns1:Minor>0</ns1:Minor></ns1:Version><ns1:ReturnTransitAndCommit>true</ns1:ReturnTransitAndCommit>

<ns1:RequestedShipment>
<ns1:DropoffType>REGULAR_PICKUP</ns1:DropoffType>';
// add- if service type is selected, echo service type code.  if not, leave it out
//<ns1:ServiceType>'. $service_type .'</ns1:ServiceType>
$xml .= '<ns1:PackagingType>YOUR_PACKAGING</ns1:PackagingType>
<ns1:TotalInsuredValue>
<ns1:Currency>USD</ns1:Currency>
</ns1:TotalInsuredValue>

<ns1:Shipper>
<ns1:Contact>
<ns1:PersonName>Sender Name</ns1:PersonName>
<ns1:CompanyName>Sender Company Name</ns1:CompanyName>
<ns1:PhoneNumber></ns1:PhoneNumber>
</ns1:Contact>

<ns1:Address>
<ns1:StreetLines></ns1:StreetLines>
<ns1:City></ns1:City>
<ns1:StateOrProvinceCode></ns1:StateOrProvinceCode>
<ns1:PostalCode>xxxxxx</ns1:PostalCode>
<ns1:CountryCode>xx</ns1:CountryCode>
</ns1:Address>
</ns1:Shipper>

<ns1:Recipient>
<ns1:Contact>
<ns1:PersonName>Recipient Name</ns1:PersonName>
<ns1:CompanyName>Company Name</ns1:CompanyName>
<ns1:PhoneNumber></ns1:PhoneNumber>
</ns1:Contact>

<ns1:Address>
<ns1:StreetLines>'. $recipient_address .'</ns1:StreetLines>
<ns1:City>'. $recipient_city .'</ns1:City>
<ns1:StateOrProvinceCode>'. $recipient_state .'</ns1:StateOrProvinceCode>
<ns1:PostalCode>'. $recipient_zip .'</ns1:PostalCode>
<ns1:CountryCode>'. $recipient_county .'</ns1:CountryCode>
<ns1:Residential>'. $residential .'</ns1:Residential>
</ns1:Address>
</ns1:Recipient>

<ns1:ShippingChargesPayment>
<ns1:PaymentType>SENDER</ns1:PaymentType>
<ns1:Payor>
<ns1:ResponsibleParty>
<ns1:AccountNumber>'.$account_number.'</ns1:AccountNumber>
</ns1:ResponsibleParty>
</ns1:Payor>
</ns1:ShippingChargesPayment>

<ns1:RateRequestTypes>ACCOUNT</ns1:RateRequestTypes>

<ns1:PackageCount>1</ns1:PackageCount>
<ns1:RequestedPackageLineItems>

<ns1:SequenceNumber>1</ns1:SequenceNumber>

<ns1:GroupPackageCount>1</ns1:GroupPackageCount>

<ns1:Weight>
<ns1:Units>LB</ns1:Units>
<ns1:Value>'.$totalweight.'</ns1:Value>
</ns1:Weight>

<ns1:Dimensions>
<ns1:Length>10</ns1:Length>
<ns1:Width>10</ns1:Width>
<ns1:Height>10</ns1:Height>
<ns1:Units>IN</ns1:Units>
</ns1:Dimensions>

</ns1:RequestedPackageLineItems>

</ns1:RequestedShipment>
</ns1:RateRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://ws.fedex.com:443/web-services');
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$result_xml = curl_exec($ch);

// remove colons and dashes to simplify the xml
$result_xml = str_replace(array(':','-'), '', $result_xml);
$result = @simplexml_load_string($result_xml);

;


$number = -1;

foreach($result->SOAPENVBody->RateReply->RateReplyDetails as $value) {
    $number = ++$number;
    $key1 = $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->ServiceType;
    $value1 = $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount;
    //echo $key1 .': '. $value1 .'<br />';

    $options[$key1] = $value1;
}

    return $options;

} // function


I was able to get it to work by adding an empty value before and after the $result in the array...but WHY is this the case? Why cant I pass the value of the $result tag to the array by itself?

$key1 = ''. $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->ServiceType .'';

    $value1 = ''. $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount .'';

CAN ANYONE TELL ME WHY I cannot pass the $result directly to the array without any additional blank tags? This ended up being the problem, so the person who figures that out gets the accepted answer.

Upvotes: 0

Views: 101

Answers (3)

Samiul Amin Shanto
Samiul Amin Shanto

Reputation: 1397

After parsing XML, every element is SimpleXMLElement object and object can't be set as key in array.

When you concat empty string, it became string instead of Object. as you know when you try to echo an object it call __toString method (if defined).

if you like to debug this issue, try to call,

var_dump($result->SOAPENVBody->RateReply->RateReplyDetails[$number]->ServiceType)

You can also resolve this by:

$key1 = (string)$result->SOAPENVBody->RateReply->RateReplyDetails[$number]->ServiceType;

OR

$key1 = $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->ServiceType->__toString();

Upvotes: 2

KDJ
KDJ

Reputation: 292

I was able to get it to work by adding an empty value before and after the $result in the array...but WHY is this the case? Why cant I pass the value of the $result tag to the array by itself?

$key1 = ''. $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->ServiceType .'';

    $value1 = ''. $result->SOAPENVBody->RateReply->RateReplyDetails[$number]->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount .'';

Upvotes: 0

monstercode
monstercode

Reputation: 964

The problem is that $options is not defined before in fedex_rate(). just define it as an empty array before the foreach.

 $options = array();
 foreach($result->SOAPENVBody->RateReply->RateReplyDetails as $value) {
    ....

Upvotes: 0

Related Questions