Iterator Pattern in Zend Framework

The Iterator design pattern has provided a common mechanism for accessing collections. It allow user to traversal, access, and manipulate data sets, such as array, files, RSS feeds and database result sets etc., in the same way.

 

One of the progresses which php5 compare to php4 is that it encapsulates a variety of iterator interface. It’s just so easy to implements the iterator in php5.

 

There are plenty of examples that implement the iterator in Zend Framework. Now let’s take Zend_Feed for example :

 

 

The source code below is simplified and first of all is Zend_Feed_Element : 

 

[codesyntax lang=”php”]

/**
* Zend_Feed_Element for encapsulating DOMElement
*/

class Zend_Feed_Element implements ArrayAccess
{
// @var DOMElement DOM object
protected $_element;
// Zend_Feed_Element construct
public function __construct($element = null)
{
$this->_element = $element;
}
// ......
/**
* ArrayAccess interface function
* Check element exists or not
*/

public function offsetExists($offset)
{
// ......
return $this->_element->hasAttribute($offset);
}
/**
* ArrayAccess interface function
* Return attribute of element
*/

public function offsetGet($offset)
{
// ......
return $this->_element->getAttribute($offset);
}
/**
* ArrayAccess interface function
* Return the value of element
*/

public function offsetSet($offset, $value)
{
// ......
return $this->_element->setAttribute($offset, $value);
}
/**
* ArrayAccess interface function
* Unset the attribute of element
*/

public function offsetUnset($offset)
{
// ......
return $this->_element->removeAttribute($offset);
}
// ......
}

[/codesyntax]

 

We notice that Zend_Feed_Element has implemented ArrayAccess interface which means we can maniplate Zend_Feed_Element and its children as array.

 

Then is abstract parent Zend_Feed_Abstract : 

 

[codesyntax lang=”php”]

require_once 'Zend/Feed/Element.php';

/**
* Zend_Feed_Abstract the abstract parent for feeds
* It has implemented two core interfaces from php5 : ArrayAccess and Iterator
*/

abstract class Zend_Feed_Abstract extends Zend_Feed_Element implements Iterator
{
/**
* Index of current entries
* It's used for iterator
* @var integer
*/

protected $_entryIndex = 0;
/**
* Entries data sets
* @var array
*/

protected $_entries;
// ......
// Iterator interface method, rewind index
public function rewind()
{
$this->_entryIndex = 0;
}
// Iterator interface method, return current entry
public function current()
{
return new $this->_entryClassName(
null,
$this->_entries[$this->_entryIndex]);
}
// Iterator interface method, return index of current entry
public function key()
{
return $this->_entryIndex;
}
// Iterator interface method, set next index
public function next()
{
++$this->_entryIndex;
}
// Iterator interface method, validate the current index
public function valid()
{
return 0 <= $this->_entryIndex && $this->_entryIndex < $this->count();
}
// ......
}

[/codesyntax]

 

Zend_Feed_Abstract has implemented ArrayAccess and Iterator interface, which means we can now access the data sets inherited from Zend_Feed_Abstract just like accessing array.

 

Here are two children, Zend_Feed_Rss and Zend_Feed_Atom :

 

[codesyntax lang=”php”]

require_once 'Zend/Feed/Abstract.php';

class Zend_Feed_Rss extends Zend_Feed_Abstract
{
    // ......
}

class Zend_Feed_Atom extends Zend_Feed_Abstract
{
    // ......
}

[/codesyntax]

 

Examples of how they act :

 

[codesyntax lang=”php”]

$channel = new Zend_Feed_Rss('http://rss.example.com/channelName');
foreach ($channel as $item) {
    echo 'Title: ' . $item->title() . "n";
}

$feed = new Zend_Feed_Atom('http://atom.example.com/feed/');
foreach ($feed as $entry) {
    echo 'Title: ' . $entry->title() . "n";
}

[/codesyntax]

 

The Iterator has provided a common and unified method for accessing data sets in our applications. It abstracts out the concept of accessing data collections and transparents these kind of operations to users.

 

Thanks to iterator, we can focus on business logic and improve the efficiency of development.

 

