The Developer Day | Staying Curious

TAG | zend

Mar/10

10

Zend Framework Advanced Error Controller

The default Zend Framework Error Controller generated by Zend_Tool is quite simple. It displays a simple error message, sets a response status and if exception display is enabled in the current environment, an exception message, stack trace and request variables are displayed.

While such a standard error controller may work well for many web applications it may not be suitable for everyone. The main disadvantage of the default error controller is that it does not notify developers of the errors that occurred and instead silently logs them. Many enterprise web applications will find this unacceptable and will try to implement their means of solving the issue. In this post I’ll try to show how a more advanced Zend Framework error controller could be implemented to help developers tackle errors quickly.

class ErrorController extends Zend_Controller_Action
{
    private $_notifier;
    private $_error;
    private $_environment;

    public function init()
    {
        parent::init();

        $bootstrap = $this->getInvokeArg('bootstrap');

        $environment = $bootstrap->getEnvironment();
        $error = $this->_getParam('error_handler');
        $mailer = new Zend_Mail();
        $session = new Zend_Session_Namespace();
        $database = $bootstrap->getResource('Database');
        $profiler = $database->getProfiler();

        $this->_notifier = new Application_Service_Notifier_Error(
            $environment,
            $error,
            $mailer,
            $session,
            $profiler,
            $_SERVER
        );

        $this->_error = $error;
        $this->_environment = $environment;
   }

    public function errorAction()
    {
        switch ($this->_error->type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->message = 'Page not found';
                break;

            default:
                $this->getResponse()->setHttpResponseCode(500);
                $this->_applicationError();
                break;
        }

        // Log exception, if logger available
        if ($log = $this->_getLog()) {
            $log->crit($this->view->message, $this->_error->exception);
        }
    }

    private function _applicationError()
    {
        $fullMessage = $this->_notifier->getFullErrorMessage();
        $shortMessage = $this->_notifier->getShortErrorMessage();

        switch ($this->_environment) {
            case 'live':
                $this->view->message = $shortMessage;
                break;
            case 'test':
                $this->_helper->layout->setLayout('blank');
                $this->_helper->viewRenderer->setNoRender();

                $this->getResponse()->appendBody($shortMessage);
                break;
            default:
                $this->view->message = nl2br($fullMessage);
        }

        $this->_notifier->notify();
    }

    private function _getLog()
    {
        $bootstrap = $this->getInvokeArg('bootstrap');
        if (!$bootstrap->hasPluginResource('Log')) {
            return false;
        }
        $log = $bootstrap->getResource('Log');
        return $log;
    }
}

The modified error controller is aware of the environment it is running in. It’s likely that depending on the environment you would want to display different layouts with different information. For example while debugging Zend Controller Tests you may want to reduce the amount of HTML appearing in your terminal screen by disabling the layout while running in the test environment. You’ll also notice the Application_Service_Notifier_Error class dependency. This class is responsible for deciding whether to send an email to the developers and gathers potentially helpful information from different sources. You’ll also notice how the dependencies for the notifier are instantiated. It can be done in different ways using dependency injection frameworks, using bootstrap resources and so on. It’s up to you to decide what fits your application better.

class Application_Service_Notifier_Error
{
    protected $_environment;
    protected $_mailer;
    protected $_session;
    protected $_error;
    protected $_profiler;

    public function __construct(
        $environment,
        ArrayObject $error,
        Zend_Mail $mailer,
        Zend_Session_Namespace $session,
        Zend_Db_Profiler $profiler,
        Array $server)
    {
        $this->_environment = $environment;
        $this->_mailer = $mailer;
        $this->_error = $error;
        $this->_session = $session;
        $this->_profiler = $profiler;
        $this->_server = $server;
    }

