Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

October 22 2010

10:00

A Complete Beginner’s Guide to Zend Framework: Part 2

A Complete Beginner’s Guide to Zend Framework: Part 2After reading the first part of our series, you’ve learned how to create a simple website based on Zend Framework. But it’s necessary to keep the information for full web-application. In this part we will learn how to work with databases using ZF.

Zend_Db

Zend_Db_Adapter gives us an opportunity to work with different database management systems (DBMS).

Using PDO drivers:

  • BM DB2 and Informix Dynamic Server (IDS), using pdo_ibm extension
  • MySQL, using the pdo_mysql PHP extension
  • Microsoft SQL Server, using pdo_mssql
  • Oracle, using pdo_oci
  • PostgreSQL, using pdo_pgsql
  • SQLite, using the pdo_sqlite PHP extension

Using PHP extensions:

  • MySQL, using the mysqli extension
  • Oracle, using the oci8 PHP extension
  • IBM DB2, using ibm_db2
  • Firebird / Interbase, using php_interbase

We’ll use the PDO driver to work with MySQL in this article.

Let’s Get Started

We need the way to store configuration file to the database connection. For it we’ll create a application.ini file in our ./application/configs directory. Add to the file following lines:

	db.adapter          = "pdo_mysql"
	db.params.host      = "localhost"
	db.params.username  = "root"
	db.params.password  = ""
	db.params.dbname    = "your_db_name_here"

I think the content will not cause any difficulties for you. We will use Zend_Confg_Ini to parse the config of this file. You have to initialize connection to the database before dispatching process. Add the following code to your index.php file.

	// Load up our config file
	$config = new Zend_Config_Ini('./application/configs/application.ini', 'db');

	$db = Zend_Db::factory($config->db->adapter,
				   $config-db->config->toArray());

	// Return data as object
	$db->setFetchMode(Zend_Db::FETCH_OBJ);

	// The default adapter for table classes
	Zend_Db_Table::setDefaultAdapter($db);

	// Write our adapter to registry
	Zend_Registry::set('db', $db);

If you do not want to receive the result as an object, there are descriptions of other styles to obtain the result for you:

  • Zend_Db:: FETCH_ASSOC: returns the data in an associative array.
    The keys of the array are the column names. It’s the mode of extraction is used by default in Zend_Db_Adapter classes.
  • Zend_Db:: FETCH_NUM: returns the data in an array. The array indexed by integers in accordance with the position of the field in the select query list.
  • Zend_Db:: FETCH_BOTH: returns the data in an array. The keys of the array are lines and integer values. The number of elements will produce twice more in the array than if FETCH_ASSOC or FETCH_NUM is used.
  • Zend_Db:: FETCH_COLUMN: returns the data in an array of values. The value is the value returned from one column of the result set in each array. By default, it’s the first column, indexed by zero.
  • Zend_Db:: FETCH_OBJ: returns the data in an array of objects. By default, the built-in PHP class stdClass is used. Columns of the result of sample are available as public properties of this object.

You are probably interested why have we recorded the adapter to the registry? We did so to be able to get access to our created adapter in any controller or model. To extract our adapter from the registry back we can use Zend_Registry::get(); method

	Zend_Registry::get('db');

Well, let’s try to execute some requests!

	$sql = 'SELECT * FROM users';
	$result = $db->fetchAll($sql);

The $result variable will contain an array of objects. To extract a single column from the sample results you should do

	$sql = 'SELECT name, id FROM users';
	$result = $db->fetchCol($sql);

Now $result contains only the name. In order to extract a single row from the result of sampling execute the following code

	$sql = 'SELECT * FROM users WHERE id = 2';
	$result = $db->fetchRow($sql);

And now $result is the single object ($result->name). Extracting a single value

	$sql = 'SELECT COUNT(*) FROM users';
	$result = $db->fetchOne($sql);

$result contains the number of users. That’s all with SELECT queries. But we still have to add and modify our data in the database. Lets’s look at it.

Adding Records

There is a special method for inserting data to the database: Zend_Db’s insert method.

	$data = array('name'  => 'Nick',
				  'login' => 'nick',
                  'email' => 'myemail@gmail.com');

	$db->insert('user', $data);
	$lastId = $db->lastInsertId();

We need to pass two parameters to insert method: table name, and an associative array with the data. lastInsertId method will return the value of auto-increment primary field in the table.

Updating Records

To able to update our db data we should call the update method and pass it three parameters. The first parameter is the name of the table, the second – an associative array with the data, the third parameter – a condition (optional); if you omit the third parameter, all records will be updated. The array of conditions can be passed as a WHERE condition.

	$data = array('name'  => 'Nick',
		          'login' => 'nick',
                  'email' => 'myemail@gmail.com');

	$db->update('user', $data, 'id = 1');

Deleting Records

Now you should know what each parameter is used for. The first argument is the name of the table, the second is the condition. Simply, right? Also there may be several conditions which is passed as an array. If you omit the second argument, all records of the table will be deleted.

	$db->delete('user', 'id = 1');

Example Bits of Code

Example 1:

	// Extract Zend_Db_Select
	$select = $db->select();	

	// 1st - table name, 2nd - array of selecting columns
	$select->from('news', array('YEAR(date) AS yearNews',
		'MONTH(date) AS monthNews',
		'DAy(date) AS dayNews'));

