Zend_Cache Dummy backend

Posted on Friday, November 27th, 2009 under , ,

I was working today on a caching system for one of our projects written using Zend_Framework. And, of course, in order to see what I was doing I needed to turn off the cache in the development stage. A task that proved to be more complicated that it would seem, as Zend_Cache doesn’t have a “turn off” feature. As pointed out by robo in this comment, Zend_Cache *does* have a turn off feature. Documented. There! On the first paragraph of the first page! Man l feel dumb :( Well…live and learn. Special thanks go to Robo47 for pointing out my error.

Setting the “caching” attribute to false in the caching frontend will stop Zend_Cache. Use this in your bootstrap:

/**
 * inits the cache
 *
 * @return void
 */
protected function _initCache() {
    $frontendOptions = array(
        'lifeTime'                => 60,
        'automatic_serialization' => true,
    );
 
    $backendOptions = array(
        'cache_db_complete_path'  => APPLICATION_PATH . '/cache/cache.sqlite',
        'automatic_vacuum_factor' => 5,
 
    );
 
    if(APPLICATION_ENV != 'development') {
        $frontendOptions['caching'] = false;
    }
 
    $cache = Zend_Cache::factory('Core', 'Sqlite', $frontendOptions, $backendOptions);   
    Zend_Registry::set('cache', $cache);
}

Simple as that. But if you don’t have anything better to do now, you can read original post (non edited) below and see how complicated a simple thing can get:

After looking dumb to the screen for several minutes – hoping that the problem will fix itself or something – I came to the conclusion that the easiest way to turn off the cache would be, in my case, to use a dummy cache backend, that doesn’t cache anything and always returns false when you try to fetch an object from it. Just like django has.

But Zend Framework doesn’t have such a class. It has a caching backend class called Zend_Cache_Backend_Test, but its method return stuff like ‘foo’ and ‘bar’. Really! They do! I don’t get this class’s purpose, as it’s clear that it can’t be used for testing. So I’ve decided to write my own dummy caching backend class and share it with my readers. It can be downloaded directly from my GitHub repository, by following this link Generic_Cache_Dummy.php.

The usage is quite simple, just add this to your bootstrap:

/**
 * inits the cache
 *
 * @return void
 */
protected function _initCache() {
    $frontendOptions = array(
        'lifeTime'                => 60,
        'automatic_serialization' => true,
    );
 
    $backendOptions = array(
        'cache_db_complete_path'  => APPLICATION_PATH . '/cache/cache.sqlite',
        'automatic_vacuum_factor' => 5,
 
    );
 
    if(APPLICATION_ENV != 'development') {
        $cache = Zend_Cache::factory('Core', 'Sqlite', $frontendOptions, $backendOptions);
    }
    else {
        $dummyBackend = new Generic_Cache_Dummy();
        $cache = Zend_Cache::factory('Core', $dummyBackend, $frontendOptions, $backendOptions);
    }
    Zend_Registry::set('cache', $cache);
}

…and, whenever you need to save/retrieve something from the cache, just do…

$cache = Zend_Registry::get('cache');
if(!($object = $cache->load($cacheKey))) {
	// bla bla bla...fetch object
	$cache->save($object, $key);
}
 
return $object;

Happy caching!

Zend Framework and web hosting services

Posted on Tuesday, November 24th, 2009 under , ,

Let’s face it. We can’t all buy or rent our own servers. It’s not cost effective. So we turn to hosting companies – always the popular choice. But when you’re using an shared hosting service, you can’t make changes in the server’s configuration file. You usually get a writeable directory in a location like

/home/{your-username}/public_html/

…and a Cpanel account to manage your share of the server, emails, databases and so on. And…that’s about it. You can’t point your webroot to the public directory as taught in Zend Framework’s manual, all your library files will be exposed to the public and so on. What to do then? The answer is simple: .htaccess and mod_rewrite. Usually, hosting companies install mod_rewrite and set AllowOverride to true, so this solution will work in the vast majority of cases.

Upload via FTP or SSH your content into your public_html, wwwroot or www directory (the webroot directory, whatever its name may be). Then add 4 htaccess files, one directly in the web root, one in the public directory and one in all other folders. It should look something like this (without the numbers, of course).

public_html/
     /public
       .htaccess (2)
     /application
        .htaccess (3)
     /library
        .htaccess (3)
    .htaccess (1)

Now, the first htaccess file – #1 – should contain the following:

RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]

…this will redirect the traffic from this folder to the public/ sub-folder. The second .htaccess – the one in the public folder – should be the .htaccess file shipped with Zend Framework. It usually looks like this:

