Implementing Factory Methods in PHP 5

If you’ve ever developed desktop applications using mature object-oriented languages like C++ and Java, then it’s possible that you’ve found yourself saying a few funny phrases such as “I need to implement a factory method within this class,” or in the worst case: “this class needs to implement a factory method, but I don’t have a single clue about how to do that.” Surprisingly, you can implement these factory methods pretty quickly and easily in PHP 5, as this six-part series will show you.

To be honest, I grappled with factory methods in Java myself, but in the end I learned not only how to quickly build factory methods in Java classes, but how to implement those methods in PHP as well.

While it’s undeniable that PHP is easier to learn than Java, many PHP developers with long experience in developing procedural programs may find it hard to grasp the foundations of the object-oriented paradigm, to say nothing of the implementation of design patterns that involve the use of objects, such as Singletons or the aforementioned Factory.

Fortunately, building factory methods in PHP is a simple process, which became even simpler with the release of PHP 5. But what is a factory method? In a nutshell, a factory method is a method that fabricates things and returns them when possible to client code.

In most cases, these things are objects, but they don’t have to be. However, by far the most important facet of factory methods is their ability to create objects, which means that they play a relevant role when building object-oriented web programs, and therefore deserve a closer look.

So, given the importance of factory methods to developing web applications, in this group of tutorials I’m going to show how to implement this kind of method in PHP 5. I’ll start with some basic code samples, and then, with the key concepts already digested, I’ll go into more complex examples that will combine the use of Singletons and static methods.

Now, it’s time to start learning how to define a few simple factory methods with PHP 5. It’s going to be an instructive journey, trust me!

{mospagebreak title=The simplest object constructor}

In the introduction, I explained that a factory method is in most cases responsible for creating objects that are returned to client code. Of course, this concept is true, but it doesn’t reflect the full reality of the factoring process. The most basic way to spawn objects in PHP 5 is by means of the “new” keyword.

Actually, “new” is a language construct and not a method, but since it’s mandatory to use it for creating instances of classes, it’s worth spending a few moments looking at it. But, wait a minute! What about constructors? Well, because of their suggestive name, you might think that these are the ones that really take care of creating objects, which is a wrong, misleading concept.

When implemented, constructors are only methods called after object creation that quite often perform some useful initialization tasks. They don’t create any objects automatically, however, unless they contain the logic required to do that. Without diving into the depths of the C language, which as you know is the driving force behind PHP, it is necessary to understand that the “new” construct is used to create class instances, and then, if a constructor method has been defined in the originating class, the program flow will be delegated to this particular method. It’s that simple, really.

However, to clarify the difference between the “new” construct and a constructor method, below I defined a simple class that reads from and writes data to a target file, which looks like this:

class FileProcessor

{

private $fileName = ‘dafault.txt';

private $data = ‘Sample data';

 

// implemented constructor

public function __construct($data = ”, $fileName = ”)

{

if ($data != ”)

{

$this->data = $data;

}

if ($fileName != ”)

{

$this->fileName = $fileName;

}

}

 

// read data from target file

public function read()

{

return file_get_contents($this->fileName);

}

 

// write data to target file

public function write()

{

file_put_contents($this->fileName, $this->data);

}

}

As seen above, understanding how this example class works isn’t brain surgery. It defines two main methods, called “read()” and “write()” respectively, where the first obviously fetches data from a specified text file, and the second one puts this data into that targeted file.

The most important detail to notice here, though, is that the class implements its constructor, which simply assigns new values to the $data and $fileName properties. So far, there’s nothing special about this method, except that it demonstrates the actual role it plays when an instance of the “FileProcessor” class is created. Consider the following script:

$fileProc = new FileProcessor(‘This string will be saved to the target file’);

// write data to target file

$fileProc->write();

// read and display data from target file

echo $fileProc->read();

In this example, after a new file processor object has been created via the “new” keyword, the constructor is called with an incoming argument. However, as I said before, this method doesn’t build any objects; it only performs the assignment process shown before.

Taking the example a bit further, it would be perfectly possible to create a file processor object using the default values assigned to its properties, even if the originating class were defined as follows:

class FileProcessor

{

private $fileName = ‘dafault.txt';

private $data = ‘Sample data';

 

// read data from target file

public function read()

{

return file_get_contents($this->fileName);

}

 

// write data to target file

public function write()

{

file_put_contents($this->fileName, $this->data);

}

}

 

// create new file processor object

$fileProc = new FileProcessor();

// write data to target file

$fileProc->write();

// read and display data from target file

echo $fileProc->read();

There you have it. The above code sample demonstrates in a nutshell that the $fileProc object always gets created, even when no constructor method exists. While this example may look rather primitive at first sight, it shows the differences between using the “new” construct and implementing class constructors.

So far, so good. At this point, I took a quick look at the simplest way to create factory objects in PHP, via the corresponding “new” keyword, a process that  you’ve surely grasped in a snap. Therefore, it’s time to start explaining how to build real factory methods within classes.

