-
-
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.