    public function getFullErrorMessage()
    {
        $message = '';

        if (!empty($this->_server['SERVER_ADDR'])) {
            $message .= "Server IP: " . $this->_server['SERVER_ADDR'] . "\n";
        }

        if (!empty($this->_server['HTTP_USER_AGENT'])) {
            $message .= "User agent: " . $this->_server['HTTP_USER_AGENT'] . "\n";
        }

        if (!empty($this->_server['HTTP_X_REQUESTED_WITH'])) {
            $message .= "Request type: " . $this->_server['HTTP_X_REQUESTED_WITH'] . "\n";
        }

        $message .= "Server time: " . date("Y-m-d H:i:s") . "\n";
        $message .= "RequestURI: " . $this->_error->request->getRequestUri() . "\n";

        if (!empty($this->_server['HTTP_REFERER'])) {
            $message .= "Referer: " . $this->_server['HTTP_REFERER'] . "\n";
        }

        $message .= "Message: " . $this->_error->exception->getMessage() . "\n\n";
        $message .= "Trace:\n" . $this->_error->exception->getTraceAsString() . "\n\n";
        $message .= "Request data: " . var_export($this->_error->request->getParams(), true) . "\n\n";

        $it = $this->_session->getIterator();

        $message .= "Session data:\n\n";
        foreach ($it as $key => $value) {
            $message .= $key . ": " . var_export($value, true) . "\n";
        }
        $message .= "\n";

        $query = $this->_profiler->getLastQueryProfile()->getQuery();
        $queryParams = $this->_profiler->getLastQueryProfile()->getQueryParams();

        $message .= "Last database query: " . $query . "\n\n";
        $message .= "Last database query params: " . var_export($queryParams, true) . "\n\n";

        return $message;
    }

    public function getShortErrorMessage()
    {
        $message = '';

        switch ($this->_environment) {
            case 'live':
                $message .= "It seems you have just encountered an unknown issue.";
                $message .= "Our team has been notified and will deal with the problem as soon as possible.";
                break;
            default:
                $message .= "Message: " . $this->_error->exception->getMessage() . "\n\n";
                $message .= "Trace:\n" . $this->_error->exception->getTraceAsString() . "\n\n";
        }

        return $message;
    }

    public function notify()
    {
        if (!in_array($this->_environment, array('live', 'stage'))) {
            return false;
        }

        $this->_mailer->setFrom('do-not-reply@domain.com');
        $this->_mailer->setSubject("Exception on Application");
        $this->_mailer->setBodyText($this->getFullErrorMessage());
        $this->_mailer->addTo('alerts@domain.com');

        return $this->_mailer->send();
    }
}

This class provides an extensive report providing helpful details in what state the application was when an exception occurred. What’s the IP address of the server (maybe the application is distributed on many servers), what was the time, was it an AJAX request, what was user’s session data, request data.

One of the nice things to have is to be able to tell what was the last database query executed. This is especially useful if some dynamic database query fails or someone is trying to make an SQL injection. The easiest way to achieve this is to use a Zend_Db_Profiler. But the default profiler consumes a lot of server resources and should not be enabled on production environments. To work around this we use a custom dummy profiler that does no profiling at all and just stores the last query information in memory.

class Application_Db_Profiler extends Zend_Db_Profiler
{
    protected $_lastQueryText;
    protected $_lastQueryType;

    public function queryStart($queryText, $queryType = null)
    {
        $this->_lastQueryText = $queryText;
        $this->_lastQueryType = $queryType;

        return null;
    }

    public function queryEnd($queryId)
    {
        return;
    }

    public function getQueryProfile($queryId)
    {
        return null;
    }

    public function getLastQueryProfile()
    {
        $queryId = parent::queryStart($this->_lastQueryText, $this->_lastQueryType);

        return parent::getLastQueryProfile();
    }
}

The custom error controller will only notify developers of errors that occur on production and stage environments to avoid spamming people with exceptions from the unstable development environment. The Application_Service_Notify_Error class is also highly testable. All the dependencies can be mocked, no global variables or constants are used. The class itself could be more refined by employing polymorphism instead of if statements but I believe it’s better to keep the example simple to make it easily understandable.

Depending on which version of the Zend Framework is being used the implementation for the custom error controller may be a little different, but the general idea is the same. In short the advanced error controller provides additional information such as session data, database queries, server variables and also is capable of notifying developers when errors occur on production or stage environments. Please let me know if this is helpful by providing feedback in the comments.

, , , , Hide

Feb/10

20

Zend Framework Database Profiler Reporting

Zend Framework has a powerful Database Profiler component. It is remarkably simple to integrate the database profiler with the Zend Framework front controller with the use of Firefox addons FireBug and FirePHP:

// In your bootstrap file

$profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);

// Attach the profiler to your db adapter
$db->setProfiler($profiler);

Or just by enabling it in the database configuration:

$db = array(
    'type' => 'pdo_mysql',
    'host' => 'localhost',
    'dbname' => 'dbname',
    'username' => 'username',
    'password' => 'password',
    'profiler' => array(
        'enabled' => true,
        'class' => 'Zend_Db_Profiler_Firebug',
    )
);

Producing nicely formatted results:

Firebug profiler is great tool. But it requires to use Firefox and have FireBug and FirePHP addons installed. Not everyone in your organization may be Firefox users or have these addons installed. Another drawback is that sometimes queries may be quite big and complex. It’s not easy to analyse them in a Firebug window or to copy them to an editor that supports SQL highlighting.

To solve that it is possible to create a custom database profiler reporting mechanism. To output the profiler queries I’ll create a custom Zend Framework action helper:

class Company_Product_Helper_Profiler extends Zend_Controller_Action_Helper_Abstract
{
    protected $_profiler;
    protected $_view;
    protected $_config;
    protected $_db;

    public function __construct(Zend_Config $config, $db)
    {
        $this->_config = $config;
        $this->_db = $db;
    }

    public function init()
    {
        $this->_view = new Zend_View();

        parent::init();
    }

    public function postDispatch()
    {
        $this->_profiler = new Company_Product_Db_Profiler_Report($this->_db1);

        if (!$this->_isProfilerEnabled()) {
            return false;
        }

        $this->outputToScreen();
    }

    protected function _isProfilerEnabled()
    {
        if ($this->_config->environment == 'live') {
            return false;
        }

        if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) {
            return false;
        }

        $profiler = $this->getRequest()->getParam('profiler');

        if (!empty($profiler)) {
            return true;
        }

        return false;
    }

    protected function outputToScreen()
    {
        $this->_view->headLink()->appendStylesheet('/css/highlight/default.css', 'screen');

        $this->_view->headScript()->appendFile('/js/highlight.pack.js');
        $this->_view->headScript()->appendScript('
            hljs.tabReplace = \'    \';
            hljs.initHighlightingOnLoad();
        ');

        $this->getResponse()->appendBody($this->_profiler);
    }
}

The action helper uses a post dispatch hook. The post dispatch hook is called after the Zend Framework dispatcher dispatches a request. A post dispatch hook is used to ensure that all queries have been run and to integrate the profiler with the Front Controller without changing any of the controller classes.

Action helper profiler checks to see if any profiling information should be outputted. It checks if the current configuration environment is not production to not allow unauthorized people to use the profiler. It also checks if a request is not an AJAX request, since AJAX requests may be returning JSON data structures and any additional output can break the client which sent the request. Profiler can be enabled by adding a URL query parameter ?profiler=1.

To highlight the SQL queries profiler uses a third party JavaScript highlighting library Highlight.js. On page load highlight.js finds all <code> nodes in the DOM structure, detects the programming or markup language type of the content inside them and highlights it.

The profiler action helper also uses another class to format the profiler report. The profiler report class implements an iterator interface and the __toString method allowing to use it in different ways. It could also be used to format profiler output for environments such as terminals which can’t interpret HTML.

class Company_Product_Db_Profiler_Report implements Iterator
{
    protected $_profiler;
    protected $_html = false;
    protected $_position ;

    public function __construct($db, $html = true)
    {
        $this->_profiler = $db->getProfiler();
        $this->_html = $html;
        $this->_position = 0;
        $this->_profiles = $this->_profiler->getQueryProfiles();
    }

    public function setOutputFormatToHtml($value)
    {
        $this->_html = !empty($value);
    }

    public function __toString()
    {
        $out = "";

        if ($this->_html) {
            foreach ($this->_profiles as $key => $query) {
                $out .= $this->_formatProfileAsHtml($key, $query);
            }
        } else {
            foreach ($this->_profiles as $key => $query) {
                $out .= $this->_formatProfileAsText($key, $query);
            }
        }

        return $out;
    }