Example 2:

	// Extract Zend_Db_Select
	$select = $db->select();	

	// Descending sorting
	$select->from('news')->order('date DESC');
	$result = $db->fetchAll($select);

Example 3:

	// Extract Zend_Db_Select
	$select = $db->select();	

	// Descending sorting by date and ascending by title field
	$select->from('news')
		->order(array('date DESC', 'title'));

	$result = $db->fetchAll($select);

Example 4:

	// Extract Zend_Db_Select
	$select = $db->select();	

	// Descending sorting by date and ascending by title field
	$select->from(array('n' => 'news'), // table name and its alias
				array('newsTitle' => 'title', // The second parameter
						'newsDescription' => 'description', // column alias => column name
					'date' => 'date'))
			->join(array('a' => 'author'), // The first param for join method | alias => table name
					array('n.author = a.id'), // The 2nd param - array of condition for join operator
					array('name' => 'authorName')) // Associative array of columns
			->order('date DESC'); // Sorting descending by date column

	$result = $db->fetchAll($select);

Zend_Db_Select

Zend_Db_Select – is the assistant of making SELECT queries. Using this class methods we can build our complicated queries expressions part-by-part.

Queries Building

For example, we have to choose the record of news from a table with this query

	SELECT * FROM news WHERE id = 12;

Using Zend_Db_Select it would look like so

	// Extract Zend_Db_Select
	$select = $db->select();

	$select->from('news')->where('id = 12');
	$result = $db->fetchAll($select);

Now, let’s choose all the news records, but breaking the date’s field into three columns – year, month, day

SELECT *, YEAR(date) AS yearNews,
	MONTH(date) AS monthNews,
	DAY(date) AS dayNews
FROM news;

SQL has several types of joining operation. Below are the list of methods for supporting different joining types in Zend_Db_Select.

  • INNER JOIN, methods join (table, join, [columns]) and joinInner (table, join, [columns]).
  • LEFT JOIN, the method joinLeft (table, condition, [columns]).
  • RIGHT JOIN, the method joinRight (table, condition, [columns]).
  • FULL JOIN, the method joinFull (table, condition, [columns]).
  • CROSS JOIN, the method joinCross (table, [columns]).
  • NATURAL JOIN, the method joinNatural (table, [columns]).

There are also some special methods of Zend_Db_Select class.

  • orWhere() – the same as where(), but with logical OR.
  • group() – one column’s name can be sent to this method by one line or the lines’ array of columns’ names./li>
  • limit() – passes the desired number of rows to choose by the first parameter, by the second – number of the optional rows which can be omitted.

The Result

Another one Zend Framework lesson is completed. Digest the received knowledge, and I hope we will try to continue our experiment in the next part. Bye!

P.S. I look forward to receiving your feedback and questions in the comments below.

October 19 2010

10:00

A Complete Beginner’s Guide to Zend Framework: First Steps

Getting into Zend Framework: First StepsYou’ve been still tormenting and write-ins of the same type in the n-times for the site? You do what has been done for you and try to divide the project design from the code? Looking for realization of the necessary functions in questionable forums? If you answered “yes” one of these questions, so this article is definitely for you. There I will tell you about the powerful free framework (Content Managment Framework), if you learn it you will not only save time for the design, but also rtake the quality of your work to a much higher level. So, let’s sit comfortably and read my first article of the series “Learning to work with Zend Framework”.

Why to use Zend Framework?

The major aim for any CMF – reduce time for a project’s working up. Using this product, you can achieve following:

  1. Permanent structure of your projects. The problem of majority projects, making from nothing, – absence of a permanent structure. First, you put necessary function in one module, in the next project you realized you’d made a mistake and decided to change everything. As a result, the more you create a website / web-applications, the more you improve your knowledge, well then you make changes in the structure of new projects. But now try to imagine that you will have to go back to support/revision of your oldest project. I’m sure you’ll just get entangled or waste much of time for the code’s investigation. When you create a web-based application frameworks, this problem disappears, because you’re always guided by rules. This approach can guarantee that, if the oldest project’s revision is necessary, you will always know its structure and can finish it off easily.
  2. Increase the speed of development. There is a set of classes in ZF that allow to realize a lot of typical actions. You’ll not need to create one more bicycle cause you have the whole Kamaz of ready-made bicycles.:)
  3. Increase the level of safety. Everybody makes mistakes and no one is safety. It is difficult to argue, but with the help of ZF you can significantly reduce the error rate in the project. Because it’s really to make a lot of typical actions with the help of built-in classes, it means you have to write less code. And less code, less errors.

Is It Difficult?

Someone says that ZF is too complicated for understanding, heavy, requires a lot of server resources. It’s not like this in reality. If you can to learn php, so moreover you can deal with ZF, and as for heaviness, a good diet will eliminate this shortcoming with no problems.

Positive and Negative Of ZF

There are no ideal solutions and ZF is not the exception. It has its both positive and negative sides, which we’ll discuss in this part. Let’s start with the negative:

  1. Heavy, version 1.8.a for exaple is 17 MB (well, not be afraid of), although this is not so much. If you’re scared this size, see the size of many commercial CMS. Almost of them rolled over for 10 MBs and it is not surprising, cause they have a lot of functions. It is the similar story with ZF. It provides a lot of opportunities, but it’s not the fact that you can use them all.
  2. Requires a lot of time to study. Actually, this all is individually here. Some may mark time a year, while it will be enough for others just a few days and they are ready to write their first applications.
  3. Resource-intensive. To be honest, I have not seen more than one hosting provider that would kick the bucket from ZF.

