Zend Framework View Helpers

Zend Framework View Helpers allow developers to easily maintain view code, but many existing helpers are coded in very poor form. A few simple guidelines can vastly improve the way developers approach these helpers.

What is a View Helper

A view helper is simply an additional method added to the view object. The Zend Framework includes are number of very simple and easy to use view helpers.


<?= $this->partial('sidebar.phtml'); ?>

This partial view helper does exactly what you would expect it to, it displays the contents of sidebar.phtml onto the page.

Why Use a View Helper

Imagine having to include a bunch of files on a page without using the partial() view helper. The code would get messy pretty quickly since it would be filled with random file opens. The view helper makes it easier since it cuts down on copy-and-paste code and centralizes all logic specific to a certain process in one place. In other words, it keeps code DRY.

All developers have heard of “Fat Model Skinny Controller”, but when it comes to views there is no catch phrase rule of thumb. Many believe that views can be fat (lots of code).  Its perfectly fine for views to contain many lines of code, but high line count in views is often an indicator to add in view helpers.  Think of views in the skinniest way possible by putting every modular part of a page into a custom view helper.

View helpers should exist for any content that could possibly go onto more than one page. For example, a social networking site would have a page that lists all of your friends. The site would also want to display a user’s top ten friends on another page. This is the perfect use a view helper, which we will call friends().

What does a Zend Framework View Helper Look Like?

class My_View_Helper_Friends extends Zend_View_Helper_Abstract {

 public function friends() {
  return "hello friends!"
 }

}

This is a view helper in its simplest form. Adding this helper to an applicated can be done by calling Zend_View::addHelperPath().

To call this method from a view:

My Friends

<?= $this->friends() ?>

Use Chaining

The biggest problem with View Helpers in the Zend Framework Community is that most developers treat them as methods/functions rather than objects. Since they are defined in their own class developers really have no excuse for ignoring the added benefits that come with object oriented programming. Using methods and setters of an class is always going to be more maintainable than passing parameters to a function.

Parameters are messy. The friends helper could take a ton of parameters, such as: The number of friends to display, recent friends, old friends, male friends, female friends, friends in a certain city, it goes on-and-on-and-on. Does this look fun?

My Female Friends in Boston

<?= $this->friends(10, 'recent', 'female', $city120) ?>

The function is ugly, it’s impossible to remember the order of parameters, and what happens if another parameter is needed in the function in a few months from now. Refactoring this code is going to be painful.

More important, that function is going to be nearly impossible to unit test. All of the if statements, extra parameters, and default parameters are going to cause nightmares for any coder. The test cases are going to be filled with so much junk in order to test each little section of the function.

This code on the other hand is much easier to read, extremely easy to refactor, and simple to test:

My Bro Friends

<?= $this->friends()->show(12)->gender('Male') ?>

Write a render method, Don’t Call it

Its good practice to write a render() method that returns the HTML/final output to the view, but it sure is a pain to have to keep writing “->render()” at the end of each view helper call.

To avoid this use PHP’s magic method __toString().

public function render() {
 return "some html";
}

public function __toString() {
 return $this->render();
}

Now every time the helper is called with a short tag it will automatically be displayed.

Things to remember about View Helpers

  1. When chaining an object, the setter methods will have to return instances of the object.
  2. The Zend View object will retain all instances of view helpers. So all default values will have to be reset whenever the helper is called for a 2nd time. See method _defaultValues() below for an example.
  3. The render() method returns HTML/text/output.

Here is what the final friends() helper would look like:

class My_View_Helper_Friends extends Zend_View_Helper_Abstract {

 private $_show;
 private $_gender;

 public function friends() {
  $this->_defaultValues();
  return $this;
}

 private function _defaultValues() {
  $this->show(null);
  $this->gender(null);
 }

 public function show($show) {
  $this->show = $show;
  return $this;
 }

 public function gender($gender) {
  $this->gender= $gender;
  return $this;
 }

 public function render() {
  // .. replace with a method call to gather data based on whats been set
  return "these are my friends: " . $this->_finalOutput;
 }

My Experience

I pretty much put just about everything I can inside a view helper. I have no view that is over 100 lines of code. In fact, most of my pages are just a couple of lines, there are probably very few that contain more than 20 lines. There is a huge benefit here that has nothing to do with DRY principles or the object oriented properties I have mentioned in this article. In fact, it has very little to do with development, but everything to do with team flow:

When a view is skinny and has a majority of its ‘code’ moved into helpers the only thing that remains is text. Views with mostly text allow non technical people to easily edit (and even commit) the pages of your application.

More

Zend Framework View Reference
Devzone Article on Views

PHP Dependency Injection

Dependency injection is the answer to more maintainable, testable, modular code.

Every project has dependencies and the more complex the project is the more dependencies it will most likely have.  The most common dependency in today’s web application is the database and chances are if it goes down the app will all together stop working.  That is because the code is dependent on the database server… and that is perfectly fine.  Not using a database server because it could one day crash is a bit ridiculous.  Even though the dependency has its flaws, it still makes life for the code, and thus the developer, a lot easier.

The problem with most dependencies its the way that code handles and interacts with them, meaning, the problem is the code and not the dependency.  If you are not using dependency injection, chances are your code looks something like this:

class Book {