    protected function _formatProfileAsHtml($key, $query)
    {
        $out = "<pre><code>{$key}. " . wordwrap($query->getQuery(), 150) . "\n\n ({$query->getElapsedSecs()} s.) </code> </pre>";
        return $out;
    }

    protected function _formatProfileAsText($key, $query)
    {
        $out = "$key. {$query->getQuery()} ({$query->getElapsedSecs()} s.)\n\n";
        return $out;
    }

    public function rewind()
    {
        $this->_position = 0;
    }

    public function current()
    {
        if ($this->_html) {
            return $this->_formatProfileAsHtml($this->_position, $this->_profiles[$this->_position]);
        } else {
            return $this->_formatProfileAsText($this->_position, $this->_profiles[$this->_position]);
        }
    }

    public function key()
    {
        return $this->_position;
    }

    public function next()
    {
        ++$this->_position;
    }

    public function valid()
    {
        return isset($this->_profiles[$this->_position]);
    }
}

To make Zend Framework aware of the profiler action helper add the following lines of code to the bootstrap file:

Zend_Controller_Action_HelperBroker::addHelper(
    new Company_Product_Helper_Profiler($config, $databaseConnection)
);

When done the output of the profiler should look something like this:

, , , , , Hide

Zend Framework 1.8 book As I mentioned earlier guys from Packt publishing asked me to review a recently published book Zend Framework 1.8 Web Application Development. The title says it all – it’s a book about designing and developing PHP web applications using Zend framework.

This book doesn’t require the reader to be familiar with zend framework and explains all concepts in proper detail, though it will be easier to read the book if the reader is familiar with the framework and/or has experience with MVC and OOP in general. This book should be interesting to all developers who design and develop day to day web applications using MVC frameworks or not yet familiar with them as it may improve their insights towards web applications modelling, testing , optimizations and more.

Even though I am fairly familiar with the framework I found the book to be an interesting, easy read, plentiful of examples explaining the intricacies of the framework.

The first though a very important chapter teaches the concept of bootstrapping using Zend_Application and shows how to write and run a simple hello world program using controllers and views. As well it introduces the use of controller utility methods such as _getParam(), _forward(), _redirect(), action helpers, view helpers which are very valuable and a lot of developers miss them entirely. This chapter also shows the proper use of the response object which also tends to get forgotten.

The second chapter dives straight into the Front Controller pattern explaining how the framework routes, dispatches requests and responds to the client. I have never been bothered to understand the whole thing and was quite surprised to see how simple it all is. It is worth mentioning that this chapter explains in great detail how the router and various routes work and how elegantly it integrates with Zend_Config. Last the chapter covers the request object and it’s external API which provides lot’s of valuable functionality.

From the third chapter author Keith Pope starts building the main application of the entire book, the Storefront. It’s a relatively simple “real life” application that serves the purpose of being an online products catalog. This chapter shows how such an application is structured on a file system and bootstrapped and configured.  Even more the chapter covers the creation of Zend_Log and various logging writers and database profiling. Extremely valuable features that not many developers know of. If every zend framework application would start as the chapter describes I believe a lot more developers would be eager to start their IDE’s 9:00 AM straight.

Next is my personal favorite chapter – Models. Zend Framework does not have a base Model class and there’s a pretty good reason why it doesn’t. Models are specialized for a certain business task and as such it is arguably impossible to make a generic model implementation that would fit all sizes well. It then might raise a question what’s there to read about? It is my personal belief that web applications modelling has lost focus during the years by the ever growing development community. Developers got their minds focused on the next “new” thing. Let it be template engines, ORM’s, rise of active record and ruby on rails, ajax and javascript frameworks. While the majority of the models “out there” are deeply crippled. Hundreds of books were written explaining how to manage the complexity of the problem so a single chapter is a mighty challenge. I believe the author made a great choice by explaining the concept of the fat model, skinny controller, explaining the benefits composition over inheritance, data access layer separation from the business layer and my deepest respect for introducing domain model design, Martin Fowler’s book Patterns of Enterprise Application and Eric Evan’s book Domain Driven Design also known as DDD.

