Wednesday, February 25, 2015

Doctrine in the Back-end #1

The setup

- MSSQL 2008
Normalized the tables to the ground. Seems it is a requirement for any ORM as they work best with clean entities and relations. Connection is made to a remote server with an instance. On the dev machine (win) sqlsrv is used. On the production server (*nix) still the old mssql (FreeTSD) is running. ( NOTE: still need to figure out how to deal with this setup. Originally I created a custom SQL class to automatically use one or the other based on availability. Not sure how Doctrine will handle this. Will see later.)

- Win8.1 with Zend Studio 12
As dev. But normally the script supposed to run on Linux so namespace / folder / classname capitalization must matter. The best is to follow PSR-4 (http://www.php-fig.org/psr/psr-4/)

- Composer 
Used for autoloading local and 3rd party libs. First time I use it for back-end scripts so far so good.

- Doctrine 2.4 ORM and 2.5 DBAL (as of January 2015)


Autoload from your own app directory

When tried to instantiate the entity with the Doctrine entityManager::find('<className>') I couldn't figure out why it keeps throwing 'class not found' exceptions. I reverse engineered the DB tables into annotations then generated the entity classes successfully using Doctrine command line. 

$php ..\..\vendor\doctrine\orm\bin\doctrine orm:convert-mapping --from-database annotation ../mapping

$php ..\..\vendor\doctrine\orm\bin\doctrine orm:generate-entities --generate-annotations=true --generate-methods=true ../models

Ok I had to add the namespace to the generated entity class (is there a way to add it when you are not using any framework? I saw doctrine-module can do it but the plain doctrine orm:generate-entities has no parameter for it.)

Then I started debugging to see what are the available classes at that point when Doctrine is trying to access it and turns out I added everything to composer.json but totally forgot the application directory itself. So I added it to my little script Doctrine bootstrap:

$loader = require_once dirname(__DIR__) . '/vendor/autoload.php';
$loader->add('myAppNamespace', dirname(__DIR__));