	public function __construct() {

		$registry  = RegistrySingleton::getInstance();
		$this->_databaseConnection = $registry->databaseConnection;

		// or

		global $databaseConnection;
		$this->_databaseConnection = $databaseConnection;
	}

}

The book object now is given full access to the database once it is constructed.  That is good, the book needs to be able to talk to the database and pull data.  The problem lies in the way the book gained its access.  In order for the book to be able to talk to the database the code must have an outside variable named $databaseConnection, or worse, it must have a singleton pattern class (registry) object containing a record for a databaseConnection.  If these don’t exist the book fails, making this code is far from modular.

This raises the question, how exactly does the book get access to the database?  This is where inversion of control comes in.

In Hollywood a struggling actor does not call up Martin Scorsese and ask for a role in his next film.  No, the opposite happens.  Martin Scorsese calls up the broke actor and asks him to play the main character in his next movie.  Objects are struggling actors, they do not get to pick the roles they play, the director needs to tell them what to do.  Objects do not get to pick the outside systems they interact with, instead, the outside systems are given to the objects.  Remember this as Inversion of Control: The Hollywood Way.

This is how a developer tells his objects how to interact with outside dependencies:

class Book {

	public function __construct() { }

	public function setDatabaseConnection($databaseConnection) {
		$this->_databaseConnection = $databaseConnection;
	}

}
$book = new Book();
$book->setDatabase($databaseConnection);

This code allows for the book class to be used in any web app.  The Book is no longer dependent on anything other than the developer supplying a database shortly after object creation.

This is, at its finest, dependency injection.  There are two common practices of injecting dependencies.  The first being constructor injection and the second being setter injection.  Constructor injection involves passing all of the dependencies as arguments when creating a new object.  The code would look something like this:

$book = new Book($databaseConnection, $configFile);

The more dependencies an object has, the messier this construction becomes.  There are other reasons why this is a bad approach, involving ideas around code reusability and constructors doing work.

This leaves us with other method of dependency injection, called setting injection, which involves creating a public method inside the object for the dependencies that need injection.

$book = new Book();
$book->setDatabase($databaseConnection);
$book->setConfigFile($configFile);

This is easy to follow, but it leads writing more and more code for your application.  When a book object  is created three lines of code are required.  If we have to inject another dependency, a 4th line of code is now needed.  This gets messy quickly.

The answer to this problem is a factory, which is class that is designed to create and then inject all the dependencies needed for an object.  Here is an example:

class Factory {

	public static $_database;

	public static function makeBook() {

		$book = new Book();
		$book->setDatabase(self::$_database);
		// more injection...

		return $book;
	}

}

And then:

$book = Factory::makeBook();

All dependencies should be registered into the factory object during run time.  This object is now the gateway that all dependencies must pass through before they can interact with any classes.  In other words, this is the dependency container.

The reason makeBook is a public static function is for ease of use and global access.   When I started this article off I made a reference to the singleton pattern and global access being a poor choices of code.  They are… for the most part.  It is bad design when they control access, but it is perfectly ok when they control creation.  The makeBook function is only a shortcut for creation.  There is no dependency what-so-ever between the book class and the factory class.  The factory class exists so we can contain our dependencies in one location and automatically inject those dependencies with one line of code creation.

The factory or container class removes all of the extra work of dependency injection. 

Before injection:

$book = new Book();

And now:

$book = Factory::makeBook();

Hardly any extra work, but tons of extra benefits.

When test code is run, specifically unit tests, the goal is to see if a method of a class is working correctly.  Since the book class requires database access to read the book data it adds a whole layer of complexity.  The test has to acquire a database connection, pull data, and test it.  All of a sudden the test is no longer testing a single method in the book class, it is now also testing database.  If the database is offline, the test would fail.  This is FAR from the goal a unit test.

A way of dealing with this is just using a different database dependency for the unit tests.  When the test suite starts up a dummy database is injected into the book.  The dummy database will always have the data the developer expects it to have.  If a live database was used in a unit test the data could potentially change causing tests to unnecessarily fail.  There is no need for a unit test to be refactored when a record in a database changes.

The code is more modular because it can dropped into any other web application.  Create the book object and inject a database connection with $book->setDatabase().  It does not matter if the database is in Registery::Database, $database, or $someRandomDatabaseVarible.  As long as there is a database connection the book will work inside any system.

The code is more maintainable because each object given exactly what it needs.  If separate database connections are required between different instances of the same class then there no extra code needed inside the class what-so-ever.  Give book1 access to database1 and book2 access to database2.

Factory::$_database = $ourDatabaseVarForDB1;

$book1 = Factory::makeBook();
$book2 = Factory::makeBook();
$book2->setDatabase($database2);

Dependency injection really is the answer to more maintainable, testable, modular code.


I titled this article PHP Dependency Injection, but there is really nothing in here that is specific to PHP.  The reason I choose to include PHP and write all of the code examples in PHP is because I constantly see PHP projects not using DI.  I believe the best place to teach good coding practices is in popular frameworks by forcing the users of the framework to develop within the guidelines of a certain pattern.  Take MVC for example, now a days all developers understand it and most of the  underlying principles that accompany it.  This is because the frameworks they use force them to use MVC.

There was a proposal for a DI container to the Zend Framework.  While in discussion on whether or not to include the container in the framework the proposal was shutdown due to its complexity and small benefit to the framework itself.  Both were valid reasons to halt development.  However, I do believe that if a container were to be shipped with the framework we would see better code written by it’s users.  Better code leads to faster development time, which leads to feature filled projects, which then lead back to the framework, causing it to become more popular.  I really would like to see more PHP developers using DI, and I do believe that the Zend Framework team has the ability to make that happen.

Oh yeah, that would work

I came across Social History (code) today. In a nutshell, its a javascript plugin that allows you to see what social bookmarking sites each of your users visit. It removes the need of having to display a link to every social site on each of your pages. If a user doesn’t visit digg, don’t waste his screen space with a digg icon. Its a simple idea, it makes sense, and its genius.

More interesting, is how it works. It builds a list of links and puts them on the page somewhere, hidden, so the user cannot see them. Links that you have not visited are in blue, and links you have visited are in purple. The javascript then loops through all the links, and if a social bookmark site has a purple link, it knows you have visited it in the past.

Its nice to see this code being used in a productive way, but there is a pretty large privacy flaw that this code can easily start to abuse. Instead of tracking social bookmarking sites, it could be used to track sites you wouldn’t want anyone tracking, for example online banking sites, facebook pages, porn sites, and whatever else you want to keep private.

The good news is that it can only find the pages you have visited by asking your browser if you have visited a specific page. So in order for it to grab your entire history, it would have to ask your browser about each web page on the Internet, one by one. The bad news is that someone could pretty easily compile an extensive list of private web pages.

Personally, I say we patch this flaw. Lets stop displaying visited links in purple, unvisited links in blue. In other words, kill off a:visited. This is a pretty bold statement to make, but the security benefit outweighs the usability benefit in this scenario for me personally. It probably does for you too, when was the last time you went to a website and 1) saw the blue/purple links, and 2) thought ‘Oh good, I know which links of this site I’ve clicked and which ones I haven’t'? For me, that would be somewhere around 1999.

So yes, remove the a:visited property.

Open Source

I bought a G1 today and while going through the whole sales process with the t-mobile rep, she wouldn’t stop bringing up the fact that the software was all open source.  I am sure she did not have a  complete understanding of what it means for android to be open source, but it sure was great hearing non tech people rave about open source projects.

I believe that open source software is great in a situation where it is only a part of the package.  Make the android platform open source and let developers from all around the world contribute to it, which will result in better code, less bugs/exploits, faster development time, great documentation, and a community with a solid understanding of the system.  This won’t make money, in fact it may bleed money, but it will make an amazing platform with a ton of great applications, themes, and 3rd party addons.  Those extra features are going to keep customers happy, entertained, enthusiastic about the product.  Now customers will be willing to pay for the rest of the package, such a cell phone device, plan/minutes/data, and whatever other services and features can be cooked up by google… and all of those will make money.

As a programmer, I love using open source software for the reasons mentioned above.  I wish there was more open source projects in the mainstream market place that everyday users knew about.  Right now I think when people think of open source they think of dirty hippies wanting to give software away for free, which is so far from the truth (well, partly).  Hopefully android will turn open source into a house hold name and really push the open source business model further along.

Thanks UB

Recently UB has been following the whole ‘lets add a ton of pros to our site’ trend that FTP made popular.  Most TV pros suck, this is nothing new, but the types of TV pros that sign with UB (couldn’t make the cut with FTP/Stars) must REALLY suck.  Over the past few weeks these rejects have been running rampant over the place, bouncing between high and low, limit and no limit games.

This weekend one such pro really proved just how good he was and earned himself a note that read something along the lines of ‘play him until you die’.  I then go to throw him on my ultimate buddy list (a who’s online type thing for ub players).  I login to ultimate buddy and notice that in order to promote these new pros UB has added them to everyone’s buddy list.

That’s a few less screennames I’ll have to copy and past. Thanks UB!