Next five chapters describe the implementation of the Storefront application. Each chapter highlights a major component of the framework. Use of resource autoloaders, plugins, Zend_Form, Zend_Auth, Zend_Acl. Before saying anything else it is very important to say that books rarely ever show hardcore “real life” applications as examples. Even Fowler himself likes to skip certain topics like validation in certain sections of his famous book just because they complicate things too much. This book is no exception to the rule. It’s a pretty straightforward application. There isn’t a single join to another table or a GROUP BY statement in SQL, forms implemented with Zend_Form are rather simple with little if any javascript / ajax. I found it a bit disturbing that class create other classes having both business and factory logic. One of the ugly examples was where a getPrice() method on a product model creates it’s own Taxation service which could not be mocked if that class would need to be unit tested. In most of the cases author provides injection methods for unit testing but I would argue that it does not show class dependencies explicitly which is very valuable for unit testing. Besides that I really enjoyed how the author decided to go with ACL in the domain layer. This would more often than not be implemented in the controllers making the model tightly dependent on the controllers. All in all keeping in mind that it’s a tutorial application introducing the framework I’m highly satisfied of it’s overall quality. Repeating myself. If every zend framework application would be so well written..

Another chapter worth mentioning is regarding optimizations. I was surprised to learn about such things like plugin loader cache, table gateway metadata or various Zend_Cache frontends which I have never bothered to look up. Not to mention widely known tricks using APC, stripping zend framework of all requires and setting up an optimized include path.

And last but not least again one of my favorite topics – testing. I strongly agree with Misko Hevery that test driven development is a skill. It’s definitely not easy to start or learn. One would fool himself to think otherwise.  This topic deserves many books of it’s own. I can only share from my own experience – once I started unit testing applications that I work with, I have never looked back. This chapter explains different types of testing, shows how to setup PHPUnit and provides examples of controller testing using Zend_Test. I believe this chapter deserves more attention on how to do testing with a database in mind, debugging failing controllers, avoiding complicated mocks, implementing continuous integration. But again it is worth to keep in mind that the book is about Zend Framework and not testing in general.

All in all I enjoyed reading this book. I would and will recommend it to my colleagues and friends. I hope that this hopefully not too boring review convinced you to buy the book and learn something new. Once again – big thanks to Packt Publishing for a free book. Happy reading. Over and out.

, , , , Hide

Zend Framework 1.8 bookI was recently asked by Packt Publishing to review a copy of one of their books called Zend Framework 1.8 Web Application Development book. This book is about designing, developing and deploying feature-rich PHP MVC based web applications using Zend framework. Guys from Packt Publishing were generous to send me a hard copy of the book. I owe them a thanks.

Even though I feel fairly familiar with Zend Framework I believe this book will be a great opportunity to dwell into the darker corners of the framework. The fact the Zend Framework is now at version 1.9.5 and version 2.0 is on the horizon is a bit worrying but having had a quick glimpse at the table of contents I see that some topics of particular interest to me like chapters about model design, optimizations and testing are not the ones that change at the same pace as the framework does which makes this book even more worthwhile to read.

I believe I will have a great time reading and reviewing this book.

, , , , Hide

Dec/08

31

Benchmarks battle: Yii vs. Zend Framework

While browsing through planet-php.org like every morning I’ve found this blog post promoting Yii framework. Interested I took a look at Yii benchmarks page and got really surprised.

To be honest benchmarking frameworks on a hello world application is a bit unfair. A hello world application requires very little complexity from the the framework. Zend Framework is a very powerful framework that has many strengths. A test should do something realistic. For example connecting to a database, having a configuration file, properly rendering a view, having a model to retrieve data, doing something with it, rendering a layout, trying some plugins or other components like pagination. It requires more work to do such applications, but that is a good way to do a fair benchmark.

Not related to benchmarking but I couldn’t help but notice that Yii benchamarks die in controller actions. It is not best the best thing to do. It does not allow the framework to completely shutdown and do whatever it has to do. For example executing post dispatcher methods.

The benchmarks say that Yii 1.0 is 800% faster with APC than ZendFramework 1.7.2. That is trully amazing. A huge difference. And.. I don’t really believe it is true. So let’s run the same benchmark on our own metal ;)

Let’s start with server configurations.

Yii server:

Operating System: Red Hat Enterprise Linux Server release 5.2
Web Server: Apache httpd 2.0.40
PHP: 5.2.6, any non-essential extensions are disabled
CPU: Dual Intel Xeon 3.2GHz
Main Memory: 2GB
Hard Drive: 73GB 15K RPM SCSI/SAS HDD

Our server:

Operating System: CentOS 5.2
Web Server: Apache/2.2.3 Default configuration
PHP: PHP Version 5.2.6 Default configuration + APC
CPU: Intel(R) Pentium(R) 4 CPU 3.00GHz
Main Memory: 1GB
Hard Drive: 250GB 7200 RPM SATA2

As you can see there is no big difference. Actually our server is slower :( Less CPU power, less RPMs on HDD, more not needed modules and extensions enabled, less memory.

I used the same APC settings as the Yii folks.

apc.enabled=1
apc.shm_segments=1
apc.optimization=0
apc.shm_size=32
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1
apc.cache_by_default=1

I’ve downloaded Yii 1.0 and zend framework 1.7.2. I’ve setup the same applications the Yii folks provide. Except I’ve removed the die and replaced it with an echo. And changed the ZF bootstrap file to work in no view renderer mode. The bootstrap file looks like this:

set_include_path(dirname(__FILE__));
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();$front = Zend_Controller_Front::getInstance();
$front->addControllerDirectory(dirname(__FILE__)."/application/controllers", 'default');
$front->setParam('noViewRenderer', true);
$front->dispatch();

And then I ran the same AB test: “ab -t 30 -c 10 URL” as the Yii guys. I also want to note that I ran the tests a few times to warm up the APC cache. Let’s look at the results:

  • Zend Framework 1.7.2: 184 RPS (requests per second)
  • Yii 1.0: 275 RPS
  • Yii 1.0 with yiilite.php: 235 RPS

And now lets evalue these test results:

  1. Even on a slower machine ZendFramework is more than 3 times faster with APC than in the Yii benchmark. (strange)
  2. In comparison Yii is not 800% faster than ZF like shown on the Yii benchmark page.

It’s possible I’ve made a mistake somewhere. It would be nice to see more people testing this.

, , , Hide

Dec/08

22

Certification to be continued

I’ve recently got listed on the Zend yellow pages. Even managed to get a comment from a Zend employee on my last blog post about PHP5 certification.

I’m also interested in MySQL developer and MySQL DBA exams. I have been working with MySQL for more than 5 years and I still don’t feel that I know all it’s angles really well. Recently I’ve started reading the MySQL 5.0 certification study guide. It will be interesting to compare the Zend and MySQL certification programs. While reading the book it was odd to find out that MySQL Query Browser was the third chapter of the book. And you must be able to know your way around the tool to take the developer exam. I have never used MySQL Query Browser and phpmyadmin has allways sufficed my needs as a web applications developer. Though I agree it is very useful tool. The study guide book comes with a CD that has training exercises in it. I was a little disappointed when I didn’t find a mock exam application to test what I’ve learned but instead found a PDF e-book with questions from every chapter. Still better than nothing. Even though the guide states that it is designed to make you think instead of memorize the material I think it is more effective to learn by taking tests.

, , , Hide

Dec/08

18

Finally a Zend Certified PHP5 Engineer!

Zend the PHP company Finally! After months of battles with myself delaying the day out of pure laziness I took the PHP 5 Zend Certificate exam and passed it! Should be visible in the yellow pages in the following 7 days. I’m really happy I have done this and I hope this will help me in the future to prove my worth to current and future employers.

I’d love to share some details about my experiences with my readers who might one day take the exam themselves.

First of all.. It’s sad that companies such as Zend or PearsonVUE can’t store my firstname and lastname with a proper encoding. Surprising that such world famous international companies don’t use UTF8 encoding. The paper I got after taking the exam had my name written as “?ilvinas ?altys”. When I forgot my password and had to fill in my first name and last name to get a new one I had to use question marks to make it work.

Before taking the exam I’ve done about 13 mock exam tests. I also had problems to order them and had to contact Zend and wait for weeks to complete my order, the tests them selves aren’t very good. You get 70 questions and 90 minutes to answer them. Tests had lots of mistakes and sometimes rather dumb questions. For example .. Which methods are required to implement when implementing the Iterator interface. Tests give 5 choices and ask to select 5 choices. Then there are questions which you cannot answer correctly because either they are out of date or they are wrong from the start. Then there are questions that ask you questions about the PHP virtual machine implementation or PDO extension options or Sqlite performance configuration settings. Good luck knowing all that. After 10 tests you start shooting answers like darts because questions start to repeat a lot. The most frustrating thing is that it’s really hard to learn from these mock tests. They don’t tell you which questions you have answered correctly and why were you wrong. When you start doing a test you look for answers on the internet to find out what is the correct answer and it may some time to do it for any single question. Funny enough I have never got a completely excellent score from the mock exams. I always failed in at least one category and couldn’t figure out why.

Mock exam results

About the exam itself. A heard a lot of poeple saying. “Oh it’s easy!”, “Oh it’s easier than the mock exams!”, “It’s basic level!” If you can complete that exam and you are confident that you have answered atleast 90% of the questions correctly you are a walking bible of PHP that knows the manual really well, all the possible configuration options, all the nonsense tricks in PHP and have some profesional experience. It’s not that easy. A lot of questions are hard to answer. Most of the time you can be only 80% sure. Unless of course you have a very good memory and can remember all the details. Not many developers know what PHP does with floating point array keys or how exactly PHP handles type juggling. When I was about to end the exam I was not sure I will pass it. I knew for sure that there were a lot of questions that I wasn’t 100% sure of. There are tons of questions where the exam tries to TRICK you. For example .. You have a lot of code with classes, abstractions and it asks you what does it output? And you can get confused and not notice that there is no echo statement anywhere and there’s no output. Somewhere I’ve found that noone completed the exam with perfect score and I think it was a statement by Zend itself but I’m not completely sure. You have to answer about 50 – 60% of the questions correctly to pass the test.

A few things were disappointing and could have been better but in the end I’ve achieved my goal and would like to thank Zend for making it possible. Certificates can’t tell if someone is a great developer or a nice person but they can definitely tell how much someone knows about the details of a programming language.

, , , Hide

Oct/08

15

9 steps to prepare for the Zend Certificate Exam

I’m getting very close to taking the Zend Certificate Exam just need a few more things to take care of. I’ve made a list of things one should do to be in my opinion really prepared to take the exam. So here goes:

  • Read the Zend PHP5 Certification Study Guide. It will get you going through all the basics ant not so basic tipsies and tricksies. It’s quite an easy read and if you are confident you can skip or eye-scan a lot of stuff.
  • Read the Essential PHP Security to get a grasp of most of the web security problems.
  • Read the PHP 5 Objects, Patterns, and Practice by Matt Zandstra. It teaches most of the Gang Of Four patterns and a few of the so called enterprise ones. It’s one of the best books on design patterns.
  • Book reading is over. The HOLY manual is your best friend now. Start with PHP array functions. Study each one of them carefuly, memorize parameters and return values.
  • Next go to the PHP string functions.
  • You also need to know the basics of XML, Streams, PDO, SQLite if you are going to take the exam. You don’t have to study each extension closely. I would recommend to give more attention to DOM XML, SimpleXML, XML Parser, Streams functions and PDO.
  • Go and learn some regular expressions. Should take you one evening or so.
  • There are also some misc extensions like SPL or functions like __halt_compiler(), error_reporting() you should know of. Though they cover a little part of the exam.
  • Next you buy 5 – 10 Zend Certification Online Practicing Tests and it costs you arround $20 – $25 greengos.

And that’s basically it. Do that and not only you can take the exam but you will have deeper knowledge of the language you are using and how to use it more properly.

, , , Hide

Sep/08

9

PHP Zend Certification Exam

Previously I wrote that I would like to take the Zend Certification Exam and I thought I could review every chapter of the Zend Certification Exam study guide. Well I think i have lost my inspiration somwhere along the way. Though I recently found a blog that already did what I wanted to do. Check it out and see if it helps. I also found out about Paul Reinheimer’s Zend Certification Exam course which is available as a free PDF on the internet and could be really useful to prepare.

, , , Hide

Apr/08

16

Zend PHP certificate study guide overview (part I)

I’m currently preparing to take the Zend PHP certificate exam and have just finished reading the Zend PHP 5 Certification Study Guide. To help myself and other PHP developers to prepare for the exam I thought I could review every Zend PHP5 certification study guide chapter to provide some highlights on things that may not be known to everyone.

Chapter I – PHP basics

  1. Syntax
  2. Anatomy of a PHP script
  3. Data types
  4. Variables
  5. Constants

1.1 Syntax

You must know that PHP syntax is derived from the C language. PHP syntax has been influenced by Perl and JAVA (latest OOP additions).

PHP supports these opening tags: <?php ?>, <?= ?>, <? ?>, <script language=”php”></script>, <% %>. Interestingly no one knows why <% %> were introduced at all :). Short tags, script tags and ASP tags are all considered deprecated and their use is trongly discouraged.

