-
-
Save AmyStephen/4693855 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* @package Design Patterns | |
* @copyright 2013 Amy Stephen. All rights reserved. | |
* @license MIT | |
* | |
* Proxy Pattern | |
* | |
* A proxy pattern creates an entry point which interacts behind the scenes with other objects. | |
* Can be useful for implementing access control, to implement lazy loading of resource intensive | |
* objects, or to simply act as a wrapper to reduce the options available to another more complex object | |
*/ | |
interface HttpInterface | |
{ | |
public function get(); | |
} | |
/** | |
* HttpProxy Usage Instructions: | |
* | |
* $proxy = new HttpProxy('http://rss.cnn.com/rss/cnn_world.rss'); | |
* echo $proxy->get(); | |
* | |
*/ | |
class HttpProxy implements HttpInterface | |
{ | |
protected $address; | |
protected $string; | |
/** | |
* Constructor | |
* | |
* @param $address | |
*/ | |
public function __construct($address) | |
{ | |
$this->address = filter_var($address, FILTER_SANITIZE_URL); | |
} | |
/** | |
* Method uses HTTP address to retrieve contents of the page | |
* | |
* @return mixed | |
* @throws Exception | |
*/ | |
public function get() | |
{ | |
$handle = curl_init(); | |
curl_setopt($handle, CURLOPT_URL, $this->address); | |
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($handle, CURLOPT_HEADER, 0); | |
try { | |
$data = curl_exec($handle); | |
$response = curl_getinfo($handle); | |
if ($response['http_code'] == 200) { | |
} else { | |
throw new Exception; | |
} | |
curl_close($handle); | |
} catch (Exception $e) { | |
throw new Exception ('Request for address: ' . $this->address . ' failed.'); | |
} | |
$this->string = $data; | |
return $this->__toString(); | |
} | |
/** | |
* Format output as a string | |
* | |
* @return string | |
*/ | |
public function __toString() | |
{ | |
return $this->string; | |
} | |
} | |
/** | |
* Try the Proxy Pattern Example: | |
* | |
* 1. Download and place file on your local server. | |
* 2. Open the file using your browser. | |
*/ | |
$proxy = new HttpProxy('http://www.youtube.com/watch?v=oHg5SJYRHA0'); | |
echo $proxy->get(); |
Agree - removed unnecessary comments from above. |
Agree on the "overkill" for comments. I rarely use comments in the body of the code although I am diligent to provide a decent docblock comment. It's too easy to copy and paste, rarely updated, never tested, and the code should be simple enough to document itself.
In this example case, however, I wanted to leave learners links if they wanted to pick up more about cURL since my example was so basic.
As far as the NOT recommendation, I am of the camp who believe it's best to code "positive."
I don't buy into the "avoid the else" thinking or conserving space. I agree with those who believe the IF portion should represent the "nominal case" but I will think about how to express the normal case in a positive way.
The example we are talking about is simple either way but when the logic starts to get complex, it is very easy to create a bug combining NOT's with OR's and compound logic.
Thanks so much for your comments!
This is not a Proxy. A proxy delegates to a subject just like a decorator, with the only difference that proxies are often connecting to a different boundary like a database or remote call or used for lazy loading.
Like:
class LazySoapClient extends SoapClient
{
protected $constructor, $subject;
public function __construct($wsdl, array $options = null)
{
$this->constructor = func_get_args();
}
protected function _getSubject()
{
if(!$this->subject)
{
$this->subject = new SoapClient(...$this->constructor);
}
return $this->subject;
}
public function __call($function_name, $arguments)
{
return $this->_getSubject()->__call(...func_get_args());
}
public function __soapCall($function_name, array $arguments, array $options = null, $input_headers = null, array &$output_headers = null)
{
return $this->_getSubject()->__soapCall(...func_get_args());
}
//... other methods that forward to the subject, left out for example
}
Why not replace the condition on line 82 with
?
A bit overkill with the comments for curl_init(), curl_exec(), etc. (as that code is self-documenting), but that's a matter of personal preference.