Monthly Archive for July, 2013

OOP PHP IV: Property and Method Visibility

oop4Can We Talk?

Because OOP helps structure PHP programs into practical modules for re-use and change, the ability of each module to communicate with another module or set of modules is key to creating a successful OOP program. For example, your client class that makes requests must have some way of communicating with the target of its request. To instantiate an instance of a class when making a request, the new statement creates an object (instance) of that class. (That’s one reason constructor functions are all set to public by design. Even if you do not include a constructor function in a class one is automatically included.)

However, you do not want every object communicating with every other object in an OOP application. Consider, for example, a Web design and development company. You may not want your programmers sending directives to your design or UX people. (e.g., Let’s put an animated PacMan on every page.) or your design people telling your programmers what to do (e.g. The colors of your source code listings are all wrong. Change them to pastels.) However, you do want the head of your development team to communicate with the head of your design team to coordinate design and development. It’s the same with OOP programs; you want to organize the flow of communication between objects to avoid tangles and unexpected consequences.

A Double Feature

This will be a two-part post because those videos can get long quick! Here’s Part I on Visibility:

To find out a little more about visibility, this next video shows some OOP programs using different types of visibility and how they can be accessed.

It will probably help if you take a minute and download the example files. You should be able to put the programs in your favorite IDE and watch the video. That’ll probably give you a clear idea of how visibility works in different contexts.
Download
If you have any feedback about the videos or blog, please feel free to use the comments. Like to hear from you.

Design Patterns, Scope, Globals and Superglobals in PHP

localGlobalThe Problem with Globals

Earlier this summer I completed a course through Rice University on Python. It was an introduction to making games with Python, and the four professors who taught it, did so brilliantly. One of the nagging issues that came up early was the use of global variables. In a clear explanation of the difference between local and global variables, virtually identical to PHP, we went through several game development exercises. At the very end of the class, however, we were admonished not to use global variables.

Online, you will find plenty of reasons to avoid globals in every computer language, but the main reason is one of maintainability. Because globals are accessible to all functions, their state can be changed by all functions. As a result, you may get unexpected outcomes that can be very difficult to track down, especially in larger programs. It’s like having a wild hare running through your program.

Encapsulation and Global Variables

Let’s start off with a simple example of global troubles. The following two programs represent sequential/procedural listings with a global.

Simple Global


$gvar = "Hello everyone!";
function showOff()
{
    echo $GLOBALS['gvar'];
}
showOff();
?>

Global With Changes


$gvar = "Hello everyone!";
function showOff()
{
    echo $GLOBALS['gvar'];
}
function fixUp()
{
    $GLOBALS['gvar']="If it weren't for treats, dogs would rule the world.";
}
fixUp();
showOff();
?>

The ouput is wholly different for these two programs when the function showOff() is called:

  • Hello everyone!
  • If it weren’t for treats, dogs would rule the world.

As programs grow in size and complexity, the problem of globals grows proportionately. (If multiple programmers are involved, the problem grows exponentially!).

Now let’s look at the same issue in a class with a global variable.


class Alpha
{
    public $gvar = "Hello everyone!";
 
    public function __construct()
    {
        echo $GLOBALS['gvar'];
    }
}
$worker1 = new Alpha();

It throws an error:

    Notice: Undefined index: gvar in ….

Rather than trying to find a clever way to get globals into classes, using either the keyword global or the associative array $GLOBALS, let’s just say that a focus on visibility in classes will better serve further discussion of global scope when it comes to OOP encapsulation. (Visibility will be discussed in an upcoming post.)

Local Variables in Classes and Methods

Local variables work with methods in the same way as they do in unstructured functions. The locality of the variable does not matter in terms of return to a call or request. As with all other visibility, that depends on the method. The following example shows a local variable named $local in multiple methods with different content and different visibility. The Client class has a local variable in the constructor function, $runner. The following listing shows a request from within a class and by an external client.


ini_set("display_errors","1");
ERROR_REPORTING( E_ALL | E_STRICT );
 
class LocalReport
{  
    public function __construct()
    {
        echo $this->showOff1() . "
"
; echo $this->showOff2() . "
"
; } private function showOff1() { $local = "All good things come to pass."; return $local; }   private function showOff2() { $local = "Fatal assumptions: He will change; she won't change."; return $local; }   public function showOff3() { $local = "We serve the public (visibility)!"; return $local; }   }   class Client { public function __construct() { $runner=new LocalReport(); echo $runner->showOff3(); } }   $worker = new Client(); ?>

The output is:

    All good things come to pass.
    Fatal assumptions: He will change; she won’t change.
    We serve the public (visibility)!

Whether to use local variables or class properties in OOP development depends on the purpose of the application under development. I tend to go for private properties to better insure encapsulation, but local variables can be handy in certain types of implementations. In either case, neither is subject to the problems associated with global variables.
superglobalman250
Superglobals

Superglobals in PHP are automatic predefined global variables available in all scopes throughout a script. Most PHP developers are familiar with $_GET and $_POST, but other superglobals such as $_COOKIE, $_SESSION and $_SERVER are commonly used as well. Elsewhere on this blog, injection attacks through superglobals have been discussed, but here I want to look at the relationship between OOP/Design Patterns and superglobals.

To get a good idea of the “superness” of superglobals, consider a typical OOP program where the requesting class is a client. It calls a class that uses a superglobal. Also, to acknowledge Brazil’s 2014 World Cup hosting, and the publication of Learning PHP Design Patterns in Portuguese (Padrões de Projeto em PHP), I thought I’d create the UI in Portuguese as shown in Figure 1:

Figure 1: Data input module

Figure 1: Data input module

The HTML data entry is a simple one, asking for the user’s favorite team and favorite sport. They are saved in the super global elements, ‘team’ and ‘sport’ and then sent off using the post method. The following HTML code was used:

DataEntry.html

?View Code HTML



    
    
    Data Entry

 

    

Exame dos Esportes

Dê entrada com o nome da equipe e do esporte em umas caixas de texto apropriadas:

Equipe de esportes favorita
Esporte favorito

You’ll have to excuse my poor Portuguese. In English it asks to enter your favorite team and sport. (As a long-suffering Chargers fan, you can see the sample entry in Figure 1.) Also, it needs some CSS, lest you think me a total savage:

brazil.css

@charset "UTF-8";
/* CSS Document */
/* 06794e (green), f8d902 (yellow), 1b3c83 (blue), ffffff */
body
{
        font-family:Verdana, Geneva, sans-serif;
        color:#06794e;
        background-color: #f8d902;
}
h2
{
        font-family: "Kilroy WF", "Arial Black", Geneva, sans-serif;
        color: #ffffff;
        background-color: #1b3c83;
        text-align: center;
 
}
img
{
        display: block;
        margin-left: auto;
        margin-right: auto;
}

The client class (SuperClient) is little more than a trigger to call a class to process the superglobals. However, the client has no superglobals itself. This is significant in that SuperClient.php is called by the HTML document (DataEntry.html).

SuperClient.php


include_once('SuperGlobal.php');
 
class SuperClient
{  
    private $superGlobal;
 
    public function __construct()
    {
        $this->superGlobal = new SuperGlobal();
    }
}
$worker=new SuperClient();
?>

So the question is,

Will the super global $_POST be accessible to the SuperGlobal class called by the client?

Let’s see.

SuperGlobal.php


class SuperGlobal
{  
    private $favoriteTeam;
    private $favoriteSport;
 
    public function __construct()
    {
        $this->favoriteTeam = $_POST['team'];
        $this->favoriteSport = $_POST['sport'];
        echo "Minha equipe favorita é $this->favoriteTeam. 
"
; echo "Meu esporte favorito é $this->favoriteSport.
"
; } } ?>

When you run the program, your output will look something like the following:

    Minha equipe favorita é Chargers.
    Meu esporte favorito é football.

That shows that a superglobal can be accessed from even the most encapsulated environment. In the sense that the HTML Document called the SuperClient and yet the superglobals were available in the SuperGlobal object should tell you (and show you) that once launched from an HTML document a superglobal can be accessed from any PHP file communicating directly or indirectly with the originating HTML document.

Can Superglobals Cause Global Trouble?

For superglobals to be a problem, they need to change unexpectedly within a program.

So the first question, we need to ask is, Can superglobals be changed once they are sent from an HTML document?

We showed that superglobals can get inside an encapsulated object, but can they be changed or do they maintain the values set by the HTML document? The following is a test to find out. With a slight change to the SuperGlobal class and a couple more objects, we can find out.

Step 1: Change the SuperGlobal class to the following:

SuperGlobal.php


//Include new class
include_once('GlobalChanger.php');
 
class SuperGlobal
{  
    private $favoriteTeam;
    private $favoriteSport;
 
    public function __construct()
    {
        $this->favoriteTeam = $_POST['team'];
        $this->favoriteSport = $_POST['sport'];
        echo "Minha equipe favorita é $this->favoriteTeam. 
"
; echo "Meu esporte favorito é $this->favoriteSport.
"
;   //Add a new line $caller = new GlobalChanger(); } } ?>

Step 2: We need a class to change the values of the superglobals and call another object to display the changes in the same super global.

My friend Sudhir Kumar at PandaWeb.in from Chennai, India is a cricket fan; so I decided to use his favorite team and sport to replace whatever team and sport is entered.

GlobalChanger.php


include_once('SuperChanged.php');
 
class GlobalChanger
{   
    public function __construct()
    {
        $_POST['team']="Team India";
        $_POST['sport']= "cricket";
        $caller = new SuperChanged();
    }  
}
?>

Step 3: Finally, we need to see if the new team and sport has been changed in the application.

SuperChanged.php


class SuperChanged
{  
    private $newTeam;
    private $newSport;
 
    public function __construct()
    {
        $this->newTeam=$_POST['team'];
        $this->newSport=$_POST['sport'];
 
        echo "
Now my favorite team is $this->newTeam.
"
; echo "And my very favorite sport is $this->newSport.
"
; } } ?>

Starting with the same html document initially used, we can now see that indeed the superglobal values have been changed, and they are quite available throughout the program.

    Minha equipe favorita é Chargers.
    Meu esporte favorito é football.

    Now my favorite team is Team India.
    And my very favorite sport is cricket.

As you can see, the GlobalChanger object changed the original values. Furthermore, it is clear that we were using the same superglobal array in the SuperChanged class when the $_POST values were passed to private variables and displayed using the echo statement.

Obviously, a PHP programmer cannot simply drop superglobals. Further, even though we can change their values, that doesn’t mean we should change them or even have an occasion to do so. But, we need to be aware of the problems with global variables. After all, superglobals are global variables, even in an encapsulated environment.

Conclusion

Two important points need to be emphasized here:

  1. Don’t use global variables.
  2. Where you have to use superglobals, don’t change their values dynamically in PHP.

Like everything else in programming there are exceptions, but remember that globals, while having a purpose, often loose that purpose in OOP programs and structured design patterns. When using superglobals, keep in mind that they are true globals and they can be changed, but only if the developer assigns them different values after they’ve been assigned values in HTML. As true globals, they can cause the same kinds of problems that any other globals can. So treat them more like constants, and let their originally assigned values from the HTML form stay put.

OOP PHP III: Properties and Variables

oop3From Variable to Class Property

All classes in all programming languages are made up of two fundamental elements, 1) Methods and 2) Properties. In this installation of learning OOP in PHP, I want to look at properties.

To understand properties in a PHP class, it’s important to understand (at this stage) that we’re dealing with variables. Variables inside of a class can act as properties of that class or properties of a method within a class. In OOP, we speak of visibility of variables/properties. You will find an earlier post on this blog that explains private variables in detail, and future posts delve into visibility in greater detail. For now variables in PHP (and virtually every other programming language) have two basic types:

  • local
  • global

Generally speaking any variable declared outside of a function in a sequential or procedural listing is global, and any variable declared inside of a function is local. The same is true to some extent in OOP programming, but variables (or properties) require a different sense. Take a look at the video, and you’ll see the basics of variables within classes.

The video touches on the most fundamental aspects of variables and properties. However, as every PHP programmer knows, there’s no substitute for some clear practical OOP PHP code. The following examples show several different aspects of creating and using variables and properties.

All of these examples use a Client->Request->Class model. The first is similar to the one in the video except it has a client make the request:
Client 1
Client1


//Client1.php
include_once('OneProp.php');
class Client1
{
 
        public function __construct()
        {
            //$oneProp is a local variable
            $oneProp = new OneProp();
            echo $oneProp->showProperties();
        }
}
//$worker is a global variable in this program
$worker = new Client1();
?>

OneProp


//OneProp.php
class OneProp
{
        private $magicWord;
 
        public function showProperties()
        {
            $this->magicWord = "

Alacazam!

"
; return $this->magicWord; } } ?>

More Properties and a Little JavaScript inside PHP Class

This last example is a little more involved. One of the properties is assigned an entire Web page using heredoc. Two more properties serve as labels and instructions. Here we use a little JavaScript, and the JavaScript event handler (onClick) uses the this statement and property reference using a dot:

this.src

Because the JavaScript is part of a heredoc string in a PHP property ($this->document), PHP does not attempt to execute the JavaScript or find an error in its format. (In other words it doesn’t throw an error when this.src appears instead of $this->src is in the JavaScript listing.)

Client2


include_once('ImageSwap.php');
class Client2
{
        private $light;
        public function __construct()
        {
            $light = new ImageSwap();
        }
}
$worker = new Client2();
?>

ImageSwap


//ImageSwap.php
ini_set("display_errors","1");
ERROR_REPORTING( E_ALL | E_STRICT );
class ImageSwap
{
    private $document;
    private $turnOff;
    private $howTo;
 
    public function __construct()
    {
        $this->document = <<
        
        
        
        
        Light Switch
        
        
        
        
        
LIGHTSWITCH;
        $this->turnOff = "

Turn off the light!

"
; $this->howTo = "

(Just click the image!)

"
;   echo $this->turnOff; echo $this->document; echo $this->howTo; } } ?>

To run this, you’ll need to download the following two graphic files:
onoff

Put the two graphic files into the same directory as the classes you’ll be using. Notice how the three different properties in the ImageSwap class are employed. Also note that in the two Client classes, the $worker variable (not a property because it does not belong to a class) is assigned an object. To download the two graphic files, just right click to download them and then move them to the same directory (folder) with your ImageSwap.php file. In the next installment of OOP PHP, we’ll look at the visibility that properties and methods can have and how to use them.

Padrões de Projeto em PHP

Para nossos amigos em Brasil e em Portugal que são os melhores programadores do mundo!

portuguese

O principal evento de PHP da América Latina
Conferência do PHP de novembro em Brasil. Não o falte.

PHP CMS Project Part V: The Factory Method

cms5A Simple Factory Method CMS

In deciding which design pattern to apply to this CMS, two came to mind. Because PHP is creating a Web page, creational patterns appeared to be the most appropriate. Both the Factory Method and the Abstract Factory were considered. The Factory Method is the simplest of the two and it can be expanded, and so I settled on it. The Abstract Factory would be more appropriate if the main goal was to select different Web page styles. This CMS is to update and use data from a MySQL table. Since a lot of files make up this CMS, it’s probably a good idea to download them first:
Download

To get started, take a look at Figure 1. In Part IV of this series you saw how to put data into and retrieve it from a database and use in a Web page. That is pretty much what has been done here except the request is through the Creator interface to insure loose coupling. The PageCreator implements the factoryMethod() method which creates a requested product specified by the Client. As a result the Client is only loosely bound to the concrete product it requests.

Figure 1: File Diagram for Factory Method CMS

Figure 1: File Diagram for Factory Method CMS

When the concrete creator object (PageCreator) passes the request for the concrete Product object (PageProduct1()), it does so through the deliverWeb() method—the method implemented through the Product interface.

Multiple Inheritance (Sort of)

Some languages like Java and Python support multiple inheritance. Strictly speaking, PHP does not, but you will find workarounds and you can combine inheritance and implementation in a single child class. In the declaration of the PageProduct1 class, you can see how this is done:


include_once('UniversalConnect.php');
include_once('Product.php');
include_once('ProductTools.php');
class PageProduct1 extends ProductTools implements Product
{
    function deliverWeb()
    {      
        $this->tableMaster="blogette";
        $this->hookup=UniversalConnect::doConnect();
        $this->loadContent();
        $this->content = array("css" => $this->css,
                         "title" => $this->title,
                         "header1" => $this->header1,
                         "header2" => $this->header2,
                         "body1" => $this->body1,
                         "body2" => $this->body2,
                         "image1" => $this->image1,
                         "image2" => $this->image2,
                         "caption1" => $this->caption1,
                         "caption2" => $this->caption2
                         );   
        return $this->content;
    }
 
