Deprecated: This code uses an old version of Doctrine and Zend Framework, there is now an semi-official way of integrating Doctrine and Zend Framework, see the announcement of the zf-doctrine project and checkout my plugin for ZFDebug to have access to the Doctrine Profiler: http://github.com/danceric/zfdebugdoctrine

This is my notes on integrating the Doctrine ORM with a Zend Framework project that use Zend_Application. This post was largely inspired by the post Integrating Zend Framework and Doctrine. In fact, you can see mine as an updated version of this great post to work in ZF 1.8. Ruben Vermeersch, the author, have stated on his blog that he want to update the post but he don’t have the time yet, so this is me trying to help.

This was done on OS X, so the instructions here assume a n*x like environment. You should also be comfortable with Zend Framework 1.8+ and the new Zend_Application. As stated in the ZF quickstart tutorial, you can create a project by running this command from the uncompressed Zend Framework folder:

./bin/zf.sh create project ~/Sites/zfdoctrine

In the newly created directory, which is a complete zf application, create the directories that will be needed by doctrine

cd ~/Sites/zfdoctrine
mkdir doctrine doctrine/migrations doctrine/schema
mkdir doctrine/data doctrine/data/fixtures doctrine/data/sql

Now, put the content of the Doctrine (1.0 or 1.1) lib folder in library. I strongly suggest that you put the ZF library here too. If you manage more that one project, it’s very unlikely that you will have time to update all your projects at the same time, which is needed if you use a global include path.

Create the Doctrine configuration in application/configs/application.ini

;doctrine.connection_string = "mysql://root:pwd@localhost/zfdoctrine"
doctrine.connection_string = "sqlite:///" APPLICATION_PATH "/zfdoctrine.db"
doctrine.data_fixtures_path = APPLICATION_PATH "/../doctrine/data/fixtures"
doctrine.models_path = APPLICATION_PATH "/models"
doctrine.migrations_path = APPLICATION_PATH "/../doctrine/migrations"
doctrine.sql_path = APPLICATION_PATH "/../doctrine/data/sql"
doctrine.yaml_schema_path = APPLICATION_PATH "/../doctrine/schema"

Initialize Doctrine in you application by adding this function to application/Bootstrap.php

public function _initDoctrine()
{
    require_once 'Doctrine.php';        
    $loader = Zend_Loader_Autoloader::getInstance();
    $loader->pushAutoloader(array('Doctrine', 'autoload'));
 
    $doctrineConfig = $this->getOption('doctrine');
 
    $manager = Doctrine_Manager::getInstance();
    $manager->setAttribute(
        Doctrine::ATTR_MODEL_LOADING, 
        Doctrine::MODEL_LOADING_CONSERVATIVE);    
 
    // Add models and generated base classes to Doctrine autoloader
    Doctrine::loadModels($doctrineConfig['models_path']);
 
    $manager->openConnection($doctrineConfig['connection_string']);    
 
    return $manager;
}

One of the fun thing about Doctrine is that you have access to a lot of command line tool to create your database, models, sql, schema, etc. Create a new file called doctrine-cli in a scripts folder at the root of you project with the following content:

#!/usr/bin/env php
<?php
/**
 * Doctrine CLI script
 */
 
define('APPLICATION_ENV', 'development');
 
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
 
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));
 
require_once 'Zend/Application.php';
 
// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
 
$application->getBootstrap()->bootstrap('doctrine');
 
$cli = new Doctrine_Cli($application->getOption('doctrine'));
$cli->run($_SERVER['argv']);

You can make this script executable and try it, to see the list of task that doctrine-cli can do for you

chmod +x ./scripts/doctrine-cli
./scripts/doctrine-cli

Now you can jump back to [Ruben Vermeersch's Tutorial]http://ruben.savanne.be/articles/integrating-zend-framework-and-doctrine) tutorial in the “Building an application” section and create the sample application. You’ll learn how to use Doctrine do a simple insert, a query and how to use the command line to create your database and model.

note: If you’re using these two projects together, you may be interested in my next post too: ZFDebug and Doctrine ORM

update 2009/10/29: things are getting easier, check out: Doctrine 1.2 is Zend Framework friendly

Posted in php.

Want to test your reading skills? try out the ZCE PHP5 Mock Exam from PHP|Arch. Don’t be turned off by the name of the test, you don’t need to know anything about PHP to have this answer right :)