PHP parser strips new lines after ?> closing tag. An easy way to prevent spurious output from an include file is to omit the closing tag at the end, which the parser considers this perfectly legal.

1.2 Anatomy of a PHP script

It is possible to skip the last semicolon in a PHP script though that is considered a parser quirk and should be avoided.

There are three types of comments in PHP: /* */, //, #. A comment can be ended with a newline or the php closing tag ?>

Interesting to know echo is not a function and, as such, it does not have return value. If you need to output data through a function, you can use print() instead.

An important function is die(); which itself is an alias of exit(); You can echo output with these functions by passing a string or return a numeric status to the process that called PHP by passing an integer.

1.3 Data types

PHP is loosely typed, meaning that it will implicitly change the type of a variable as needed, depending on the operation being performed on its value.

All data types in PHP are divided into two categories scalars and composites. Scalars are: ints, strings, floats, booleans. Numbers can be declared using several different notations: decimal, octal, hexadecimal. Octal numbers can be easily confused with decimal numbers and can lead to some… interesting consequences!

PHP supports two different notations for expressing floats: decimal and exponential. For example 1e2 equals 100. Floats can be as wide as your processor supports. It will be longer on 64 bits systems compared to 32 bits. Be aware that PHP does not track overflows so any operation with big scary numbers can have catastrophic consequences on the reliability of your application. Also be aware that basic operations with floats are not always precise. For example: echo (int) ((0.1 + 0.7) * 10); would output 7 instead of 8. Because internally in PHP the float value is 7.99999 and when casted to an integer becomes 7. To avoid this use extensions such as BCMath.

