PHP Proxy Design Pattern: Protect Your Assets

Protection Proxy Design Pattern

The Proxy Design Pattern is another pattern that’s easy to understand. Essentially, you have a proxy object that acts as a stand-in for a real object. A request is made to the Proxy which in turn passes on the request to the RealSubject or blocks the request from the RealSubject. The purpose of the Proxy is to have variation where you have different ways an object is accessed. As a result, you find the Proxy patterns are commonly found where you have login controlled by a username and password. The access, while it may appear to be directly to the object of interest, is actually through a proxy object.

Try it out clicking the Play button and the Download button will download all of the files. (To figure out the username and password see the Proxy.php file listing.)

The Many Faces of Proxy

The Proxy design pattern has more than one kind. All Proxy designs separate the request from the RealSubject, but because of the different applications, Gamma, Helm, Johnson and Vlissides (p. 210) specify three distinct kinds of proxies:

  1. Remote Proxy. When a proxy object is in one address space and the real object is in another, the proxy is a remote one. Besides using a remote proxy as a firewall, the remote proxy can be used for online games where the same object is needed in different places at the same time.
  2. Virtual Proxy. A virtual proxy may cache information about a real subject so that access to the real subject can be postponed. Sometimes high security logins use a virtual proxy for the login before the real object handles the login data.
  3. Protection Proxy. The protection proxy keeps the request away from the real subject until the request is verified by the protection proxy. The real subject is the target of the request, such as access to database information. Many protection proxies have different levels of access, depending on the user’s login information; so instead of having a single real subject, the real subject may be multiple and restricted.

    Figure 1 shows the proxy’s structure that can be applied to all three kinds of proxies:

    Figure 1: Proxy Design Pattern

    The RealSubject and Proxy classes share the same interface (Subject) whether it is an abstract class or interface. Note that the request is through the Subject interface, and with PHP, that can be a little tricky, but as you’ll see, not impossible.

    Ask the Proxy

    To understand the Proxy design pattern In a nutshell,

    The client makes a request through the proxy and the proxy passes on the request to the real subject.

    Often, you will see an object diagram that outlines the structure of the pattern at run-time. Figure 2 shows the Proxy pattern in such a diagram:

    Figure 2: Proxy Object Diagram

    As you can see, the client holds a reference to the Subject and the Proxy holds a reference to the RealSubject. In designing an application in PHP, we need to keep in mind that the reference to an interface requires use of PHP type hinting. That is a crucial requirement because programming to an interface instead of an implementation is one of the key requirements of using design patterns correctly. The interfaces provide the loose coupling in a design pattern.

    The Subject Interface

    In previous Proxy design pattern applications, I’ve used an interface instead of an abstract class for the interface. (The term interface is used to describe the general methods that are inherited or implemented in either an interface or abstract class declaration.) In this application I found that using an abstract class provided a security option in that I could assign the MySQL connection, database and table values to a participant that cannot be instantiated.

    
    abstract class ISubject
    {
            protected $server="localhost";
            protected $user="bill";
            protected $pass="billz";
            protected $currentDB="phpwork";
            protected $tableMaster="proProxy";
     
            abstract protected function request();
    }
    ?>

    The class name, ISubject indicates that it is used as the application’s interface. From this class, we derive both the Proxy class and RealSubject class. The Proxy has no use whatsoever for the MySQL properties in ISubject, but if ever an unwanted access was made to the RealSubject, the connection information would still be secure in the abstract class.

    The Proxy Class

    The Proxy class is really nothing but a login control that forwards a request to the RealSubject. However, the key method, request(), is a protected one. (This was defined in the ISubject class.) Protected visibility adds yet another layer of security to the design. This means that the RealSubject request() method can only be accessed through the Proxy class. The following listing shows how this is accomplished:

    
    include_once("ISubject.php");
    include_once("RealSubject.php");
    class Proxy extends ISubject
    {
            private $realSubject;
     
            protected function request()
            {     
                    $this->realSubject=new RealSubject();
                    $this->realSubject->request();    
            }
     
            public function login($un,$pw)
            {
                    //Evaluates password etc.
                    if($un==="Professional" && $pw==="acp")
                    {
                            $this->request();
                    }
                    else
                    {
                            print "Cry 'Havoc,' and let slip the dogs of war!";
                    }
            }
    }
    ?>

    Like private variables and methods, PHP requires that the $this statement to be used with protected elements in a class. The program declares a private $realSubject variable (yet another layer of protection) to be used in establishing a reference to the RealSubject object.

    The public method login simply evaluates the login credentials and passes on the request to the RealSubject. It does this by calling the protected request() method in the Proxy class, which in turn calls the RealSubject’s request() method.

    The RealSubject

    Other than the fact that it’s protected by the Proxy class, the RealSubject object can be just about anything you want. In other words, any class you want that includes the parent class interface.

    
    class RealSubject extends ISubject
    {             
            protected function request()
            {
                    ini_set("display_errors","2");
                    ERROR_REPORTING(E_ALL);
     
                    $hookup=new mysqli($this->server, $this->user, $this->pass, $this->currentDB);
                    if (mysqli_connect_error()) 
                    {
                    die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
                    }
     
                    //Create Query Statement
                    $sql ="SELECT * FROM $this->tableMaster";
     
                    if ($result = $hookup->query($sql))
                    {
                    printf("Select returned %d rows.

    ", $result->num_rows); while ($row = $result->fetch_assoc()) {   printf("ID: %d Name: %s OS: %s Language: %s
    "
    ,$row ['id'], $row['uname'],$row['os'],$row['lang'] ); }   $result->close(); } $hookup->close(); } } ?>

    In the Proxy pattern, the RealSubject does not return anything but generates data and output itself. In this example, it simply generates output from a table using mysqli functions. Think of the RealSubject as what’s protected, but once accessed, it’s just a standard object.

    The Client Holds a Reference to the Interface

    The sine qua non of design patterns is to optimize reuse and change. The key to doing that is the first rule of design patterns—program to the interface and not the implementation. As you can see in Figure 1, the Client holds a reference to the Subject (ISubject in this design) interface. Given that PHP has dynamic typing, we need to use type hinting—PHP’s data typing. (See the principle.)

    The Client class does that by adding a getIface() method called by the constructor function. The getIface() method adds a type hint in its parameter so that all objects are recognized as ISubject types. The same client could be used with any call to virtually any version of a Proxy object because it is through the ISubject type. This is a simple yet important little added method to the Client as you can see in the following listing:

    
    include_once("Proxy.php");
    class Client
    {
            private $proxy;
            private $un;
            private $pw;
     
            public function __construct($un,$pw)
            {
                    $this->un=$un;
                    $this->pw=$pw;
                    $this->getIface($this->proxy=new Proxy());
            }
     
            private function getIface(ISubject $proxy)
            {
                            $proxy->login($this->un,$this->pw);
            }
    }
    ?>

    Oftentimes programmers make the mistake of trying to tighten up their code by taking out “unnecessary” code in design patterns. They will take out one operation or another, or even an entire participant. (See Missing Pieces.) In this case, the getIface() method may seem superfluous , but it not only provides a reference to the interface it also provides the call to the Proxy method. So by removing the method, not only is little saved in terms of lines of code, the all important reference to the ISubject is omitted. Loose coupling is essential to good design patterns, and because of type hinting, you can help maintain loosely coupled programs.

    To launch the program, I used a simple trigger file that accepts user data from an HTML file:

    
    ini_set("display_errors","2");
    ERROR_REPORTING(E_ALL);
    include_once("Client.php");
    $un = $_POST['un'];
    $pw = $_POST['pw'];
    $client=new Client($un,$pw);
    ?>

    The HTML5 file is equally standard and quite simple:

    ?View Code HTML
    
    
    
    
    
    Protected Proxy
    
    
    
    Protected Proxy
    User Name

    Password

    Finally, the CSS filed decorates only two elements—body and header:

    @charset "UTF-8";
    /* CSS Document */
    /*705B35,C7B07B,E8D9AC,FFF6D9,570026 */
     
    body
            {
                    font-family:Verdana, Geneva, sans-serif;
                    font-size:12px;
                    color:#705B35;
                    margin-left:20px;
                    background-color:#FFF6D9;
            }
     
    header
            {
                    font-size:18px;
                    font-family:"Arial Black", Gadget, sans-serif;
                    color:#570026;
            }

    All of these files are included in the download along with the PHP code for creating the table and inserting data into the table. However, I encourage you to substitute the RealSubject class with code that reflects what you’d like to place behind a Protection Proxy. All you have to do is to put your own code in the request() method and if you’re using MySQL, change the values in the Subject class to reflect those you’re using. Of course, you don’t have to access data from a database, but you can put in any PHP code you want into the RealSubject request() method.

    As always, your comments are most welcomed.

    Copyright © 2010 William Sanders. All Rights Reserved.

4 Responses to “PHP Proxy Design Pattern: Protect Your Assets”


  • Congratulations, it’s very interesting article. I’ve read your articles about design pattern and are very interesting. I look foward to reading the next.

  • Hi Albert,

    Sorry I haven’t responded until now, but I’ve been busy with different projects I’ve had to take care of. Soon I hope to have lots more for this blog and try to move through all of the PHP design patterns,

    Kindest regards,
    Bill

  • Hi!

    I use the proxy design pattern to control access to the functions of the web application, using ACL ‘s. In order to control every operation you can perform the user.

    In my opinion I think it’s best to use the interface instead of abstract class, because as you say if you get more safety data connection to the database, but if another developer creates a class:

    How do you do to control that actually implements the proxy?

  • Hi Gabriele!

    I like your site!

    Acclamazioni,
    Bill

Leave a Reply