Created
November 17, 2011 14:49
-
-
Save yattias/1373304 to your computer and use it in GitHub Desktop.
A very good function for executing service calls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* @author: K0b3 Attias | |
* Executes a services call to a specific endpoint using curl with a number of options | |
* TODO: Modify the params to be a single object with multiple options | |
* @since 09/02/11 | |
* @param <string> $service: The service to execute the call on (defined as a constant in one of the includes files) | |
* @param <string> $method: The method that will be called on the service (defined as a constant in one of the includes files) | |
* @param <string> $http_method: HTTP method | |
* @param <array> $params: Params which will be passed to the endpoint | |
* @param <bool> $verbosity: Return values can either be just the response or an array | |
* containing the http code, method, url, params, and response if this flag is set to TRUE | |
* @param <array> $options: Array of CURL options (for curl_setopt_array) | |
* @return FALSE on error OR the server response on a 2XX reply and verbosity = 0 OR array of all params and http status if verbosity = 1 | |
* */ | |
function rtr_services_exec($service, $method, $params, $http_method, $verbosity = 0, $options = array()) { | |
global $user; | |
$response = NULL; | |
try { | |
//Initialize connection and save curl handler | |
$ch = curl_init(); | |
$url = $service . "/" . $method; | |
$serialized_params = NULL; | |
//Serialize params...http_build_query DOES NOT PLAY WELL with curl! Do Not use! | |
foreach ($params as $key => $value) { | |
if (is_array($params[$key])) { | |
foreach ($params[$key] as $k => $v) { | |
$serialized_params .= urlencode($key) . "=" . urlencode($v) . "&"; | |
} | |
} else { | |
$serialized_params .= urlencode($key) . "=" . urlencode($value) . "&"; | |
} | |
} | |
$serialized_params = rtrim($serialized_params, '&'); | |
//Notify log | |
rtr_info("### SERVICE CALL -- SERVICE: " . $service . " -- METHOD: " . $method . " -- PARAMS: " . $serialized_params . " ### "); | |
//Set maximum number of seconds to connect with the service | |
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, RTR_API_TIMEOUT_SECONDS); | |
//Set maximum number of seconds to try and execute request | |
curl_setopt($ch, CURLOPT_TIMEOUT, RTR_API_TIMEOUT_SECONDS); | |
//This could be a liability if someone is passing URL, HTTPGET, POST, etc options) | |
if (sizeof($options)) { | |
//ASSERT: options specified, set them. | |
curl_setopt_array($ch, $options); | |
} | |
//Set curl method | |
switch (strtoupper($http_method)) { | |
case 'GET': | |
//Set URL | |
curl_setopt($ch, CURLOPT_URL, $url . "?" . $serialized_params); | |
curl_setopt($ch, CURLOPT_HTTPGET, TRUE); | |
break; | |
case 'POST': | |
curl_setopt($ch, CURLOPT_URL, $url); | |
curl_setopt($ch, CURLOPT_POST, sizeof($params)); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $serialized_params); | |
break; | |
default: | |
curl_setopt($ch, CURL_HTTPGET, $serialized_params); // default to get | |
break; | |
} | |
//TODO: Add support for PUT requests | |
//Return response as string | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); | |
//Execute curl | |
$response = curl_exec($ch); | |
//Info | |
$response_info = curl_getinfo($ch); | |
//TODO: Don't rely on a 200 only response code as sucess, talk to infra on proper response set | |
if ($response_info['http_code'] != 200 && $verbosity == 0) { | |
//ASSERT: Error has occured | |
throw new Exception('bad_http_code'); | |
} else { | |
switch($verbosity) { | |
case 0: | |
$return = $response; | |
break; | |
case 1: | |
if ($response_info['http_code'] != 200) { | |
watchdog("rtr_services", __FUNCTION__ . ": TOOK " . curl_getinfo( $ch, CURLINFO_TOTAL_TIME ) . " SECS, RETURNED HTTP CODE " . $response_info['http_code'] . " AND CURL ERROR " . curl_error($ch) . " " . $url); | |
} else { | |
watchdog("rtr_services", __FUNCTION__ . ": TOOK " . curl_getinfo( $ch, CURLINFO_TOTAL_TIME ) . " SECS, RETURNED HTTP CODE " . $response_info['http_code'] . " AND RESPONSE " . $response . " " . $url . ". REQUEST TOOK " . curl_getinfo( $ch, CURLINFO_TOTAL_TIME ) . " SECONDS"); | |
} | |
$return = array( | |
"http_code" => $response_info['http_code'] | |
, "url" => $url | |
, "params" => $serialized_params | |
, "method" => $http_method | |
, "response" => $response | |
); | |
break; | |
default: | |
$return = $response; | |
break; | |
} | |
} | |
//Close curl handler | |
curl_close($ch); | |
} catch (Exception $e) { | |
switch ($e->getMessage()) { | |
case 'bad_http_code': | |
rtr_warn('Request to URL failed: ' . $url . PHP_EOL . 'Reason: HTTP Code' . $response_info['http_code']); | |
break; | |
default: | |
rtr_warn('An exception occured while trying to execute service call o_0' . PHP_EOL . 'Error: ' . $e->getMessage()); | |
break; | |
} | |
$return = FALSE; | |
} | |
return $return; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Actually, the only thing left to do to make it even better is to have different behavior depending on http codes.