That’s all the negative sides. Now the positive:

  1. ZF is a set of classes, most of which are not tied to each other, so that it can be used as the spare parts in other projects and completely. There is all you need in today’s Web projects.
  2. The presence of a component to work with third-party services.
  3. Object-oriented approach.
  4. MVC pattern based.
  5. Well documented.

So, it’s enough, no more theory and let’s go straight to practice. We estimate the possibility of the giant, so to speak:) Inorder to work with ZF, we need ZendFramework (you can download the latest version from here, HTTP server with the mod_rewrite support, PHP at least version 5.2, and MySQL 5. Download the latest stable version. By the way I almost forgot, you can download ZF in two different assemblies:

  • Full
  • Minimal.

Full Package contains the Dojo Toolkit, and the demos to work with a skeleton. Because you are just beginning to study this framework, I recommend to download this version.

Minimal Package contains only ZendFramework library.

Extract the folder with the core (/ library / Zend), ZF is better to keep a few levels higher, so that don’t produce the files for each project, in my example, it turned out in this folder D: \ library \ ZF \ 1.7.8 \ Zend \. (i’m on PC)

Making the Structure of the Project

Let’s organize the file structure for our future project. Create two directories in the root of the application:

  • application – here all our software modules of the project will be stored
  • public, where will be available all share files.

Also create index.php and .htaccess in the root, in which immediately add rules of redirects:


RewriteEngine on
RewriteRule .* index.php

It’s necessary to add similar .htaccess file, in the folder “public”.


RewriteEngine off

Now lets create 3 folders in “application” directory: configs, library, modules.

  • configs — here is configuration files of the project.
  • library — for additional libraries.
  • modules — and it’s for modules of our application.

After all these simple manipulations I had such a structure:

The root:

  • application
  • configs
  • library
  • modules
  • public
  • .htaccess
  • .htaccess
  • index.php</li

If the structure is ready, so we can move on to the coding ;-)
Open our index file (index.php). Let the interpreter know that php code wiil start soon and determine 4 constants:


PATH_TO_ZF - the path to ZF
PATH_TO_APPLICATION - the path to the folder “application”
PATH_TO_LIBRARY - the path to our libraries
PATH_TO_MODULES - the path to our modules.

The code:

define('PATH_TO_ZF', '../../../ZF/1.7.7/');
define('PATH_TO_APPLICATION', './application/');
define('PATH_TO_LIBRARY', PATH_TO_APPLICATION . 'library/');
define('PATH_TO_MODULES', PATH_TO_APPLICATION . 'modules/');

Now we should tell our intepriter the path to load all our stuff from:

include_path(PATH_TO_ZF . PATH_SEPARATOR . PATH_TO_APPLICATION . PATH_SEPARATOR . PATH_TO_LIBRARY);

The next step is to download Zend_Loader (later we will return to it) and register classes’ autoload.

require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();

So, Zend_Loader is loaded, now let’s activate Zend_Controller_Front (about it, too, later) and point the location of our modules to the dispatcher. Then start the process of dispatching.

$controller = Zend_Controller_Front::getInstance();
$controller->addModuleDirectory(PATH_TO_MODULES)->dispatch();

The result should be something like this:

define('PATH_TO_ZF', '../../../ZF/1.7.7/');
define('PATH_TO_APPLICATION', './application/');
define('PATH_TO_LIBRARY', PATH_TO_APPLICATION . 'library/');
define('PATH_TO_MODULES', PATH_TO_APPLICATION . 'modules/');

set_include_path(PATH_TO_ZF . PATH_SEPARATOR . PATH_TO_APPLICATION . PATH_SEPARATOR . PATH_TO_LIBRARY);

require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
$controller = Zend_Controller_Front::getInstance();
$controller->addModuleDirectory(PATH_TO_MODULES)->dispatch();

As you can notice Zend_Controller_Front never loaded because Zend_Loader loadsController automatically. Zend_Loader recognizes location of the controller on its name:
Zend_Controller_Front is in Zend/Controller/Front.php

A Little Bit More About Controller

Zend_Controller_Front implements the Singleton pattern, that means it can be initialized in the project only once. When you call a method dispatch(), the manager goes into a loop of dispatching passing three events:

  1. Routing defines what module, controller and the event can be called. If other ways are not written, then: site.ru/modules/controller/action/var1/value1/var2/value2 /. You can also override the paths through Zend_Controller_Route, but more on that in the next article.
  2. Dispatching – checking for the called module, controller, and events and call events.
  3. Answer – the view rendering.

Developing our Module

Create the folder “default” in our modules folder, it will be our first module. If we turn to our website using the link http://localhost/site.ru (you may have another location), it will be carried our default module. Name of default module can be changed, for example, to the “index”. It is done using the method – setDefaultModule (), object Zend_Controller_Front. It’s necessary to call the method before dispatching. As a parameter the method should get the module name, which will be used by default.


$controller->setDefaultModule('index');