choose5

disclaimer : for those easily offended, I’m not bashing Zend or PHP|Arch. There was 69 other questions that were actually about PHP5, and some of them were pretty hard to answer.

Posted in php.

Since I have started using the Zend Framework, I have noticed a limitation in the Markdown parser. As there is classes with names such as Zend_Form_Decorator_Fieldset, and Markdown replace everything between underscore with emphasis, they get rendered like this: ZendFormDecorator_Fieldset. So I have switched to PHP Markdown Extra which fix this, and I have applied the same modifications as before to have syntax coloring.

My new patch for PHP Markdown Extra and GeSHi is availlable on GitHub.

Don’t forget to adjust the require_once line to your GeSHi folder location, and start your code block with the language name between square brackets. ie [PHP]

Also added, is the ability to use the parser from the commande line. If used from the command line with a valid file as an argument, it will ouptput the result to stdout, one sample usage could be:

markdown-geshi-extra.php README.markdown > README.html
Posted in php.

One of the component in the Zend Framework that I’m learning to love lately is Zend_Http_Client. If I remember correctly, back in the days, my first reaction on this component was:

Oh, this is for just for those who don’t know how to use curl_* functions. I don’t need that, pff

Then somebody, trying to convince me to use it, told me:

but you don’t understand! this is usefull if your php was build without cURL support

I hate the ‘if your php is built without…’ family of excuses. And what about if my webserver don’t have the required PHP > 5.2.4 as needed by Zend, or if it’ is built without PHP support, or if my server is without an OS? I must confess that I have always (eh, mostly) been working with company that have enough control on their server to make it easy for the developers. I strongly think that to create something great, one need some control on his environment. Would you like to have a surgery by a surgeon who don’t have access to all his tools?

Back on topic. First thing first, Zend_Http_Client makes your code easier to read, even after a while. cURL argument are like regular expression, you never totally forgot them, but you need to look at the documentation once in a while. To me, the main advantage is that you can tell your http client to use different adapter. And my favorite these days is the Test adapter. As the name implied, it is really usefull when doing (unit) test.

Using the Test adapter, I can simulate an answer from a website. This mean that I can work on some Twitter stuff and test them anytime, even if Twitter seems to always be down at the exact same moment I want/need to try something.

Here’s an example that simulate a search request, you first start by getting an example answer with curl on the command line (when Twitter is up) that you save into dummy.json:

curl -o dummy.json -i http://search.twitter.com/search.json?from=danceric

and then use this file to set the response with the test adapter

$client = new Zend_Http_Client();
$client->setUri('http://search.twitter.com/search.json');    
 
// Set the expected response
$client->setAdapter(new Zend_Http_Client_Adapter_Test());
$fakeResponse = file_get_contents('dummy.json');
$client->adapter->setResponse($fakeResponse);
 
$client->setParameterGet(array(
  'from' => 'danceric',
));    
$response = $client->request();
 
//let's pretend I want the result as an array
$searchResult = Zend_Json::decode($response->getBody());

Now I can have a result returned without contacting Twitter. it’s easy to create a set of dummy data for your different unit test. Of course this code is not to be used as is in a unit test…

Btw, Twitter is not always down. It just seems worse when you use it too much.

Posted in php.

One of the easiest (ie: fastest) way to have a fully working LAMP development environment on OS X is to install Zend Server, which is a package containing apache/php/mysql/zend framework and some other goodies

There is a free version available on the Zend Server Community Edition web page

One thing you might want to do after the installation is to add the Zend binaries in your path before the OS X bundled php/apache binaries.

Add this line to ~/.bash_profile OR ~/.profile

# Zend Server Community Edition
export PATH="/usr/local/zend/bin:$PATH" 

Your webserver should now be available on port 10088 and the Zend admin interface on port 10081

Xdebug

Zend Server CE comes bundled with the Zend Debugger, which is nice when your boss gaves you a Zend Studio licence to use the great profiler. But for me, at home, I use some other editor/IDE (Eclipse PDT, Komodo, TextMate, Netbeans…). So, when I want to profile a script/application, I use Xdebug, which can be used with webgrind or KCachegrind to profile your web application. Oh, and XDebug provides this nice formating for var_dump()… how could I resist.

Installing Xdebug on Zend Server CE on OS X

Adapted from the Windows instructions at http://forums.zend.com/viewtopic.php?f=8&t=553

Save yourself some time and get the pre-compiled Xdebug binaries for OS X from Activestate. And while you’re there, you should download and try Komodo IDE/Edit if you have never done so.

From the archive, copy the file

5.2/xdebug.so

to

/usr/local/zend/lib/php_extensions/

Before using Xdebug though, you have to disable the Zend Debugger. Open the file

/usr/local/zend/etc/conf.d/debugger.ini

and comment the line starting with

zend_extension_manager.dir.debugger

by adding a semicolon at the start of the line

Now, to tell PHP that we’re using Xdebug, add these lines in /usr/local/zend/etc/php.ini just before the [zend] section

[xdebug]
zend_extension="/usr/local/zend/lib/php_extensions/xdebug.so"

Now if you restart your web server, you should see Xdebug in the View PHPinfo page link of the admin dashboard

sudo /usr/local/zend/bin/zendctl.sh restart-apache
Posted in php.

Last week –after seven years of PHP– I have read php|architect’s “Zend PHP 5 Certification Study Guide, 2nd Edition.” I think that it will be a useful tools on my resume to have a PHP certification. More often than not, the HR peoples don’t trust applicants without a certification.

My first discovery was: On page 9-10, in the part about Numeric Value there’s explanations about a ‘bug’ that we have had in a previous company, the so called ‘bug’ cost us thousands of dollars. This mistake could have been avoided if one of the developer had read this $32 book. I feel ashamed for me and the team. When you’re selling a tremendous amount of ‘stuff’ daily at $0.001, you have to be aware of this PHP gotcha. We’ve learned it the hard way.

When you’re coding PHP, do you adhere to your own way of doing thing, or do you adhere to coding standard like the Pear or Zend Framework one?

Coding Standards are a great way to reduce cognitive friction when developers look at your code. Most developer spends more time reading that writing code. So it only make sense to make your code as readable as possible, consistency is the key. When the look of the code is not consistent, i’t slows you down a tiny little bit on each difference that you encounter while reading. Only a lot of little slowdown, but it can add up really fast (take a look a “Don’t Make Me Think” by “Steve Krug” to know why all these slowdowns, that he call ‘question mark’, are bad). Following coding standard does not speed up the development process; it speeds up digging into the code by any member of your team.

It’s not really important which standard you choose, the only important thing is that everybody in your team stick to the same one.

If you’re doing it, you might as well choose a recognised one, one that a lot of people know, even if they are not aware of that. And by the way, it doesn’t hurt to pick one that is easily marketable. It will help new team member, and it will help you on your next job too, because it just look professional.

Tools exist to help you embrace coding standards. PHP CodeSniffer is great tools that tokenize and analyze your source code to detect violations of a defined set of coding standards. The beauty of CodeSniffer lies in the fact that it does not make any change to your code, it only suggest what to change, so the more you use it, the more you learn. After using it for a while, you will (almost) not need it anymore, coding to the standard will be a habit.

There’s a proposal by David Coalier to improve PHP_CodeSniffer with Google Summer of Code 2009. The idea is to add XSS and SQL security analyzer to it. That could become a really important tool one should learn to use in the near future. For more information, see the GSoC 2009 page on the PEAR wiki

With most IDE and text editor it’s easy to set an external tool to be launched. If you’re using Eclipse PDT for example, you can easily set a shortcut to launch PHP CodeSniffer and display the output capture the output. Just look under

> Run > External Tools > External Tools Configurations...

And don’t forget to check the ‘Allocate Console’ checkbox under the ‘Common’ tab.

A word about documentation

Most of the standards suggest that one use PHPDoc format for documentation. I would add the suggestion to read “The Element of Style” by “William Strunk and E. B. White” It’s available in its original edition for less than $5, or you can get a revised Deluxe Hardcover 50th Anniversary Edition for around $20.

This book identifies the principal requirements of proper American English style and concentrates on the most often violated rules of composition. It’s really short and concise, and it will help you write more readable comments.

This post was inspired by The Framework as Franchise by Paul M. Jones for the PHP Advent 2008 website.

Posted in php.