SetEnv APPLICATION_ENV production 
 
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

And the .htaccess files located in all other directories – #3 – should simply forbid access to their respective folders, like such:

deny from all

Worked for me :)

Debugging PHP with FirePHP on Zend Framework

Posted on Thursday, October 1st, 2009 under , , , ,

firephpYou know the saying: if debugging means taking the bugs out, then programming means putting them in. Yes. We all have bugs in our code. And since not all of them can be marketed as “undocumented features”, from time to time we have to debug our applications.

The best debugger for PHP I’ve used so far is Zend’s. Zend Platform together with Zend Studio constitutes a very good development environment and a great debugging environment. Due to the fact that Zend Studio is a little pricey, I don’t use it any more, instead I’m using a highly customised vim. This makes a great development environment, but unfortunately isn’t not that great when debugging. I know you can use vim with Xdebug, but it’s quite a chore, and I don’t like it. Since old school debugging with var_dump() or print_r() is out of the question, I was looking for another way to debug my applications. And I’ve found just the thing: FirePHP. It’s a Firefox extension, just like FireBug – that can receive debug information from the server.

Since I do most of my bugging programming on Zend Framework, I also need debugging for this platform. I use the OOP based bootstraping method, where you extend your Bootstrap class from Zend_Application_Bootstrap_Bootstrap. And in the .htaccess file of the /public/ directory, I have an envelope with the current state of application (usually on of development/staging/production):

SetEnv APPLICATION_ENV development

Normally, I need the debug information only when the application is in the “development” state, so I’m using this method in the Bootstrap class.

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
    // Bootstrap other components
 
    /**
     * inits FirePHP for debugging
     *
     * @return void
     */
    protected function _initFirebugDebugger() {
        if(APPLICATION_ENV == 'development') {
            // don't debug while not in "development"
            $logger = new Zend_Log();
            $writer = new Zend_Log_Writer_Firebug();
            $logger->addWriter($writer);
 
            Zend_Registry::set('logger',$logger);
        }
    }
}

I also like to have some syntactic sugar when developing, so I’ve define this function in the Bootstrap.php file. Yes, I know that this might be perceived as a blasphemy by some of the OOP purists out there, but I really don’t care. If you don’t want non-OOP “stains” on your code, simply create a YourApplication_Utility_Firebug class or whatever with a static debug() method and paste the code in it.

/**
 * syntactic sugar for logging errors
 * and debug messages to FireBug
 *
 * @param string $message
 * @param int $label
 * @return void
 */
function fb($message, $label = null) {
    if($label != null) {
    	$message = array($label, $message);
    }
 
    if(Zend_Registry::isRegistered('logger')) {
    	Zend_Registry::get('logger')->log($message);
    }
}

And now, any time you need to debug something, simply type:

fb($variable);
fb($_POST); // and so on

And all these variables will be sent to Firefox’s FirePHP toolbar and you can inspect them from there. For even better results, you can also send debug information from your ErrorController to FirePHP (comes in handy when using Ajax).

PS: I’ll have a look into FireLogger for PHP. It also look pretty interesting, although it’s only in Beta.

Zend Framework SameAs validator

Posted on Tuesday, September 29th, 2009 under , ,

While working on a Zend Framework project, I’ve found myself in need of a “same as” validator. If you’re familiar with Zend Framework’s form system, then you know what a validator is, if not, enhance your knowledge on the topic by reading this page from ZF’s manual.

My validator was supposed to check if the same value was entered into two password fields, to avoid the user’s typos in passwords. You know, those annoying “please re-type your password” fields. At the time, I couldn’t find a good validator for this purpose, so I’ve decided to write my own. The source code is available on Git Hub, here.

It’s quite easy to use:

// create some filters
$stringTrimFilter = new Zend_Filter_StringTrim();
$stripTagsFilter = new Zend_Filter_StripTags();
 
// other validators
$notEmptyValidator = new Zend_Validate_NotEmpty();
$notEmptyValidator->setMessage('This field is required');
 
// create the SameAs validator
$sameAsValidator = new Generic_Validate_SameAs();
$sameAsValidator->setMessage('The 2 fields do not coincide', Generic_Validate_SameAs::NOT_THE_SAME);
 
// create the main password field
$password = new Zend_Form_Element_Password('password');
$password->setOptions(
    array(
        'label'       => 'Password',
        'required'   => true,
        'filters'      => array($stringTrimFilter, $stripTagsFilter),
        'validators' => array($notEmptyValidator),
    )
);    
 
 
// add this field to the SameAs validator
$sameAsValidator->setElement($password);
 