Come on. We will create now two more folders in the module’s folder:

  • controllers — there are module controllers
  • views — but here everything related to the view (presentation)

Create a new controller (IndexController.php), and put this code:

class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
return;
}
}

Now you need to create a script for our controller. For it, create folders “scripts/index” in a folder “views”. It should be something like this:


default
controllers
IndexController.php
views
scripts
index

Create a file index.phtml in the folder views/scripts/index/. Try to test it! If there are no errors, it means you are good to listen to me :) Now add the event:


$this->view->var = ‘ZendFramework’;

General view of the controller looks like this:

class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$this->view->var = ‘ZendFramework’;
}
}

Lets add into the view file the following code:

echo $this->var;

After that, update the page.

Creating an Error 404 Page

Create another controller in our module, ErrorController.php:

class ErrorController extends Zend_Controller_Action
{
public function errorAction()
{
return;
}
}

Now lets create a submission for the error: /default/views/scripts/error/error.phtml:


404

In order to test it, type in your browser’s address bar: site/qwerty. As we do not have this page, so the result will be appropriate. In order that would include the output error due to which the script is stopped before dispatching we need to call the throwExceptions() method and passing the appropriate parameters, if we want to see a mistake, true, and false, if we want to differentiate a mistake when we created this page.

You’re Done!

First, I think that’s enough. For our first meeting we discussed a lot of interesting things. It is not all clear while, but do not worry. Skill comes with time. The main thing is not to be lazy and try to do something. In the article I mentioned that ZF is based on the MVC architecture. If you’re scared or have entered a dead end, the words “view”, “controller”, then launch Google and read a basis MVC theory.

That’s all; I hope you enjoyed this tutorial, and thanks for reading! See you in next chapter.

Sponsored post
feedback2020-admin
14:56
you are awesome!
Reposted bysirthomasbolton sirthomasbolton

June 04 2010

15:46

10 Compelling Reasons to Use Zend Framework


Trying to decide which framework to use for your new project? In this article, we’ll go in-depth about why Zend Framework should absolutely be your PHP framework of choice.


Introduction

Whether you’re starting a new project or improving an existing one, in this article, I’ve provided ten reasons why you should use Zend Framework for your next project, and hopefully, it helps you in making an informed decision.


Reason 1. Extend Classes like There’s no Tomorrow

Zend Framework is a fully object-oriented framework, and as such, it utilizes a lot of object-oriented (OO) concepts like inheritance and interfaces. This makes most, if not all, of ZF’s components extendable to some point. It allows developers to implement their own special variations of individual components without having to hack into the ZF codebase itself. Being able to customize ZF this way allows you to create functionality that is unique to your project, but because of its object-oriented nature, you’ll be able to use this functionality in other projects as well.

Example

Zend Framework has a very extensive Validation component, which you can use to validate data coming from forms. In ZF, forms are treated as objects as well, and are represented by the Zend_Form component.

Let’s assume that you want to create a custom URL validator to restrict URL input from the user. The quickest way to do this would be to just validate the input using something like:

$isValid = filter_var($submitted_url, FILTER_VALIDATE_URL);

But this won’t adhere to the OO nature of form objects, since it’s not used within the context of the form. To solve this, we can create a new Zend_Validator class by extending the Zend_Validate_Abstract class:

<?php
class Zend_Validate_Url extends Zend_Validate_Abstract
{
	const INVALID_URL = 'invalidUrl';

	protected $_messageTemplates = array(
		self::INVALID_URL   => "'%value%' is not a valid URL.",
	);

	public function isValid($value)
	{
		$valueString = (string) $value;
		$this->_setValue($valueString);

		if (!Zend_Uri::check($value)) {
			$this->_error(self::INVALID_URL);
			return false;
		}
		return true;
	}
}

This actually uses the Zend_Uri class, which already has a URL checking method we can use. But since it doesn’t extend the Zend_Validate_Abstract class, we implemented a wrapping class which does implement the needed abstract class. This lets us use the Zend_Uri URL checking function in our Zend_Form objects like so:

<?php
class Form_Site extends Zend_Form
{
	public function init()
	{
		$this->setMethod('POST');
		$this->setAction('/index');

		$site= $this->createElement('text', 'siteurl');
		$site->setLabel('Site URL');
		$site->setRequired(true);

		//  Adding the custom validator here!
		$site->addValidator(new Zend_Validate_Url());
		$this->addElement($site);
		$this->addElement('submit', 'sitesubmit', array('label' => 'Submit'));
	}

}

If we wanted to check that our URLs are valid YouTube video URLs, we could do something like this:

<?php
class Zend_Validate_YouTubeUrl extends Zend_Validate_Abstract
{
	const INVALID_URL = 'invalidUrl';

	protected $_messageTemplates = array(
		self::INVALID_URL   => "'%value%' is not a valid URL.",
	);

	public function isValid($value)
	{
		$valueString = (string) $value;
		$this->_setValue($valueString);

		if (strpos($value, "http://www.youtube.com/watch?v=") !== 0) {
			$this->_error(self::INVALID_URL);
			return false;
		}
		return true;
	}
}

If we added this to our site form object as a validator, it would ensure that all URLs submitted begin with the correct YouTube video URL prefix.


Reason 2. Object-oriented Goodness


Image courtesy of http://www.developer.com

In Zend Framework, everything is an object, as proven by our example above. This poses its own disadvantages, such as making things more complicated to code. Its main advantage, though, is the ability to make code reusable, and since nobody likes to repeat themselves, this is a very good thing.

Example

We already have our Zend_Validate_Url and Form_Site class from our example above, so let’s reuse them in this example.

<?php

class IndexController extends Zend_Controller_Action
{

    public function indexAction()
    {
		$siteform = new Form_Site();

		if( $this->_request->isPost() && $siteform->isValid($this->_request->getPost()) ) {
			//stuff to do if the input is correct
			$this->_redirect("/index/correct");
		}
		$this->view->siteform = $siteform;
    }

    public function correctAction()
    {
		// Yay, we're re-using our Form_Site object!
		$this->view->siteform = new Form_Site();
    }
}

Here’s what it would look like on a browser:

If you tried to submit an invalid URL, you can see our URL validator at work:

Here, you can see what would happen if you did input a valid URL:

As you can see, we’ve never had to repeat our form object code.

“Zend_Validate classes can be used in other ways as well, not only within the context of Zend_Form classes. You simply instantiate a Zend_Validate class and call the isValid($parameter) method, passing it the value you want to validate.”


Reason 3. Use What you Need, Forget Everything Else

Image courtesy of http://dev.juokaz.com

By design, Zend Framework is simply a collection of classes. Normally, you’ll use Zend MVC components to create a fully-functional ZF project, but in any other case, you can just load the components you need. ZF is very decoupled, which means we can take advantage of the components as individual libraries, instead of the framework as a whole.

If you’ve been looking at other framework articles, you’ve probably heard of the term glue framework. ZF, by default, is a glue framework. Its decoupled nature makes it easy to use as “glue” to your already existing application.

There’s a debate between using glue frameworks vs. full-stack frameworks. Full-stack frameworks are those that provide you everything you need to create your project, like ORM implementations, code-generation, or scaffolding. Full-stack frameworks require the least amount of effort to create a project, but fall short in terms of flexibility, since it imposes strict conventions on your project.

Example

Let’s say you need a way to retrieve information about a specific video on YouTube. Zend_Gdata_Youtube is a ZF component which allows you to access data from YouTube via the GData API. Retrieving the video information is as simple as:

//Make sure you load the Zend_Gdata_Youtube class, this assume ZF is in your PHP's include_path
include_once "Zend/Gdata/Youtube.php";

$yt = new Zend_Gdata_YouTube();
// getVideoEntry takes in the YouTube video ID, which is usually the letters at the end
// of a YouTube URL e.g. http://www.youtube.com/watch?v=usJhvgWqJY4
$videoEntry = $yt->getVideoEntry('usJhvgWqJY4');
echo 'Video: ' . $videoEntry->getVideoTitle() . "<br />";
echo 'Video ID: ' . $videoEntry->getVideoId() . "<br />";
echo 'Updated: ' . $videoEntry->getUpdated() . "<br />";
echo 'Description: ' . $videoEntry->getVideoDescription() . "<br />";
echo 'Category: ' . $videoEntry->getVideoCategory() . "<br />";
echo 'Tags: ' . implode(", ", $videoEntry->getVideoTags()) . "<br />";
echo 'Watch page: ' . $videoEntry->getVideoWatchPageUrl() . "<br />";
echo 'Flash Player Url: ' . $videoEntry->getFlashPlayerUrl() . "<br />";
echo 'Duration: ' . $videoEntry->getVideoDuration() . "<br />";
echo 'View count: ' . $videoEntry->getVideoViewCount() . "<br />";

Code sample courtesy of Google Developer’s Guide

This code would output:

One thing to note here: this Zend Framework component (GData) is the official PHP library endorsed by Google to access its API. The framework’s decoupled nature allows us to use the component in any project, regardless of the framework we used to build it.


Reason 4. It lets you do a Lot of Things!

One of the things I love most about Zend Framework is that it has A LOT of components. Need a way to authenticate a user? Use Zend_Auth. Need to control access to your resources? Look up Zend_Acl. Need to create some forms? We have Zend_Form. Need to read an RSS feed? You can use Zend_Feed for that. It’s basically the Swiss Army knife of PHP classes!

Zend actually comes with some demos that show how to use its different components:

To view these, the best way is to simply download the Full Package Version of Zend Framework and test them out on your machine.

For a complete list of all the components, you can check out the Zend Framework Manual.


Reason 5. No Model Implementation – Choose your Own Adventure!

Image courtesy of http://www.vintagecomputing.com

This is actually one of the reasons most developers don’t use Zend Framework – it has no Model implementation on its own. For those who don’t know what a Model is, it’s the M in MVC, which stands for “Model-View-Controller”, a programming architecture that’s used by most PHP Frameworks.

Does that mean that Zend Framework is only a “VC” Framework?

Yes, and no.

Yes, it’s a VC framework because it doesn’t have its own Model implementation. This makes it hard for some people to use ZF, especially if they’re coming from a framework which does have a Model implementation (like CakePHP, Symfony, or even Ruby on Rails).