Posted in Design Patterns | Tagged , | 1 Comment

Strategy Pattern in Zend Framework

In the traditional process-oriented languages are often filled with a lot of if/else statements. This situation has easily made the logic of chaos and trouble to amend. The strategy design pattern was borned to solve this kind of problems.

 

When we face a problem which got serveral solution strategies, we can use the strategy pattern. Its main idea is to provide a unified and fixed interface for all strategy subclasses, for example, a parent class. And then we just use this interface to define each strategy we want.

 

Now let’s take a look at how Zend_Application_Resource_Resource implements the strategy pattern.

 

 

The following are simplified source code and first of all, is a unified interface : 

 

[codesyntax lang=”php”]

<?php
/**
* bootstrap resources : unified interface
*/

interface Zend_Application_Resource_Resource
{
// Constructor
public function __construct($options = null);
// Other functions
public function setBootstrap(Zend_Application_Bootstrap_Bootstrapper $bootstrap);
public function getBootstrap();
public function setOptions(array $options);
public function getOptions();
/**
* Strategy pattern : init() method
* @return mixed
*/

public function init();
}

[/codesyntax]

 

Then the parent Zend_Application_Resource_ResourceAbstract

 

[codesyntax lang=”php”]

<?php
/**
* @see Zend_Application_Resource_Resource
*/

require_once 'Zend/Application/Resource/Resource.php';
/**
* Parent : Resource
* @uses Zend_Application_Resource_Resource
*/

abstract class Zend_Application_Resource_ResourceAbstract implements Zend_Application_Resource_Resource
{
// Implements interface methods
public function __construct($options = null)
{
// ......
}
public function setOptions(array $options)
{
//......
return $this;
}
public function getOptions()
{
// ......
}
public function setBootstrap(Zend_Application_Bootstrap_Bootstrapper $bootstrap)
{
// ......
return $this;
}
public function getBootstrap()
{
// ......
}
// ......
// init() is left for subclasses to implement
}

[/codesyntax]

 

We haven’t implemented the init() function within parent, but also because the parent is defined as abstract, we can only to subclass for the realization of its init() function. In this case we can make the use of resources properly. Here are two examples about the Layout and the View.

 

Zend_Application_Resource_Layout :

 

[codesyntax lang=”php”]

<?php
/**
* Layout resource : Zend_Application_Resource_Layout
* @uses Zend_Application_Resource_ResourceAbstract
*/

class Zend_Application_Resource_Layout
extends Zend_Application_Resource_ResourceAbstract
{
// @var Zend_Layout
protected $_layout;
/**
* Defined in Zend_Application_Resource_Resource
* @return Zend_Layout
*/

public function init()
{
$this->getBootstrap()->bootstrap('FrontController');
return $this->getLayout();
}
/**
* Get the layout object
* @return Zend_Layout
*/

public function getLayout()
{
if (null === $this->_layout) {
$this->_layout = Zend_Layout::startMvc($this->getOptions());
}
return $this->_layout;
}
}

[/codesyntax]

 

Zend_Application_Resource_View : 

 

[codesyntax lang=”php”]

<?php
/**
* View resource : Zend_Application_Resource_View
* @uses Zend_Application_Resource_ResourceAbstract
*/

class Zend_Application_Resource_View
extends Zend_Application_Resource_ResourceAbstract
{
// @var Zend_View_Interface
protected $_view;
/**
* Defined in Zend_Application_Resource_Resource
* @return Zend_View
*/

public function init()
{
$view = $this->getView();
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
return $view;
}
/**
* Get the view object
* @return Zend_View
*/

public function getView()
{
if (null === $this->_view) {
$this->_view = new Zend_View($this->getOptions());
}
return $this->_view;
}
}

[/codesyntax]

 

It’s Zend_Application_Bootstrap_Bootstrap who make the really call of init(). It is responsible to collect all the resources and the implementation of their initialization function init() : 

 

[codesyntax lang=”php”]

<?php
/**
* Zend_Application_Bootstrap_Bootstrap::_executeResource($resource)
* Execute one resource
*/