However, this topic will be covered in the section to come. So, click on the link below and read the next few lines.

{mospagebreak title=Defining factory methods}

To demonstrate how to implement a simple factory method in PHP 5, I’m going to define a basic class, which will be charged with returning to client code a few basic web form element objects. For this concrete example, these objects will be capable of generating all the HTML markup required for rendering input text boxes and text areas.

So, here are the definitions of the classes that are the blueprints for the mentioned web form element objects:

// define TextBox class

class TextBox

{

private $name = ‘mytextbox';

private $id = ‘textbox';

private $class = ‘textbox';

private $maxlength = 20;

 

// constructor

public function __construct($attributes = array())

{

if (empty($attributes) === FALSE)

{

foreach ($attributes as $attribute => $value)

{

if (in_array($attribute, array(‘name’, ‘id’, ‘class’, ‘maxlength’)) and empty($value) === FALSE)

{

$this->$attribute = $value;

}

}

}

}

 

// renders input text box element

public function render()

{

return ‘<input type="text" name="’ . $this->name . ‘" id="’ . $this->id . ‘" class="’ . $this->class . ‘" maxlength="’ . $this->maxlength . ‘" />';

}

}

 

 

// define TextArea class

class TextArea

{

private $name = ‘mytextarea';

private $id = ‘textarea';

private $class = ‘textarea';

private $rows = 10;

private $cols = 20;

 

// constructor

public function __construct($attributes = array())

{

if (empty($attributes) === FALSE)

{

foreach ($attributes as $attribute => $value)

{

if (in_array($attribute, array(‘name’, ‘id’, ‘class’, ‘rows’, ‘cols’)) and empty($value) === FALSE)

{

$this->$attribute = $value;

}

}

}

}

 

// renders textarea element

public function render()

{

return ‘<textarea name="’ . $this->name . ‘" id="’ . $this->id . ‘" class="’ . $this->class . ‘" rows="’ . $this->rows . ‘" cols="’ . $this->cols . ‘"></textarea>';

}

}

As I mentioned before, the two sample classes shown above simply construct HTML input boxes and text areas, via their respective “render()” methods. On the other hand, their constructors act like simple setters for the attributes that will be appended to these web form elements.

Now that you’ve grasped how the previous classes function, it’s time to define the class responsible for creating form element objects. As you’ll see in a moment, this brand new class implements a method called “factory.” Its definition looks like this:

// define FormElementFactory class

class FormElementFactory

{

public function factory($formElement, $attributes = array())

{

if ($formElement === ‘textbox’ or $formElement === ‘textarea’)

{

return new $formElement($attributes);

}

}

}

Certainly, there’s not much to be said about the above “FormElementFactory” class, except that it uses its factory method to create only two specific form element objects, text boxes and text areas. However, this is a great breakthrough, since it’s a simple example that shows how to define a factory method in PHP 5.

If you ever though this was a difficult process, then you should take a deep breath and relax, because in reality it’s simple. But, if you’re like me, then you’ll want to see how the previous factory class can be used to display an input box and a text area on the browser.

This procedure will wrap up this introductory tutorial of the series. To learn more about it, go ahead and read the last segment.

{mospagebreak title=Factoring web form element objects}

Undoubtedly, the best way to understand how the previous form element factory class works is by looking at an example. So, with that idea in mind, below I coded a small script that first spawns two form element objects, and then calls the "render()” method of these objects to display the corresponding HTML elements on screen. Take a look: 

 

$formFactory = new FormElementFactory();

// create some form elements objects

$texBox = $formFactory->factory(‘textbox’);

$textArea = $formFactory->factory(‘textarea’);

// display form elements

echo $texBox->render() . ‘<br />’ . $textArea->render();

This basic example shows how easy it is to define a factory method in PHP 5, which in this particular case builds a couple of web form element objects. But, before I hear your loud complaints, it’s important to note that the use of the factory method and its originating class is rather poor, since an instance of this class has been previously created, which is completely unnecessary.

However, this issue will be partially addressed in the next part of the series. So, for the moment feel free to edit all of the code samples included in this tutorial, which will help you build a more solid background in defining factory methods in PHP 5.

Final thoughts

In this introductory installment of the series, I provided you with a quick overview of implementing factory methods with PHP 5. In this specific case, I went through the development of a basic factory class, which was tasked with creating web form element objects, thus making it much easier to generate HTML forms in a dynamic way.

However, as you may have noticed, this factory class has a serious drawback. It calls its “factory” method in the object context, which means that an instance of the class was previously created. This instantiation process isn’t necessary at all, since the purpose of the class was to build form element objects, without dealing with its own instances.

Thus, in the next part of the series I’m going to modify the definition of this factory class so it can return only singletons to client code.

Don’t miss the upcoming tutorial!

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort