1
\$\begingroup\$

I'm currently using a scientific information management system that employs a RESTful API. I've never used this API with PHP, and I had a hard time finding best practice examples online. After some reading and experimenting, I came up with the following proof-of-concept procedure to retrieve data from the API and then upload the XML object, slightly modified, in order to change information in the system.

I'm most concerned with PHP best practices here: is my PHP efficient, robust, and secure? Is there any code I can remove or make more efficient? I'm using PHP v5.3.8

<!DOCTYPE html>
<html>
<head>

</head>
<body>

<?php
$uriPrefix = 'http://[user:pass]@[path_to_web_app:port]/api/v2/';

//Open up a connection to the API
//for the container:
$containerSuffix = 'containers/27-95';
$containerUri = $uriPrefix . $containerSuffix;
$containerCurl = curl_init($containerUri);

//for the sample:
$sampleSuffix = 'samples/DOR6A12';
$sampleUri = $uriPrefix . $sampleSuffix;
$sampleCurl = curl_init($sampleUri);

//API-specific settings
curl_setopt($containerCurl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($sampleCurl, CURLOPT_RETURNTRANSFER, true);

//get the yummy data
$containerResult = curl_exec($containerCurl);
$containerXml = new SimpleXMLElement($containerResult);
$sampleResult = curl_exec($sampleCurl);
$sampleXml = new SimpleXMLElement($sampleResult);

//close the API connection
curl_close($containerCurl);
curl_close($sampleCurl);

echo '<h2>Some XML for a LIMS Container:</h2>';
echo htmlentities($containerXml->asXML());
echo '<h2>Some XML for a LIMS Sample:</h2>';
echo htmlentities($sampleXml->asXML());

//Now let's infer the project ID for the sample from the XML result
$limsId = $sampleXml->project['limsid'];
echo "<p>The project ID for the sample is $limsId</p>";

//Now let's change the sample name
$newName = 'New Sample Name';
$oldName = (string)$sampleXml->name;
$sampleXml->name = $newName;

$changeSampleCurl = curl_init($sampleUri);
curl_setopt($changeSampleCurl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($changeSampleCurl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($changeSampleCurl, CURLOPT_POSTFIELDS,$sampleXml->asXML());

$changeSampleResult = curl_exec($changeSampleCurl);
echo '<h2>The submitted XML</h2>';
echo htmlentities($changeSampleResult);

curl_close($changeSampleCurl);

echo "<p>The old sample name was $oldName</p>";
echo "<p>It should now be $newName</p>";
?>

</body>
</html>
\$\endgroup\$
1
  • \$\begingroup\$ There's not really much that I've noticed. Though I should warn I'm unfamiliar with REST and cURL. You might consider creating a config file for your suffixes and prefixes, and you might want to escape your HTML rather than echo it; but beyond that, there isn't much here. This is a relatively simple application. \$\endgroup\$
    – mseancole
    Commented Dec 24, 2012 at 15:17

1 Answer 1

1
\$\begingroup\$

The most obvious omission is error handling. You don't handle curl errors or xml parsing errors.

A REST api is like any other external service you might use in your application (such as a database). You might consider creating a client library for it (first check to see if one does not already exist for the service in question). Example usage with the implementation details neatly tucked away:

<?php
//read these values from your configuration and set here
$connection = array(
    'user' => '',
    'pass' => '',
    'baseUrl' => '',
    'version' => ''
);
try {
    $client = new FooClient($connection);
    $container = $client->getContainer('27-95');
    if ($container) {
        //do something with the fetched container
    }

    $sample = $client->getSample('DOR6A12');
    if ($sample) {
        $sample->setName('new name');
        $client->saveSample($sample);
    }
} catch (FooClientException $e) {
    //handle accordingly
}

I'm assuming that the client will return mapped objects for the getContainer and getSample methods. These mapped objects would be instances of php classes which are part of this client library. The xml responses returned by the service would be mapped to to these returned objects. That way, you are not directly dealing with the xml here, rather those details are dealt with in your client library (errors are handled there too with an appropriate exception being thrown if need be).

\$\endgroup\$
1
  • \$\begingroup\$ Thanks, the feedback and examples were extremely helpful! That's a lot of useful info in a small space. \$\endgroup\$
    – DeeDee
    Commented Jan 7, 2013 at 2:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.