protected function _executeResource($resource)
{
// ......
if ($this->hasPluginResource($resource)) {
// ......
$plugin = $this->getPluginResource($resource);
$return = $plugin->init();
// ......
}
}

[/codesyntax]

 

This is how Zend_Application_Bootstrap_Bootstrap use resouces and the solution of resources initialization. At the same time, we can create our own resouces very easily through the common interface provided by Zend_Application_Resource_ResourceAbstract.

 

In fact, large-scale use of strategy pattern has been found in Zend Framework including : Zend_Controller_Action_Helper, Zend_View_Helper, Zend_Filter etc.

 

Posted in Design Patterns | Tagged , | Leave a comment

PHP Coding Standards – Preview

Zend had provided the guidelines for developers and teams working on or with Zend Framework.

 

Details posted on : http://framework.zend.com/wiki/display/ZFDEV/Zend+Framework+Contributor+Guide.

 

Within the guidelines we can see 2 subjects for coding standards :

 

No.4 PHP Coding Standard (draft) – It’s the basic php coding standards for developers.

 

No.10 ZF Coding Standards (RC) – It’s the supplementary of No.4 which is the coding standards for those who working on Zend Framework.

 

What we see in appendix B from manual is exactly No.4.

 

And here, I will give you a deep explanation of No.10 ZF Coding Standards (RC) together with No.4 in five chapters.

 

PS : you had better read PEAR Coding Standards first before continue.

 

Posted in Coding Standards | Tagged , | Leave a comment

Basic of Dojo

We can import the package of dojo toolkit everytime and everywhere using CDN provided by AOL or Google Api. The size of it is only about 30k :

 

[codesyntax lang=”javascript”]

<!-- From AOL -->
<script type="text/javascript"
    src="http://o.aolcdn.com/dojo/1.3/dojo/dojo.xd.js">
</script>

<!-- Or from Google Api
<script type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/dojo/1.3/dojo/dojo.xd.js">
</script>
-->

<script type="text/javascript">
    // Alert message when page loaded
    dojo.addOnLoad(function() {
        alert('Hello!');
    });

    // Alert message on every click
    dojo.query("a").onclick(function(evt) {
        alert("You are clicking a link.");
    });
</script>

[/codesyntax]

 

The current version of dojo is 1.3.0 while 1.4.0 is under development. So far it has perfectly explain what’s so called Ajax, Json and RIA since Its born.

Posted in JavaScript | Tagged , | Leave a comment

Caching application.ini for Zend Framework apps

In most of the time we build our application using Zend Framework, we make index.php as the entry which creates the object of Zend_Application and it’s configurations such as Application.ini.

 

But it’s very expensive when reading and parsing the Application.ini for every request.

 

It gave me inspiration to prevent parsing the ini for every request when I take a look into function Zend_Application::_loadConfig(). This function has allowed to pass an array as it’s parameters.

 

Here is the code in index.php :

 

[codesyntax lang=”php”]

<?php
// ......

// Application.ini.inc cache file
defined('CONFIG_INC')
    || define('CONFIG_INC',
              PROJECT_ROOT . '/library/Kbs/Config/Application.ini.inc');

// We use default config if no cache
$configFile = CONFIG_INC;
$noConfigCache = false;
if (false == is_file(CONFIG_INC)) {
    $configFile = PROJECT_ROOT . '/library/Kbs/Config/Application.ini';
    $noConfigCache = true;
}

// Zend_Application
require_once 'Zend/Application.php';

// Application object
$application = new Zend_Application(
    APPLICATION_ENV,
    $configFile
);

// Create the cache of config if no
// Only for production
if ($noConfigCache and ('production' == APPLICATION_ENV)) {
    $configs = '<?php' . PHP_EOL
             . 'return '
             . var_export($application->getOptions(), true) . PHP_EOL
             . '?>';
    file_put_contents(CONFIG_INC, $configs);
}

// ......

[/codesyntax]

 

Now the cache called Application.ini.inc will be loaded and parsed when the application find it.

Posted in Zend Framework | Tagged , | Leave a comment