I wrote a PHP connector that will allow me to communicate with a REST API using PHP.
The class was little over 1500 lines of code, it was difficult to manage it. It was a nightmare to even look at it as you can probably imagine. My intention was to better my code to a point where I can share it on GitHub and help me become a better OOP programmer. The original class can be foubd in my part 1 question.
After taking the feedback in consideration and doing research on "Single Responsibility Principle" I revised my class and broke the huge class into 11 different smaller classes.
Now, I would like to ask this question as a part 2 which extends my first question and like to see if I can get the experts to review my code and tell me how can I make it even better as I like to learn from my mistakes.
Due to the characters restrictions here, I will post a single class here and the rest can be downloaded from this URL.
Please tell me what else can be done to better my code?
Any idea that will help me improve it?
<?php
namespace ICWS;
/**
* ApiCallsHandler
*
* @package ICWS
*/
class ApiCallsHandler {
protected $cookiesFile = 'icwsCookies';
protected $timeOutMS = '5000';
protected $url = null;
protected $uri = null;
protected $method = null;
protected $params = null;
protected $header = null;
protected $debug = null;
protected $httpCode = 0;
protected $caCertLocation= null;
protected $filename = null;
public function __construct($url, $debug = false, $caCertLocation = null){
$this->url = $url;
$this->caCertLocation = $caCertLocation;
$this->debug = $debug;
}
/**
* Initialize the cURL session
*
* @return curl_init session
*/
private function initializeSession()
{
$url = $this->url . '/' . $this->uri;
$ch = curl_init();
if(
($this->method == 'POST' || $this->method == 'PUT')
&& $this->params
){
$jsonString = json_encode($this->params);
curl_setopt( $ch, CURLOPT_POSTFIELDS, $jsonString );
}
if($this->method == 'POST'){
curl_setopt($ch, CURLOPT_POST, true);
} elseif( $this->method == 'PUT'){
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
} else {
if ($this->params){
$url = sprintf("%s?%s", $url, http_build_query($this->params, '', '&'));
}
}
//echo $url .'<br>';
//set the URL
curl_setopt($ch, CURLOPT_URL, $url);
//disable the use of cached connection
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
//return the respond from the API
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//return the HEADER respond from the API
curl_setopt($ch, CURLOPT_HEADER, true);
//add custom headers
if(!empty($this->header)){
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->header);
}
//add the cookie value
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookiesFile); // write
curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookiesFile); // read
curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->timeOutMS);
//enable SSL
if( !empty($this->caCertLocation)){
curl_setopt($ch, CURLOPT_CAINFO, $this->caCertLocation);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);
}
if( $this->debug){
$requestFile = $this->getFileName();
$file = fopen($requestFile, 'w');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $file);
echo '<br>================================= START REQUEST =================================<br>';
echo 'Method: ' . $this->method .'<br>';
echo 'url: ' . $url .'<br>';
echo 'Headers<br>';
echo '<pre>';
print_r($this->header);
echo '</pre>';
print 'Body<br><pre>' . json_encode( $this->params, JSON_PRETTY_PRINT) .'</pre><br>';
echo '================================= END REQUEST =================================<br><br>';
}
return $ch;
}
public function getHttpCode(){
return $this->httpCode;
}
/**
* Calls any Method that does not require a sessionId using a GET method
*
* @param string $uri
* @param array $params
* @return array or false
*/
public function getData($uri, $params = false){
$httpCode = 0;
$data = (object) $this->processRequest('GET', $uri, $params, $httpCode);
if( $this->debug){
new showVar($data, false, 'HTTP Code: ' . $httpCode);
}
return $data;
}
/**
* returns a the filename to output the request to
*
* @return string
*/
private function getFileName(){
$requestFile = null;
if(empty($this->filename)){
$requestFile = rand(1, 100) . '.txt';
} else {
if(!strpos($this->filename, '.')){
$requestFile = $this->filename . '.txt';
}
}
return $requestFile;
}
/**
* Handle the cURL call to the API
*
* @throws ApiException
* @param string $method GET/POST/PUT
* @param string $uri
* @param array $data
* @param array &$httpCode
* @param string $filename
* @return array
*/
public function processRequest( $method, $uri, $params = false, array $header = array(), $filename = null)
{
$this->method = $method;
$this->uri = $uri;
$this->params = $params;
$this->header = $header;
$this->filename = $filename;
$ch = $this->initializeSession();
//send the request to the API
$respond = curl_exec($ch);
//read the http code returned from ICWS
$this->httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($this->debug){
new showVar(curl_getinfo($ch));
}
//throw cURL exception
if($respond === false){
$errorNo = curl_errno($this->ch);
$errorMessage = curl_error($this->ch);
throw new ApiException($errorMessage, $errorNo);
}
list($header, $body) = explode("\r\n\r\n", $respond, 2);
if($uri == 'connection'){
$this->_handleReceivedHeaders($header);
}
//convert respond to an array
$result = json_decode($body);
//throw API exception
if( $this->_hasAPIError($result) ){
$errorCode = 0;
if(isset($result->errorCode)){
$errorCode = $result->errorCode;
}
throw new ApiException($result->message, $errorCode);
}
return $result;
}
/**
* Checks if the API return an error
*
* @param array $result
* @return boolean
*/
private function _hasAPIError($result){
if( isset($result->errorId) && !empty($result->errorId)
&& isset($result->message) && !empty($result->message)
){
return true;
}
return false;
}
/**
* Get the cookie HTTP headers and set them as cookie
*
* @param array $httpRespond
* @return void
*/
private function _handleReceivedHeaders($httpRespond){
$header = $this->_http_parse_headers($httpRespond);
//new showVar($header);
//set the ININ-ICWS-CSRF-Token value
if( isset($header['ININ-ICWS-CSRF-Token']) ){
$this->ININ_ICWS_CSRF_Token = $header['ININ-ICWS-CSRF-Token'];
$_SESSION['ININ-ICWS-CSRF-Token'] = $this->ININ_ICWS_CSRF_Token;
}
}
/**
* convert cURL header into an array
*
* @param string $raw_headers
* @return array
*/
private function _http_parse_headers($raw_headers)
{
$headers = array();
$key = '';
foreach(explode("\n", $raw_headers) as $i => $h)
{
$h = explode(':', $h, 2);
if (isset($h[1])){
if (!isset($headers[$h[0]])){
$headers[$h[0]] = trim($h[1]);
} elseif (is_array($headers[$h[0]])){
$headers[$h[0]] = array_merge($headers[$h[0]], array(trim($h[1]))); // [+]
} else {
$headers[$h[0]] = array_merge(array($headers[$h[0]]), array(trim($h[1]))); // [+]
}
$key = $h[0];
} else {
if (substr($h[0], 0, 1) == "\t"){
$headers[$key] .= "\r\n\t".trim($h[0]);
} elseif (!$key){
$headers[0] = trim($h[0]);trim($h[0]);
}
}
}
return $headers;
}
}