On the other hand, no, it’s an MVC framework as well, since apart from providing the generic ways to access the database (using Zend_Db), it actually still relies on some sort of Model implementation. What it does differently is that it leaves this kind of implementation up to the developer ñ which some say should be the case since models are actually where the business logic of the application resides, and therefore, they’re not something which can be developed as a generic component. Zend Framework Philosophy states that model implementations are unique to the projectóit’s impossible to create an abstract implementation of it since they don’t really know what you need. They believe that models should be implemented by the developers themselves.

How is this a good thing?

Not having a Model implementation means that the developer is free to use whatever means he has to implement it, or even just integrate existing implementations. Being free of predefined restraints, the developer is then allowed to create more complex implementations, rather than just simple representations of tables, which is how usual Model implementations are created. Models contain your business logic. They should not be restrained by your database tables; rather, they should dictate the connections of these tables to one another. This lets you put most of your programming code in your Models, therefore satisfying the “Thin Controllers, Fat Models” paradigm of MVC.

So how will I use Zend Framework if I have no idea how to create my own models?

For beginners, the Zend Framework Quickstart tutorial shows us a good way to implement models. In the tutorial, they implement an ORM approach to the models, wherein you would create three filesóthe actual Model, which is an abstract representation of your object; a Mapper, which maps data from the database to your Model; and a Database Table object, which is used by the mapper to get the data. You can check out the code in the ZF Quickstart tutorial, where they used this approach to implement the model of a simple Guestbook application.

For those asking “Why do I have to code this myself while other frameworks do the work for me?”, this is a perfect segue to my next reason…


Reason 6. Integrate with Whatever you Want!

Zend Framework’s decoupled nature makes it very easy to integrate other libraries that you want to use. Let’s say you want to use Smarty as your templating system. It can be done by simply creating a wrapping class for Zend_View_Abstract, which uses a Smarty instance to render the view.

This works both ways, as you can integrate ZF into other libraries as well. For example, you can integrate ZF into Symfony. They’re planning to do this with Symfony 2, using the Zend_Cache and Zend_Log components from ZF.

Example

For our example, we’ll try using Doctrine to implement our Model. Continuing from our site example above, say you’ve already implemented your DB table like so:

CREATE TABLE  `site` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `url` varchar(100) CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (`id`)
);

To integrate Doctrine into ZF, we’ll have to make sure that the proper settings are defined. I’ve followed this tutorial from dev.juokaz.com about using Doctrine with ZF.

Assuming everything works out, you’ll just have to generate your model files by running the doctrine-cli.php php file from the tutorial like so:

php doctrine-cli.php generate-models-db

You should see this success message:

Afterwards, you can check the folder which you set as the place to store the generate Model classes.

Then in our controller class, we can simply use our site model class.

<?php

class IndexController extends Zend_Controller_Action
{

    public function indexAction()
    {
		$siteform = new Form_Site();

		if( $this->_request->isPost() && $siteform->isValid($this->_request->getPost()) ) {
			//stuff to do if the input is correct
			$site = new Model_Site();
			$site->url = $this->_request->getParam('siteurl');
			$site->save();
			//redirect to our success page
			$this->_redirect("/index/correct");
		}
		$this->view->siteform = $siteform;
    }

    public function correctAction()
    {
		// Yay, we're re-using our Form_Site object!
		$this->view->siteform = new Form_Site();
    }
}

If we check our sites table, we’ll see that our records is there

Now, every time we submit a site, our controller will use our Doctrine model implementation to save to our database. Isn’t that nice and easy? Setup may be a bit complicated, but on the plus side, our project is now able to take advantage of a tool which has been developed specifically for Model implementation. Our project now has the power of two very developed technologies behind it.


Reason 7. Guidelines and Standards

Zend Framework is developed in conjunction with a very extensive Contributor Guide, which basically states that:

  1. Every contributor for both documentation and/or code, at any level (either a few lines of code, a patch, or even a new component) must sign a Contribute License Agreement (CLA).
  2. Code MUST be tested and covered by a unit test using PHPUnit. And…
  3. Code must adhere to strict Coding Standards

These strict guidelines ensure that you only use readable, high-quality code that has been tested thoroughly.


Reason 8. All Code is Guilty Until Proven Innocent (aka Test-Driven Development)

Image courtesy of http://www.codesmack.com/

Test-driven development is a programming technique that requires a developer to write tests for the function he is supposed to code before writing code for the function itself. By writing the tests first, it ensures that the programmer:

  1. Thinks of the possible use-cases of his code
  2. Creates a whitelist of input and output
  3. Makes it easier to refactor his code
  4. Makes it easier to pass code from one person to another

The test-driven development Cycle
Image courtesy of Wikipedia

Zend Framework makes it easy to do TDD via Zend_Test, which uses PHPUnit, a popular unit testing framework. PHPUnit lets you test not only your Controllers, but also your library and model functions. To add to this, Zend_Tool, which is Zend Framework’s scaffolding utility, already makes provisions for PHPUnit when you use it to create your project.

Integrating PHPUnit and Zend Framework

Setting up Zend Framework and PHPUnit is not that difficult. Basically, once you’re done with it, you’ll be able to use the same setup for your future projects. Just as a side note, the following steps assume that you’ve used Zend_Tool to scaffold your project structure and files, but it should be relatively simple to change for other setups.

First, we need to install PHPUnit. The best way is to install it via PEAR:

pear channel-discover pear.phpunit.de
pear install phpunit/PHPUnit

Afterward, we’ll open our phpunit.xml, an XML file generated by Zend_Tool. You’ll find it inside the tests folder in the root directory of your project. Add the following lines:

<phpunit bootstrap="./TestHelper.php" colors="true">
    <testsuite name="Zend Framework Unit Testing">
        <directory>.</directory>
    </testsuite>

    <filter>
        <whitelist>
            <directory suffix=".php">../library</directory>
            <directory suffix=".php">../application</directory>
            <exclude>
                <directory suffix=".phtml">../application</directory>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

After saving phpunit.xml, create a new file inside the same folder as phpunit.xml called TestHelper.php. This PHP file will help us setup the environment for our tests.

<?php
// start output buffering
ob_start();

// set our app paths and environments
define('BASE_PATH', realpath(dirname(__FILE__) . '/../'));
define('APPLICATION_PATH', BASE_PATH . '/application');
define('APPLICATION_ENV', 'testing');

// Include path
set_include_path(
    '.'
    . PATH_SEPARATOR . BASE_PATH . '/library'
    . PATH_SEPARATOR . get_include_path()
);

// We wanna catch all errors en strict warnings
error_reporting(E_ALL|E_STRICT);

require_once 'ControllerTestCase.php';

We then create our parent Controller Test Case class, which all of our Controllers will extend. This will help implement methods which would usually be the same throughout all of the Controller test classes.

<?php
require_once 'Zend/Application.php';
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';

abstract class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
    public $application;

    public function setUp()
    {
        $this->application = new Zend_Application(
            APPLICATION_ENV,
            APPLICATION_PATH . '/configs/application.ini'
        );

        $this->bootstrap = $this->application;
        parent::setUp();
    }

    public function tearDown()
    {
        $this->resetRequest();
        $this->resetResponse();
        parent::tearDown();
    }
}

Lastly, we create a controller test class:

<?php
require_once realpath(dirname(__FILE__) . '/../../ControllerTestCase.php');

class IndexControllerTest extends ControllerTestCase
{
    public function testCallingRootTriggersIndex()
    {
        $this->dispatch('/');
        $this->assertController('index');
        $this->assertAction('index');
    }

    public function testCallingBogusTriggersError()
    {
        $this->dispatch('/bogus');
        $this->assertController('error');
        $this->assertAction('error');
        $this->assertResponseCode(404);
    }
}

All that’s left is to run our test. Open your command prompt and go to the tests folder and type:

phpunit

Your command line should output the following:


PHPUnit and Zend Framework setup tutorial and code courtesy of http://www.dragonbe.com

Reason 9. Community and Documentation

Due to its multiple components, complexity, and fully object-oriented approach, Zend Framework has a very steep learning curve. It becomes easier to learn due to the comprehensiveness of its documentation and its thriving community. First of all, the Zend Framework Programmer’s Reference Guide boasts a complete guide to all ZF components, with examples, code, and usage theories.

Aside from this, there are a lot of blogs out there that share Zend Framework tips and tricks. For example, Phly, boy, phly, the blog of Matthew Weier O’Phinney, a Core Contributor to Zend Framework, provides a lot of insights, clever uses, and component explanations for Zend Framework. Zend also has a site called Zend Developer Zone, which aside from publishing tutorials for Zend Framework, has stuff like Zend Framework Webinars, podcasts, and articles about PHP in general. Another site, called Zend Casts, offers a lot of useful video tutorials on different Zend Framework components as well. Last but not least, there’s a free online book called Zend Framework: Surviving the Deep End” written by P·draic Brady, another Zend Framework contributor.

As you can see, there is no lack of support from the community, the documentation, and the developers. If you have any questions or need any clarifications, a quick search with the right keywords should almost always give you relevant results. If not, there’s still the Zend Framework Mailing Lists, the official Zend Framework Forums, the unofficial Zend Framework Forums or the unofficial Zend Framework IRC channel


Reason 10. Certifications Ahoy!

If you’re still unconvinced about learning and using Zend Framework, this reason is actually the one that I feel most distinguishes Zend Framework from all the others. Zend not only offers Zend Framework Certification, but PHP Certification as well. By offering certifications, Zend helps you use your expertise in PHP and Zend Framework to boost your portfolio or CV. The Zend Certification site lists a number of reasons to get certified, some of which are:

  1. Differentiate yourself from competitors when looking for a new job
  2. Get your resume/CV noticed
  3. Have your profile displayed in Zend’s Yellow Pages for PHP Professionals
  4. Be part of the Linkedin Group Exclusively for ZCE’s
  5. Get special discounts on Zend PHP conferences worldwide

Addendum

Just to keep things balanced, here’s a quick list of reasons why you might not want to use Zend Framework:

  1. VERY steep learning curve. It’s not very hard for advanced PHP users, but for beginners, there’s a lot to learn!
  2. Big footprint. Since Zend Framework has a lot of components, it’s total size is relatively higher than other Frameworks. For example, CodeIgniter’s system folder has a 1.5MB footprint compared to Zend Framework’s 28MB footprint.
  3. No solid scaffolding tool. Although Zend_Tool offers some functionality, it’s not much compared with the scaffolding utilities of full-stack frameworks like CakePHP or Symfony.
  4. Not shared webhosting friendly. The folder structure generated by Zend_Tool suggests that the public folder be the only directory accessible via http ó which assumes that a user is able to create a virtual host for the project. This is something you aren’t able to do in most shared web hosting environments.
  5. Too gluey. Since everything is in separate classes, it’s sometimes hard to envision how everything works. This wouldn’t be a problem with full-stack frameworks, since they mostly take care of everything for you. Without Zend_Tool, it would be extremely difficult to set up a working project structure

