Book Review : Zend Framework in Action

April 10th, 2008

I signed up for the Manning early access program for Zend Framework in Action to get information on the ACL functionality in the framework and the book provided some useful examples. I was a bit underwhelmed by the content in the first release, but I guess that is to be expected when viewing a rough cut.

This release (the 2nd) is a vast improvement, and the book is really starting to come together. I like how the authors go into detail about testing, showing not only how to test your models, but also how to test controllers, and showing some common set up steps. It doesn’t cover all the details of testing, nor should it, but the book provides a solid background to build upon. This is refreshing compared to most books which simply mention testing and say whole books have been written about it.

The book does a good job of logically building upon previous examples, and I felt the flow was good when introducing more complex topics like Plugins and ActionHelpers. This version was updated to include Zend_Layout, including info on partials and ActionStack plugin, but the chapter on forms is not complete yet – looking forward to reading that when it comes out.

I thought the AJAX chapter was a little shaky. Maybe it’s me, but I felt the authors spent too much time going over a general ajax request sans the framework. By the time they work the framework into the equation, they are using an include file in a controller action to bring in some procedural code written earlier. And that procedural code lives in the models folder – it just doesn’t seem right to me. I think this would have been a good opportunity to use Zend_Filter, although it is used in later in the book when discussing Zend_Search_Lucene (the chapter on this is very thorough and easy to understand). Also, they recommend using separate controllers/actions for Ajax requests and not rendering the view in each action method. That’s fine, but I would also like to have seen using a Plugin in the dispatch loop to detect an Ajax request and automatically turn off Zend_View/Zend_Layout.

I like how the authors occasionally work in design patters, such as the registry, and the observer pattern in the search chapter. The authors describe using the observer pattern with hooks in the DB class (hooks which I didn’t know existed) to update the search index.

The chapter on deployment was good; most books don’t seem to tackle this. My only quibble is when discussing setting up virtual hosts, they say to make sure to enable AllowOverride to use .htaccess. I don’t have any problem with this, but since the book is talking about Virtual Hosts, they should recommend putting the redirects in the httpd.conf file, rather than relying on .htaccess, as it is more efficient due to the fact that Apache doesn’t need to read a file on every request.

At times I felt like there may be too much ancillary topics covered, however, after finishing the book, I felt overall it was good that topics such as testing, deployment, and version control were covered. While there isn’t enough information to provide in depth coverage, it exposures the reader to these topics and provides enough information to get started, rather than just briefly mentioning it. And the coverage of the different components with the Zend Framework is comprehensive and understandable. If you are looking at working with the Zend Framework, I would definitely recommend this book.

24% Percent of Users Can’t Find Google

March 28th, 2008

Over on usability guru Jakon Nielsen’s blog, he throws out a statistic that 24% of users in a recent study couldn’t navigate to google to perform a search - they either went to a different search engine or just failed. How you fail at that task is beyond me. Do you look at the browser, throw up your hands, and scream “I don’t know how to use the damn thing!!”.

I generally try not to be critical of non-tech savvy people, as I spend way too much time online and its only normal that things that make perfect sense to me can baffle other people. A couple of years ago a friend handed me a socket wrench when I asked for help on my car. He was amazed that I had no idea what to do with it - but hey, I had never done any work on a car engine, let alone even change the oil. It’s all perspective I guess. The scary thing about the study is this quote “Also, for this round of research we’re deliberately recruiting above-average users, so the success rate across all Internet users is probably lower than our finding.” If 24% of above average users can’t navigate to Google, then my perception of the web is way out of wack with the general population. I would have guessed in 1% to 2% range…

Loading Zend Config file for a Cron Job

March 23rd, 2008

The other day I talked about using Apache Environment variables to determine which section of a config file to use for a Zend Framework website. That works swimmingly, however, I had a cron job that was running for the same site, and since it was piped directly to php, Apache Environment variables were not an option. Fortunately, PHP has the function php_uname(’n') which will output the hostname of the computer. You can then load the appropriate config section based on that:


<?php
$environment 
= (php_uname(‘n’) == ‘rlbolton-desktop’) ? ‘development’ ‘production’;
$config = new Zend_Config_Ini(APP_PATH ‘configs/config.ini’$environment);

?>


Traits for PHP

March 17th, 2008

Via blog, found a link to a proposal for Traits in PHP. I wasn’t familiar with the practice, but as I read the proposal it struck a cord with me. I have been grappling with how to reuse certain functionality throughout disparate classes.

I looked at Mixins, which I also have been playing around with in JavaScript. Problem is, how do you combine a couple of mixins together. Say I am using the Zend Framework, and I have some classes that inherit from the Zend_Db_Table_Row and I want a couple to use some Mixin classes. Do I extend the Zend class for my Mixin, and extend my other classes off the Mixin? What happens if some of the classes need other functionality found in a different Mixin? Needless to say, it doesn’t seem like a great solution.

Lets jump into an example. I have a number of classes extending Zend_Db_Table_Row, and they all have a user entered attribute, like title or name, which gets turned into a SEO friendly url and saved to the database. Additionally, I don’t want the url to change, so there has to be code from preventing another developer from updating the url.For example,


<?php
class Article extends Zend_Db_Table_Row
{
    public function 
insert() {
         
$this->url $this->_createUrl();
         
parent::insert()
    }

     protected function _createUrl($name) {
       
//code to create the url - remove spaces, etc…
       
return $url
    
}
}

?>


How do I share that functionality across multiple classes, without using inheritance??

Data conversion Failed on MS SQL Import

February 23rd, 2008

The database was upgraded to MS SQL 9 and required me to use 2005 SQL Server Management Studio instead of Enterprise Manager. While trying to import a .csv file, I ran into a number of errors and spent awhile trying to figure out what the problem was. If you get a similar error, the problems seems (I say seem, because I am not a database guy and am simply guessing. Further exacerbating the problem is my extremely limited use of MS SQL) to be that the import tool isn’t allocating enough room for the strings going into certain columns. I.e it looks at the first 100 rows to determine how much space a typical field needs, and if a value goes way over that, it truncates the string and errors. This is the error message I got:

Error 0xc02020a1: Data Flow Task: Data conversion failed. The data conversion for column “ClickThroughURLValue” returned status value 4 and status text “Text was truncated or one or more characters had no match in the target code page.”.
(SQL Server Import and Export Wizard)

I tried to alter the values in the destination table, but that didn’t help at all. It turns out; you need to alter the OutputColumnWidth on the first screen. Since space and performance weren’t an issue for me, I just made the nvarchar quadruple the size it needed to be, so it could accommodate the random large string. One of the problems with the tool is it will error and fail on the insert when it encounters too big of a value, rather than just truncating and logging. This doesn’t seem like a huge issue, until you have a 15 gig .csv with over 4 million rows and it errors after 2 hours of importing… Below is a screenshot showing where the change needs to be made. Doing this will also alter the size of the column in the destination table and prevented the error for me.

MS SQL Error