// create the new 
$validateNewPassword = new Zend_Form_Element_Password('validateNewPassword');
$validateNewPassword->setOptions(
    array(
        'label'        => 'Re-type the password',
        'required'   => true,
        'filters'      => array($stringTrimFilter, $stripTagsFilter),
        'validators' => array($notEmptyValidator, $sameAsValidator), // add it as a validator to the second field
    )
);

If the value entered in the second field isn’t the same as the value entered in the first field, the validator will signal an error. Simple as that.

Zend_Db quoteInto() with multiple arguments

Posted on Thursday, May 21st, 2009 under ,

Zend Framework has some weird “features” so to say, which pop out from time to time and get the programmers really annoyed. The latest thing quoteInto() method of Zend_Db_Adapter_Abstract class. This is supposed to quote input variables prior to entering them into a SQL command to avoid SQL injection attacks. Sounds cool, doesn’t it? Well…not quite. Because, because it can only quote one argument.

You can’t write:

// note: I usually extend my models from the Zend_Db_Table_Abstract class
// this code should be executed in a model of a such model
$select = new Zend_Db_Select($this->_db);
$select->from($this->_name);
$select->where($this->_db->quoteInto('(a = ? AND b = ?) OR (c != ?)', $a, $b, $c);

…as this won’t work. Of course, there’s a really lame approach, to concatenate the output from multiple quoteInto() calls. Like such:

$select->where(
    $this->_db->quoteInto('(a =? AND ', $a) .
    $this->_db->quoteInfo('b = >)', $b) . 
    $this->_db->quoteInfo(' OR ( c != ?)', $c)
);

As I said, extremely lame. What’s to do then. Well, when I’ve hit this roadblock, I’ve opted for prepared statements. Of course, they brake the OOP encapsulation of SQL queries but if you don’t need to alter the query later it’s okay. So:

$stmt = $this->_db->prepare( 'SELECT * FROM ' . $this->_name . ' WHERE (a = ? AND b = ?) OR (c != ?)');
$stmt->execute(array($a, $b, $c));

This also works when you need to write custom sql queries:

$stmt = $this->_db->prepare('INSERT INTO ' . $this->_name . ' (first, second) VALUES (?, ?) ON DUPLICATE KEY UPDATE first = first + 1');
$stmt->execute(array($first, $second));

A decent workaround to the quoteInto() problem…

Zend_Tool

Posted on Wednesday, May 20th, 2009 under ,

Zend Framework I’ve downloaded the 1.8 version of Zend Framework and looked over Zend_Tool these last days. What can I say. What is there to say. Zend_Tool is cvasi-useless. You can use it to create a new project, as a shortcut to cp -r :) . It also generates a xml file with all the project’s data, which is really useless, I mean, you can’t do anything with that file, there aren’t any tools that use it. You can use it to add methods and controllers (it also creates the associated views) – again nothing that a 10 lines python script can’t do.

It lacks all the “good” features such a tool should have. What I expect from the next release of Zend_Tool is:

  • automatic form generation based on a database table’s structure, like CakePHP’s bake and scaffolding
  • easier customisation – I don’t want to write a Zend_Tool based application and use it to write my Zend Framework app
  • allow usage of a custom coding standard (I use tabs for indenting, not 4 spaces)
  • much, much better documentation

And now for something positive, I really like the new bootstrapping system they’ve introduced in the 1.8 release.

Styling Zend_Form

Posted on Friday, April 24th, 2009 under , ,

As a Zend Framework user I use a lot the Zend_Form component to render my forms. I like it, it’s easy to use, pretty versatile and comes with lots of ready built filters and validators meant to make life easier. But the problems with Zend_Form begin when one tries to style it. Problem partially solved by the developers of ZF with the use of the decorator pattern.

Using decorators, the form’s elements can be wrapped in custom HTML tags and alter the way the form displays.

But in some cases, for example when you want each element of the form to have its custom markup, to have 3 elements on the first line and 2 on the second or you want to have all the errors grouped in a single area like in Drupal, the decorator pattern fails. Bad. What to do then? Stop using Zend_Form? Or hacking it? If the second choice sounds better, then keep reading :P Keep reading»

PHP Geek Meet

Posted on Sunday, March 22nd, 2009 under , , ,

I’ve attended the first PHP GeekMeet in Cluj (for those of you that are geographically impaired, this is Cluj). I’ve held a presentation on Zend Framework, a long yet not as boring as I thought, 2 hours long presentation. My colleague Alex Novac from Zitec also held a presentation about optimisation techniques in PHP and disassembled a simple == operator call to see what happens below . The other presentation, although not strictly PHP related, was held by Andrei Gheorghe on scalability techniques.