    private function loadContent()
    {
        //Create Query Statement
        $this->sql ="SELECT * FROM $this->tableMaster WHERE id = 1";
 
        if ($result = $this->hookup->query($this->sql))
        {
            while ($row = $result->fetch_assoc()) 
            {
                $this->css = $row['css'];
                $this->title = $row['title'];
                $this->header1 = $row['header1'];
                $this->header2 = $row['header2'];
                $this->body1 = $row['body1'] . "

"; $this->body2 = $row['body2'] . "

"; $this->image1 = "images/" . $row['image1']; $this->image2 = "images/" . $row['image2']; $this->caption1 = $row['caption1']; $this->caption2 = $row['caption2']; } $result->close(); } $this->hookup->close(); } } ?>

The declaration line:

class PageProduct1 extends ProductTools implements Product

imbues PageProduct1 with both the properties of the ProductTools and the interface of the Product. By having the abstract class ProductTools provide the essential properties of a Product child, the properties need not be declared in the concrete product child classes and add some uniformity. At the same time the Product child implementations have the common Product interface. If you’re thinking that a single abstract class could have handled both the method and the properties, you’d be right. However, but having a separate class for properties, the same design could easily be adapted to include a whole new set of properties if need be.

You probably recognize PageProduct1 as the RetrieveBlog class from Part IV of the CMS series. About the only difference is that I created an abstract class ProductTools to store common product properties for use by any other product classes that the developer may care to add. It reduces clutter and makes it easier to make small changes. For example, one strategy considered is to create several different instances of PageProduct1, such as PageProduct2, PageProduct3 and so on. Each could simply identify a different table ID number to be called from the Client class. On the other hand, new data could be added simply by using an UPDATE SQL command to change the content of the record with an ID selected by the class.

Figure 2 shows an added page delivered as a concrete product upon a Client request, and as you can see, it looks just like the others in this series, but the content has changed:

Figure 2: Page created with Factory Method CMS

Figure 2: Page created with Factory Method CMS

The nature of the page has not changed, but the way in which it is requested has. The request is through the Creator interface; so next we’ll take a look at the concrete creator class and the new Client class.

Request to the Creator

The real “un-coupler” participant in the Factory Method design pattern is the Creator and its implementations. In this instance, the single concrete class passes on the request from the Client for a Product. In the following listing are both the Creator abstract class and its child class, PageCreator: (Note: Product type hinting is used so that additional concrete product implementations may be called through the same interface. This is an example of the design pattern principle of program to the interface (Product) and not the implementation (PageProduct1).


//Creator.php
abstract class Creator
{
        protected $webProduct;
        abstract public function factoryMethod(Product $pageNow);
}
?>
 
?php
//ConcreteCreator.php
include_once('Creator.php');
 
class PageCreator extends Creator
{
        public function factoryMethod(Product $pageNow)
        {
                $this->webProduct=new $pageNow();
                return($this->webProduct->deliverWeb());
        }
}
?>

At this point, you may wonder where the content of the $pageNow parameter comes from. In this case, and all along in this series actually, the Web page has been the client. It is requesting content for the HEREDOC page. So, we might as well put it where it belongs—in the Client class as shown:

hd["image2"]}>
  CMSTEMPLATE;echo$this->document;}}$worker=new Client();?>

include_once('PageProduct1.php');
include_once('PageCreator.php');
 
class Client
{
    private $content;
    private $document;
    private $hd;
 
    function __construct()
    {
        $this->content=new PageCreator();
        $this->hd = $this->content->factoryMethod(new PageProduct1());
        $this->document = <<
        
        
        hd["css"]}>
        
        {$this->hd["title"]}
        
        
        

{$this->hd["header1"]}

{$this->hd["header2"]}

{$this->hd["body1"]} {$this->hd["body2"]}
hd["image1"]}>

{$this->hd["caption1"]}

{$this->hd["caption2"]}

The two lines in the Client that show it to be part of a Factory Method design pattern are:

$this->content=new PageCreator();
$this->hd = $this->content->factoryMethod(new PageProduct1());

The Client makes the request through the PageCreator class and then invokes the factoryMethod() to specify the product, PageProduct1. Now suppose later that you want to make more products—implementations of the Product interface. Because the request in the Creator specifies through type hinting is for the Product and not any specific implementation of the Product interface, it can handle any Product implementation.

You may want to review other implementations of the Factory Method on this blog for a review in understanding how everything works together. However, it comes down to Request -> Creator -> Product.

The CMS Co-Stars

In wrapping up this series on creating a CMS using a design pattern in PHP, you will find a folder full of some of the tools you’ll need for creating and maintaining the system in a folder named “Administrative.” At some point soon, I hope to implement it for the http://www.sandlight.com site, and I’d be very interested in what others have done or ideas for making it better. In the meantime enjoy exploring its possibilities.