Contact

Paul Wolborsky
California USA
This e-mail address is being protected from spambots. You need JavaScript enabled to view it
www.linkedin.com/in/paulwolborsky



19.10.2009 22:10:00
Administrator

Recently, a client received an email from Yahoo Small Business, announcing:

You're receiving this email to notify you of an upcoming change that may affect your site. To improve security for both merchants and buyers, we will soon be disabling the following deprecated PHP options: Register_globals & allow_url_fopen.

Yahoo can calculate shipping for you, but gives you the option of doing that yourself, using Windows dot.net, asp, or PHP programming languages.  If a shopper is on the Shopping Cart page and is trying out shipping options, you can use your own webserver to can get information and shoot back a quote.  When a customer makes a purchase, you can get order information and update your own inventory/shipping/packing system.

If you are one of these businesses using PHP as your backend, this affects you.

So what are these settings?

Registered globals mean that if you pass in parameters in a url like http://www.mydomain.com/index.php?firstname=paul&lastname=wolborsky, a developer can add these lines in the script...

 

echo "Hello ".$firstname." ".$lastname

 

This is not good because I could influence the code just by crafting a URL.  Registered Globals was a bad idea from the get-go, and the programming style it allows is no longer in use, and you probably won't need to take action on it.

 

The 2nd restriction, allow_url_fopen is a bigger deal.  Your backend shipping system calls UPS and USPS for address verification and shipping quotes.  Chances are great that your developer uses the fopen function to access them.  The fopen function is used to open a file on your server, but if allow_url_fopen is enabled, you can open a file on an outside server as a URL.  This is the most popular and oldest ways to get quotes out of UPS and USPS.  And Yahoo now forbids it.

The other way to call UPS and USPS is to use the php cURL functions.  But it's not as simple as replacing the fopen call with cURL calls.  There are some wrinkles and gotchas:

1) UPS has separate services for getting shipping quotes, the old cgi you can use with fopen (http://www.ups.com/using/services/rave/qcostcgi.cgi), and a newer XML you can use with cURL (https://www.ups.com/ups.app/xml/Rate).

2) While writing code to calling the UPS CGI is easy, passing parameters as a single string like 'destinationCity=$city&destinationState=$state' you have to create an XML string for the xml, like

$xml="<?xml version="1.0"?>
<AccessRequest xml:lang="en-US">
<AccessLicenseNumber>$this->accesskey</AccessLicenseNumber>
<UserId>$this->userid</UserId>
<Password>$this->passwd</Password>
</AccessRequest>
<?xml version="1.0"?>
<RatingServiceSelectionRequest xml:lang="en-US">
<Request>
<TransactionReference>
<CustomerContext>Rating and Service</CustomerContext>
<XpciVersion>1.0001</XpciVersion>
</TransactionReference>
<RequestAction>Rate</RequestAction>
<RequestOption>$this->request</RequestOption>
</Request>
<PickupType>
<Code>$this->pickuptype</Code>
</PickupType>
<Shipment>
<Shipper>
<Address>
<StateProvinceCode>$this->s_state</StateProvinceCode>
<PostalCode>$this->s_zip</PostalCode>
<CountryCode>$this->s_country</f>
</Address>
</Shipper>
<ShipTo>
<Address>
<StateProvinceCode>$this->t_state</StateProvinceCode>
<PostalCode>$this->t_zip</PostalCode>
<CountryCode>$this->t_country</CountryCode>
<ResidentialAddressIndicator>$this->residential</ResidentialAddressIndicator>
</Address>
</ShipTo>
<Service>
<Code>$this->service</Code>
</Service>
<Package>
<PackagingType>
<Code>$this->package_type</Code>
<Description>Package</Description>
</PackagingType>
<Description>Rate Shopping</Description>
<PackageWeight>
<Weight>$this->weight</Weight>
</PackageWeight>
</Package>
<ShipmentServiceOptions/>
</Shipment>
</RatingServiceSelectionRequest>";

3) Then you have to setup cURL.  The example for UPS looks like this:
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL,"$this->upstool"); /// set the post-to url (do not includethe ?query+string here!)
curl_setopt ($ch, CURLOPT_HEADER, 0); /// Header control
curl_setopt ($ch, CURLOPT_POST, 1); /// tell it to make a POST, not a GET
curl_setopt ($ch, CURLOPT_POSTFIELDS, "$y"); /// put the querystring here startingwith "?"
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); /// This allows the output to be setinto a variable $xyz
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); /// some php version cause error withcurl without this line
$this->xmlreturndata = curl_exec ($ch); /// execute the curl session and return theoutput to a variable $xyz
curl_close();
4) Then, you have to extract the number you want from the response XML
$xmlParser = new xmlparser();
$array = $xmlParser->GetXMLTree($data);
$amount = $array["RATINGSERVICESELECTIONRESPONSE"][0]["RATEDSHIPMENT"][0]["TOTALCHARGES"][0]
["MONETARYVALUE"][0]["VALUE"];
5) And to top it off, Service codes have changed.  When before you can pass in "2nd Day Air", XML requires a number code, so you have to change other code in other functions to make this work.  Also, USPS now prefixes all its services with USPS, so any array with those services have to be changed too.
6) USPS uses a URL that embeds XML.  "<" are bad to use in a URL and XML is all about <tag>some data</tag>, so you'd have to encode the "<" for safe passage.

 

 

Other issues may come up to light only because you hadn't looked at the code for a long time.  For example, using cURL with XML, you can get a quote for all your packages with just one call, rather than making a call for each box.  You may need to be logging each call and response to make sure they all succeed.  I ran into code that returns a "0" shipping cost if even one box generates an error, to fix this issue, I'd have to add 0 to the total and log the specific error so the client will know that the total shipping cost is underestimated.  If your call fails, you have to try again, otherwise, the error triggers a pernicious 'modify header' warning that results in your back-end returning an estimate of "0" for shipping cost.

 

Your back-end is also mission critical, so you need to add testing time to your cost, and you need to make sure the developer can batch test a large number of previous transactions to make sure results are the same, or changes are very small.

 

 



  
 

25.03.2010 16:34:13

It's well known that money can make us free. But what to do if someone has no cash? The one way only is to receive the <a href="http://lowest-rate-loans.com/topics/personal-loans">personal loans</a> or term loan.

 
 
Reply this post
Username:

E-mail:

  Enter text shown in left:
 



Copyright © -2012 AjaxOfAllTrades.com