I consider this edition of GeekMeet to be a succes and I congratulate Mihai for it.

PS: my presentation can be downloaded here.

Geek Meet

Posted on Monday, March 2nd, 2009 under , ,

geekmeetI’m going to hold a presentation about Zend Framework at PHP Geek Meet in Cluj, Romania. Everyone’s invited.


Read more about the meeting here – link available only in Romanian.

Zend Framework and hidden fields

Posted on Tuesday, February 17th, 2009 under , ,

One thing I really hate about forms in Zend Framework is the fact that the hidden fields are displayed as blank lines – sounds stupid but this is what really happens – and if you have more than one – let’s say 4 or 5 – their presence can become really annoying and ruin the layout. This happens because although the hidden fields aren’t shown by the browser, their wrapping tags are. ZF wraps all the form elements in additional markup with the help of decorators. The default XHTML for a hidden field in a Zend_Form looks something like this:

<dt>&nbsp;</dt>
<dd><input type="hidden" id="myElement" name="myElement" /></dd>

The definition tags have display:block, so they insert a lot of empty spaces in the layout. Which in the end will make the designer very unhappy. The solution is to remove all the definition tags or to hide them. Since this is presentational matter, it should fall to a view helper. The first idea was to remove the tags completely for hidden fields. Like such:

class Motanelu_View_Helper_FormFixer {
    public function formFixer( Zend_Form $_form ) {
        foreach( $_form->getElements() as $element ) {
            if( $element instanceof Zend_Form_Element_Hidden ) {
                $element->removeDecorator( 'HtmlTag' );
                $element->removeDecorator( 'Label' );
            }
        }
        return $_form;
    }
}

…and in the view (assuming that the helper is the the right path and will be picked out automatically by Zend Framework)…

echo $this->formFixer( $this->form );

Should do the trick. And it does. A lame trick :) If there are more elements in the form, the resulting markup will look something like this:

<form enctype="application/x-www-form-urlencoded" action="" method="post">
    <dl class="zend_form">
        <dt><label for="name" class="optional">Enter your name</label></dt>
        <dd><input type="text" name="name" id="name" value="" /></dd>
        <input type="hidden" name="id" value="" id="id" />
        <dt>&nbsp;</dt>
        <dd><input type="submit" name="submit" id="submit" value="Go go go!" /></dd>
    </dl>
</form>

Yep, that’s right! Invalid code. Not good. Another approach would be to hide the dt and dd tags that wrap around hidden fields with CSS. First attempt:

class Motanelu_View_Helper_FormFixer {
    public function formFixer( Zend_Form $_form ) {
        foreach( $_form->getElements() as $element ) {
            if( $element instanceof Zend_Form_Element_Hidden ) {
                foreach( $element->getDecorators() as $decorator ) {
                    $decorator->setOption( 'class', 'hidden' );
                }
            }
        }
        return $_form;
    }
}

But this doesn’t work as expected. The code above will produce:

<dt>&nbsp;</dt>
<dd class="hidden"><input type="hidden" name="id" value="" id="id" /></dd>

The dt doesn’t have the hidden class added to it. After some debugging, I’ve found why. It’s not a bug, it’s an…well…undocumented feature of Zend Framework.

// Zend_Form_Decorator_Label - line 306
if (!empty($label)) {
    $options['class'] = $class;
    $label = $view->formLabel($element->getFullyQualifiedName(), trim($label), $options); 
} else {
    $label = '&nbsp;';
}

I’m very curious who is the rocket scientist that came up with this idea and more important why. Why shouldn’t I be allowed to change the class of an empty label? Well, never mind…But since it’s a very bad practice to change a framework’s source code, I’ve looked for a workaround. And found one: if the element doesn’t have a label, I’ll add a blank one. Like such:

class Motanelu_View_Helper_FormFixer {
    public function formFixer( Zend_Form $_form ) {
        foreach( $_form->getElements() as $element ) {
            if( $element instanceof Zend_Form_Element_Hidden ) {
                $label = $element->getLabel();
                if( empty( $label ) ) {
                    $element->setLabel( '&nbsp;' );
                }
                foreach( $element->getDecorators() as $decorator ) {
                    $decorator->setOption( 'class', 'hidden' );
                }
            }
        }
        return $_form;
    }
}

After adding the following code to my CSS file

.hidden {
    display: none;
}

…I can finally say that it works, that all the hidden fields stay hidden and that the resulting markup will validate even against the draconian XHTML Strict specification of the W3C.