Conclusion

A lot of advancements have been made in the world of PHP Frameworks in the past few years. I’ll be honest, there’s a whole lot of fish in the sea. There are frameworks like Codeigniter, CakePHPand Symfony which are also good to use. Some of you might be thinking, “Why did this guy focus on Zend Framework? Why didn’t he run performance tests to compare the different frameworks?” To that, I reply with this quote from a very entertaining article entitled “PHP Framework Benchmarks: Entertaining But Ultimately Useless” by P·draic Brady:

To create a positive benchmark, you need to understand that all frameworks were born as festering piles of unoptimised stinking crap. They were all born bad and get worse with age. This sounds quite sad, but actually it’s an inevitable compromise between performance and features. It’s also a compromise between performance and ease-of-use. So you see, performance is unfairly faced by two opponents: features and ease-of-use. All performance is sacrificed in the name of serving the needs of rapid development, flexibility, prototyping, and making your source code look prettier than the other guy’s. As if.

What happens if you move away from the enemies of performance and do some propping up behind the scenes? You get…wait for it…oodles of extra performance!

When it comes down to it, which framework you choose to use really depends on how comfortable you are with it. None of these frameworks would be of help to you if you aren’t able to take full advantage of their features. You can spend weeks or even months using a specific framework, only to trash it in the end because you just aren’t as comfortable using it as you were with some other framework.

So I invite you to at least try out Zend. If it works for you, that’s great! It does for me. But if it’s not a good fit, go ahead and try out the others. Soon enough, you’ll find the framework that’s just right for your needs.

November 06 2009

10:01

Book Review: Zend Framework 1.8 Web Application Development

If you are looking into buying a book to learn about Zend Framework, chances are you are already set on using Zend Framework to build your next project. Today, we will be looking at Zend Framework 1.8 Web Application Development by Keith Pope, published by Packt Publishing.

First of all, you’ll notice that this book is based on Zend Framework version 1.8, and as of writing this review, the latest stable release of Zend Framework is 1.9.4. This is not an issue, because 1.9, even though it brings new features such as PHP 5.3 compatibility and RESTful web services, does not change its structure or any part of the system that might have impact on your learning.

Flow of the Book

The flow of this book is heavily inspired by the famous Ruby on Rails book, Agile Web Development with Rails, where the author invites you to join the process of building a demo application, which in both cases is a shopping cart system. Judging by the feedback of the Rails book, most people feel quite comfortable learning a framework this way, some don’t. I guess if you are not a fan of following a defined learning structure, this book probably isn’t for you.

Short but Sweet

It is a relatively short book, with only around 350 pages. As a result, this book expects you to be comfortable with working with PHP 5 and have a solid grasp of Object-Oriented Programming. If you aren’t already familiar with PHP, or PHP 5’s OOP features, I highly recommend you to polish up the said skills.

MVC Still Rules

The first two chapters of the book focus on the MVC (Model-View-Controller) pattern. As the author mentions at the start of the book, Zend Framework is a loosely coupled framework; it does not enforce the MVC principle. However, given the popularity of MVC within the web development community, it is definitely worth while to learn how to write an application in MVC. Chapter one explains the basics of MVC whilst chapter two explains the request/route/dispatcher/response family. These two chapters will set up the foundation nicely for you and get you to understand the basic structure of a Zend Framework powered MVC application.

Adventure of the Store-Front App

Chapter three to nine contain the actual ‘adventure’ where you as the reader will be riding along with the author on the journey of creating a store-front/shopping-cart application. During the process, the author tells you not only what to do, but also why to do them. A good example is the ‘fat controller skinny model’ vs ’skinny controller vs fat model’ comparison, the book illustrates each and tells you why you should stick with the latter.

Chapter ten wraps up the store-front application with some more common tasks such as bootstrapping modules and sharing common application elements.

Code Optimization, Caching and Testing

Chapter eleven touches on a very practical topic: code optimization and caching. This is especially beneficial if you’re to run a large volume web application or if you have limited hardware resources. Pay special attention to the Zend_Cache section as the author tells you how to integrate it effectively in your application in order to achieve the best result.

The last chapter, chapter twelve, introduces you to Zend_Test, a testing framework that utilizes PHPUnit.

Verdict

To wrap the review up, I think this is an excellent book on Zend Framework provided you:

  • already have a good understanding of PHP;
  • already have a good understanding of OOP;
  • can follow the rather forceful learning flow;
  • know how to learn with initiative (e.g. do your own research!).

This book sits well in the market, as it aims primarily at web professionals who most likely are already experienced with PHP and perhaps some other PHP frameworks, and don’t have time to read books with 1000’s of pages.

You may purchase this book via Packt Publishing’s website.



Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
(PRO)
No Soup for you

Don't be the product, buy the product!

close
YES, I want to SOUP ●UP for ...