Zend Loader isReadable causing trigger error problem

I noted recently while writing a debugging error logging plugin for the Zend Framework that I was getting some E_WARNING’s logged in the database table it was utilising.

Having analysed the information a little further I realised that the framework was doing something rather funky. I had structured the application to be a modular layout as exemplified by the wiki guide for framework layout. I’d set up the module, controller and view components into their own directory (called “account”) and all was working fine. The Zend_Form was rendering correctly as I expected it to.

However, I noticed the logging utility was starting to fill up with fopen errors. Weird, i thought, as i’d not utilised fopen is any of my code. Having logged the line that was causing this error I was referred to the Zend Loader, line 160. Taking a quick look at it, i saw the supposedly “offending” @fopen sitting in the static isReadable() function. Thankfully I had a call traceback, and saw that it was attempting to open up a module/view/helpers/<file> file.

It struck me like a hammer blow to the head! The Zend Framework was being rather clever. It assumed that because I was working with an extended Zend_Form class, in a different module from the default, it would check all the view helpers for that modular component. Nice feature, bad E_WARNING! So obviously it was attempting to open files that didn’t exist, as a result throwing this error. Again, I took another look, the suppression token was there though, @ should be suppressing this error shouldn’t it? Apparently not!

Ok, so why use fopen? Why not use the is_readable() function that PHP provides. Ah! I realised what it was doing. fopen has a 4th parameter clause (optional) that allows the coder to specify whether to use the include_path’s. Obviously this allows an easy way to grab the file quickly from the included paths of the framework without too much hassle. No need to iterate through any directories.

So my answer was to use

set_error_handler(array(<class>,<function>), E_ALL^E_WARNING);

This allowed my utility to log all the errors thrown by PHP, but mitigate the logging of the WARNING errors. I’ve yet to determine if this will have a detrimental affect on the utility. I’ve not noticed any other warning errors being given off, but i’m sure there probably will be a few errors that will be missed because of this missing section.

So the lesson to be learned here is that if you use fopen with include_path and the file being searched for doesn’t exist, then you’ll get an E_WARNING thrown. It has been logged with the Zend Bug Tracker http://framework.zend.com/issues/browse/ZF-2985 with a few comments explaining various issues with the previous SVN releases of it. I also came across the Word_CamelCaseToDash error that another user pointed out after rewriting the function. I can only guess that this issue is caused by another component in the framework, which I suspect to be the dispatcher. Simply using file_exists is not an option as it doesn’t specify the directory to look in (i.e. it runs relative to the executed script), whereas fopen will utilise the include path. And rewriting it to iterate through the include path and check gives an error regarding being unable to find the correct controller. I can only imagine where else this function is tied in that causes this issue, possibly the Controller_Router_Route_Rewrite class?

At the current time it still remains an issue, and my only suggestion to get trigger_error() logging to work is to turn off E_WARNINGS.

Tags: ,

Leave a Reply