WordPress 2.6.1

I just upgraded to the newest version of wordpress and it is pretty nice.  The whole point of this post is to see the new features…

One thing that immediately caught my eye was it updated my plugins via a 1 click upgrade feature.  This makes sense, since these plugs are simple scripts and fetching newest versions from a repository isn’t going to be a hard task with todays web tools.  However, it is kind of shocking that to upgrade the actual wordpress install I had to go to wordpress.com, download a compressed file, uncompress, sftp into my box, upload the newest files, and then run the upgrade script.  Completing these tasks isn’t rocket science, its not hard and it doesn’t take much time to complete, which is exactly why it should be automated/one-click-feature.  I wonder how many people overwrite their config files, misc themes, or plugins when trying to preform an upgrade.

Continuing with that thought, I have to do the same for uploading new plugins/themes.  In firefox, when I see a new plugin that I think ‘may be good, but will most likely suck’ I have no problem giving it a test drive.  I click a link, the plugin installs, firefox restarts, and right away I can play with the tool.  It takes a few clicks, which are all contained within firefox, and I dont have any files to clean up when I am done.  With wordpress I have to go through that entire downloading process, so if I am on the fence about a plugin or theme it is simply not getting installed.

The spell check seems to lag or not always check words.  This is very bad for someone like me (and pretty much every other retard on the internet).

I wish the text/post area would expand as I type.  I want to reread my post, I have to scroll up, scroll down, scroll up, etc.  It does have a drag/resize feature, but make it automatically gain height as I type.

Ok, this post is pretty negative and I certainly don’t want to come off as someone who is unsatisfied with this software, because its very good.  I guess its a lot easier to see the negative sides of software, since we probably take all the features for granted.

few things

Google is amazing… their approach to new software is simple and makes a lot of sense.

This is a good blog post.

Short Weekend

I didn’t get in any poker this weekend due to having a million other things to do. I was able to fit in a session today, but I wasn’t really playing too well so I cut it short. For the entire month I’ve been playing pretty much nothing but 2/4 and my results have been solid, running at about 15bb/100 over my last 20k. I’m going to force myself to get in another 10k before the month ends.

This weekend:

weekend.gif

I know exactly what you have and I know exactly what you are going to do with it.

I love this saying, it makes me giggle and feel all warm and fuzzy inside. Heres an example:

$2/$4 No Limit Hold’em - 4 players
Hand Converter Powered By DeucesCracked.com

BTN: $697.00
Hero (SB): $589.80
BB: $564.20
CO: $566.40

Pre Flop: Hero is SB with 2 club.gif 2 heart.gif
CO calls $4, BTN raises to $20, Hero calls $18, 1 fold, CO calls $16

Flop: ($64.00) 8 heart.gif 2 diamond.gif J spade.gif (3 players)
Hero checks, CO checks, BTN bets $45, Hero calls $45, CO folds

Turn: ($154.00) 9 heart.gif (2 players)
Hero bets $84, BTN calls $84

River: ($322.00) 2 spade.gif (2 players)
Hero checks, BTN bets $175, Hero raises to $440.80 all in …..

BTN in this hand is a little nitty. I just call the flop for a number of reasons, the most important being that the CO in this hand is a mega fish. If he calls this flop he is NEVER folding his hand. So doing anything that could potentially push him out of this pot is nothing less than retarded.

The turn lead is pretty standard for me. I don’t want this guy to take a free card with a draw he may have just picked up or try to control the pot with an overpair. Now, the really odd thing about this hand is my turn bet size. I thought about betting closer to 100% of the pot, but that puts us in an odd river spot if he calls. I would basically have to bet 100% of the pot again on the river, close to 100bb, and he will probably fold an overpair here taking that amount of heat from me. The goal here is to win his stack, so I figured betting around half the pot was correct. Heres why:

I can then check the river:

a) He will have a large enough stack for him to bet/bluff with his busted draw.

b) It will really confuse him and he will want to value bet his overpair, since now my line looks really strange. This is the primary goal of this hand, and since an overpair makes a huge part of his range now its also the most likely to happen. It is also going to confuse him even more when he gets check raised on the river. He will have no idea what to do, and ultimately since he is getting such a good price he will make a crying/wtf call. Yahtzee!

Both options A and B cover his entire hand range once he calls my turn bet. The river card changes nothing, it does not improve my hand one bit and the BTN should know that it also does not improve his hand, since I never have J9/89 in this spot.

In retrospect I absolutely should have bet a bit more on the turn, $100, just in case a river check raise fails. Also, I would only make this play against a player who I know is going to try to squeeze value out of his overpairs when I check this river. 90% of the people monkeys I play with would snap check this river and then be so happy/thankful they just won a pot if their hand holds up.


monkeys and trainwrecks

+

=

Next Page »