Oct 13th

0

cURL wrapper class with executable and PHP extension support

7 years 8 months ago comment No Comments

Most cURL wrapper classes I found could handle either the PHP extension or the command line executable version of cURL. I needed a class where I could set one variable and have it switch from using the PHP cURL extension to the cURL executable without having to change the other variable of the class.

The class I came up with is below:


class Curl {

	// Set to "PHP" or the path to the curl executable (binary)
	var $curlExecutable = "PHP";

	// URL to request, request type (GET or POST), request parameters as an associative array or null for none
	var $url;
	var $requestType = "GET";
	var $parameters = null;

	// request headers as an array
	var $requestHeaders = array();

	// certification authority, return data with headers, follow redirects and verify peer if URL is https
	var $cainfo = null;
	var $outputWithHeaders = false;
	var $followLocation = false;
	var $SSLVerifyPeer = true;

	// connect to remote server timeout and timeout to download the entire page
	var $connectTimeout = 30;
	var $timeout = 10800;

	// if there was an error, errorNumber and error is populated. data contains the page downloaded
	var $error = null;
	var $errorNumber = null;
	var $data = null;

	function fetchPage() {

		if ($this->curlExecutable == "PHP") {
			$ch = curl_init();

			if ($this->cainfo) {
				curl_setopt($ch, CURLOPT_CAINFO, $this->cainfo);
			}

			if ($this->SSLVerifyPeer) {
				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
			} else {
				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
			}

			if ($this->requestType === "POST") {
				curl_setopt($ch, CURLOPT_POST, 1);

				if ($this->parameters) {
					if (is_array($this->parameters)) {

						$encodedParameters = "";
						$join = "";

						foreach ($this->parameters as $name => $value) {
							$encodedParameters = $encodedParameters . $join . rawurlencode($name) . "=" . rawurlencode($value);
							$join = "&";
						}

						curl_setopt($ch, CURLOPT_POSTFIELDS, $encodedParameters);

					} elseif (is_string($this->parameters)) {

						curl_setopt($ch, CURLOPT_POSTFIELDS, $this->parameters);

					}
				}

			} else {
				curl_setopt($ch, CURLOPT_POST, 0);

				if ($this->parameters) {
					$encodedParameters = "";
					$join = "?";

					foreach ($this->parameters as $name => $value) {
						$encodedParameters = $encodedParameters . $join . rawurlencode($name) . "=" . rawurlencode($value);
						$join = "&";
					}

					$this->url = $this->url . $encodedParameters;
				}

			}

			curl_setopt($ch, CURLOPT_HTTPHEADER, $this->requestHeaders);

			if ($this->outputWithHeaders) {
				curl_setopt($ch, CURLOPT_HEADER, 1);
			} else {
				curl_setopt($ch, CURLOPT_HEADER, 0);
			}

			if ($this->followLocation) {
				curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
			} else {
				curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
			}

			curl_setopt($ch, CURLOPT_URL, $this->url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
			curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);

			$this->data = curl_exec($ch);
			$this->error = curl_error($ch);
			$this->errorNumber = curl_errno($ch);
			curl_close($ch);

			if ($this->error) {
				return false;
			} else {
				return true;
			}

		} else {

			$command = $this->executable;

			$command = $command . " -s -S";

			$command = $command . " --connect-timeout " . $this->connectTimeout;
			$command = $command . " --max-time " . $this->timeout;

			if ($this->cainfo) {
				$command = $command . " --cacert "" . $this->cainfo . """;
			}

			if ($this->outputWithHeaders) {
				$command = $command . " -i";
			}

			if ($this->followLocation) {
				$command = $command . " -L";
			}

			for ($i = 0; $i < count($this->requestHeaders); $i++) {
				$command = $command . " -H "" . $this->requestHeaders[$i] . """;
			}

			if ($this->parameters){
				$encodedParameters = "";
				$join = "";

				foreach ($this->parameters as $name => $value) {
					$encodedParameters = $encodedParameters . $join . rawurlencode($name) . "=" . rawurlencode($value);
					$join = "&";
				}

				$command = $command . " -d " . escapeshellarg($encodedParameters) . "";
			}

			if ($this->requestType === "GET") {
				$command = $command . " -G";
			}

			$command = $command . " " . $this->url;

			$descriptorspec = array(
			0 => array("pipe", "r"),
			1 => array("pipe", "w"),
			2 => array("pipe", "w")
			);

			$process = proc_open($command, $descriptorspec, $pipes);

			if (is_resource($process)) {

				fclose($pipes[0]);    // close stdin as we are not going to supply any input

				$this->data = stream_get_contents($pipes[1]);    // read stdout
				$this->error = stream_get_contents($pipes[2]);    // read stderr

				fclose($pipes[1]);
				fclose($pipes[2]);

				$this->errorNumber = proc_close($process);

			} else {

				return false;

			}

			if ($this->errorNumber === 0) {
				return true;
			} else {
				return false;
			}

		}

	}

}

The following example fetches http://www.google.com :

$request = new Curl;
$request->curlExecutable = "PHP";
$request->followLocation = true;
$request->url = "http://www.google.com";
if ( $request->fetchPage() ) {
	header("Content-Type:text/plain");
	echo $request->data;
} else {
	echo "An error occured: " . $request->errorNumber . " - " . $request->error;
}

This example fetches a random quote (the ones tou see on the top right of this website):

$request = new Curl;
$request->curlExecutable = "PHP";
$request->url = "http://www.ankur.com/quotes.php";
$request->requestType = "GET";
$request->parameters = array(
	"action" => "random"
);
if ( $request->fetchPage() ) {
	header("Content-Type:text/plain");
	echo $request->data;
} else {
	echo "An error occured: " . $request->errorNumber . " - " . $request->error;
}

Unrelated to the cURL wrapper class, you can try changing the action parameter from random to all to fetch all the quotes.

Related posts:

  1. AES wrapper class with pure php and MCrypt extension support
  2. Resume HTTP downloads in PHP using cURL or fsockopen

Leave a Reply