Strings are ordered collections of binary data. They can store anything from text to music recordings.

Boolean when converted from an integer becomes false if the integer is zero and becomes true otherwise. A string is converted to false only if it is empty or if it contains the single character. If it contains any other data—even multiple zeros—it is converted to true. When converted to a number or a string, a Boolean becomes 1 if it is true, and
0 otherwise.

Arrays are containers of ordered data elements; an array can be used to store nd retrieve any other data type, including numbers, Boolean values, strings, bjects and even other arrays.

Objects are containers of both data and code. They form the basis of Object oriented programming also known as OOP.

NULL indicates that a variable has no value. A variable is considered to be NULL if it has been assigned the special value NULL, or if it has not yet been assigned value at all.

The resource data type is used to indicate external resources that are not used atively by PHP, but that have meaning in the context of a special operation— such as, for example, handling files or manipulating images.

You can force PHP to convert some types to others. For example: echo (int) $x; Though you cannot convert any data types to resources though vice versa is available to get hold of a resource ID.

1.4 Variables

Variables can only be named letters, numbers, underscores. A variable can only start with an alpha character or an underscore. Variables and constants are the only two identifier types that are case sensitive.

PHP supports variables variables:

$name = '123';
/* 123 is your variable name, this would normally be invalid. */
$$name = '456';
echo ${'123'};

Variables can also hold function names and functions can be called through variables like this:
$f = ’myFunc’;
$f(); // will call myFunc();

To determine whether a variable exists use isset(). It will return true when a variable is defined and is not NULL.

1.5 Constants

Constants can only contain scalar values and follow the same naming conventions as variables. They are also case sensitive.

, , Hide

Older posts >>

Find it!

Theme Design by devolux.org