I must admit, I'm guilty of having used file_get_contents() for far too long to make my eBay Shopping API calls. While it often gets the job done, I think fgc is really made for reading local files and just happens to be useful for quickly pulling data from remote URLs as well. When I started using the Trading API I was forced to learn a much better and more elegant/formal/stable way of making API calls via PHP: using cURL. cURL, as it turned out, wasn't difficult to learn at all.
Still, I eventually sat down and wrote a handy function to make using cURL easier for me when making eBay API calls. I called the function cURLfriend() and you are welcome to use it, located here on my site.
I use it to make both Shopping and Trading API calls. I also use it to pull data from the eBay Daily Deals XML feeds, and I presume the function would work fine with several other API calls or XML-based web services elsewhere. cURLfriend() will send a REST or XML-based call to an endpoint URL and expect an XML response. It also re-calls the server a few times if there's no response and does a couple rudimentary data-integrity checks as well. Moreover, you can specify retry count and timeout values. The reponse is an array that contains eBay's XML reponse, a status code, and some cURL call stats like the session duration and size. Here's an abbreviated example of making a Shopping API call with cURLfriend():
$ShoppingAPIcall = "http://open.api.ebay.com/shopping?appid=...." ; // insert your Shopping API call here $Response = cURLfriend($ShoppingAPIcall) ; // make the call $Response_Data = $Response[0] ; // put the XML response (as a string) into a variable $Response_Status = $Response[1] ; // cURLfriend() also returns a status code
if ($Response_Status == "n") { $Response_XML = simplexml_load_string($Response_Data) ; // convert XML string to an XML object // continue to parse/process XML data here... } else { echo("Problem retrieving data. Status Code: " . $Response_Status) ; }
You can also make a Trading API call:
$EndpointURL = "https://api.ebay.com/ws/api.dll" ; $Headers = array( /* Build your headers here */ ) ; $POSTdata = ( /* Build your POST data here */ ) ;
In the scheme of things, this isn't a complicated function -- after all, it's just a wrapper function to take the legwork out of setting up a cURL session, making retries in the occasional event of no response from the API, and doing some quick input validation and data integrity checks. Still, some may find this helpful in their work with the API.
As you can see in the function itself, I'm kind of old skool, using simple functions instead of objects/classes. If you have any nifty optimizations to share, or spot a glaring inefficiency, feel free to post it to this thread and I'll try to integrate it.
If you do go ahead and integrate cURLfriend() within your own scripts, please be sure to check out the notes beneath the function itself on my site.
Thanks, and enjoy. :)
-h
Posts:
185
Member Since:
9/11/08
Re: PHP: Using cURL to Make eBay API Calls - Need a Friendly Hand?
Posted:
Aug 3, 2009 4:32 PM
The function is good for generic use, but you added a couple ebay references to make it eBay specific. The messages can be more generic. Then you could use the function for anything. Otherwise name it eBaycurlFriend. And then go completely the other direction and have the function build the URL for you.
The validation of the inputs should be more consistent. You validate the xml, but not the url or headers. Documenting what the function expects to see would be good enough. (urlencoded, utf-8, etc)
Also, this doesn't really warrant a custom user agent. You're masking the php.ini useragent value and the cURL version. Both may have some impact on operation that is not related to your function. Appending your string to the existing agent would be friendlier, but relying on referrer to contact the website is just as good. User agent is intended for diagnostics, not as an advertisement and as you have it, it might be treated as spam.
If you leave it in, you should move the user agent assignment and anything else that needs customization by the programmer to the top in a clearly commented area. FWIW, passing email address in the UA is a bad idea. If this were used generically, the programmer's email address would end up posted to thousands of websites that post their weblogs. As an eBay specific solution that's less likely. The guys at yourdomain,com might like you though.
A bit of overkill, but the retry option is good. Have you profiled this at all to see how much overhead it adds?
How about a lighter version that just returns response or blank?
I like to say if(curlFriend(...)!=''){ instead of all that array handling around every call. I realize curl users are sorta addicted to all that typing, but I like life simpler.
Posts:
473
Member Since:
1/2/08
Re: PHP: Using cURL to Make eBay API Calls - Need a Friendly Hand?
Posted:
Aug 5, 2009 9:25 PM
User Agent: Good points. I decided to just comment out the setting of the user agent, and address its use in the notes at the bottom of the page. I hadn't thought about it overriding php.ini or, should this be used for non-eBay web services, webmasters publicizing their logs and exposing email addresses. I actually don't know a whole lot about the user agent; I don't even know if eBay's servers recognize or log them. But, when I do see strange bots accessing my sites, I look at the user agent, and if there's an email address or info URL provided, I feel a little better about the bot. So, I figured it was good etiquette for scripts to identify themselves in the UA.
Yes, I guess there is some inconsistency in the input validation. This function really is meant just for eBay API calls, but if it works with any other XML-based web services, then cool. I didn't really want to get caught up in input validation at all, since it's of course an internal matter for the developer, but some quick checks were super-easy for me to throw in there, so I went ahead with it.
HTTP Version: I forced it to HTTP 1.1 because of some occasions where we noted that a HTTP 1.0 call to the API servers might sometimes erroneously generate a HTTP 1.1 response that the calling function (using file_get_contents() or simplexml_load_file() ) couldn't process. (See threads linking from my first post here for more info on this quirk.) I figured using 1.1 would be playing it safe.
Retries: It's been a while since I've fiddled with this, but when I was first learning the API I noticed that occasionally a call would flat out fail, for a handful of different reasons. While it was frustrating to discover, the bright side was that a simple re-call almost always solved the problem, so I eventually built auto-recalling into all of my calls. I like it being transparent to my needs. No, I have not checked to see how much overhead this feature adds. Last I checked, only 1 loop/call is necessary 99+% of the time.
-h
Posts:
185
Member Since:
9/11/08
Re: PHP: Using cURL to Make eBay API Calls - Need a Friendly Hand?
Posted:
Aug 6, 2009 6:09 AM
Just thoughts there. It is what it is and most likely anyone using it will customize it themselves. My own functions test for totalitems>0 before returning the xml, so I'm doing the same thing myself.
For the intended use http 1.1 is a wise move.
As far as the performance issue goes, I wasn't thinking in terms of the retries. I was thinking in terms of all the curl and array handling. If 200 people hit at once, every little bit helps. I haven't played with curl extensively, but opening and configuring a curl session outside the fetch function might help if you are doing multiple calls. I'm probably overly concerned about the setup time. And it all depends on volume anyway.
I don't use retries at all with Shopping, I short term cache the results and if FIA fails I fallover to findpopularitems. With the finding API conversion I'm working on a different approach. Retries seemed to be a big issue for you at one point. Has this lessened, or is it just that your retry strategy corrects for it and you aren't bothered by it anymore?
Posts:
473
Member Since:
1/2/08
Re: PHP: Using cURL to Make eBay API Calls - Need a Friendly Hand?
Posted:
Aug 6, 2009 10:21 PM
Has this lessened, or is it just that your retry strategy corrects for it and you aren't bothered by it anymore?
The latter... I have retrying as part of all my calls, so I never notice unless there's a really big issue (Ack=Failure, etc.) at play. Maybe those API hiccups from last year have really lessened and I'm just not looking for it.
As for performance, you could be right. I haven't done any testing, but I do notice a speed slowdown when I make a long sequence of calls using cURLfriend(). ...Yes, optimizations can certainly be made to this function.