
We read:
Planet PHP
Planet MySQL
Exciting E-Commerce
E-Commerce Blog
Fischmarkt
fukami
Lars Jankowfsky
Themenblog
Thomas Bachem
Matt Asay on OpenSource
Joel on Software
Ibrahim Evsan
Hasematzel
Techcrunch
Indiskretion Ehrensache
Sichelputzer
Alexander Schwinn
Managing Tech
F-LOG-GE
trycatchfinally
With the release of Zend Framework 1.8 came the long awaited component for bootstrapping a Zend Framework application. Many different bootstrapping-solutions became obsolete with Zend_Application.
In the beginning of the framework most developers didn‘t give much thought on bootstrapping. Most of the initialisation work was done directly in index.php, the central starting point of the application. Teams often moved that bootstrapping code to a separate configuration script. The solution worked, but many people wanted a more standardised process for application initialisation.
Last week I had the chance to attend an Agile Developer Skills Workshop in Berlin.
The 3 day workshop is, next to a Scrum Master or PO Certification, a prerequisite for the Certified Scrum Developer, short CSD.
I was very excited about the ADS workshop and I found it an intersting approach to hold a workshop which focusses on developers rather than on the management side of scrum. Especially as in my experience all the other scrum workshops mainly concentrate on the rituals, artefacts and organisation of Scrum, without giving answers on how to develop high quality software.
JSHint ist ein JSLint Fork von Anton Kovalyov. Dieser hat zwar nicht das Standardwerk der JavaScript-Welt "JavaScript - The Good Parts" geschrieben, dennoch kritisiert er Crockford's jslint, das in dem Buch ein eigenes Kapitel bekommen hat, pointiert mit:
JSHint is a fork of Douglas Crockfords JSLint that does not tyrannize your code. It is designed to detect errors that actually break your code while skipping things that, according to Crockford, are known to contribute mistakes in projects. In other words, JSHint is a fork of JSLint for the real world. The most important difference is that JSHint is developed and supported by the JavaScript developer community and not by one very opinionated person.
In this article, I want to highlight some differences between the two PHP frameworks that have been the most popular ones at the time of writing.
Zend Framework (ZF) is currently a quasi-standard in many PHP companies and Symony2's popularity is constantly increasing. Symfony2 is pretty new now and many developers are thinking about if and when to make the switch from ZF to Symfony2 which is why I think we should spend time looking at the frameworks' differences.
I selected three topics that are implemented differently in these frameworks and will describe how each of them does it.
I took the setup of new projects as one category of comparison because it is an important to make this step as easy as possible for developers that are learning a new framework. In my opinion, the adoption time of a new technology somehow correlates with the easiness of starting a project with using this technology.
To set up a Zend Framework (ZF) project, download the framework's minimal package and extract it to an empty directory. You will see two new folders: bin and library. To initialize the project structure, run the included cli script in the project directory like this:
php bin/zf.php create project .
When you now go to http://<hostname>/ with your web browser, you see a blue welcome page which indicates that the installation was successful. To configure a database connection, you will have to manually edit the file application/configs/application.ini and add the following lines to the [production] environment.
After this step, you have a fully functional Zend Framework project which can be configured using different environments. The next step is to implement custom controllers, views and model classes.
Setting up a project with Symfony2 is pretty easy. You start by downloading a copy of the Symfony2 Standard Edition, extract it to an empty directory and can start to configure your project. However your system has to fulfill some requirements which can be checked by running the script check.php in the app folder (just run php check.php in the command line). When all requirements are fulfilled (and you created a virtual host with its DocumentRoot pointing to the project's web directory), you can navigate your browser to http://<hostname>/config.php and configure the project via a fancy web UI. After checking all requirements again, the Symfony2 sandbox asks you to enter your database configuration which will be written to a configuration file afterwards. The sandbox also includes a sample page where you can see that everything is up and running: http://<hostname>/app_dev.php/demo/hello/World.
To use the sandbox for a real project, I suggest removing the demo pages visited before. Remove the line registering the demo bundle from the file app/AppKernel.php and the demo bundle's router configuration from app/config/routing_dev.yml. Last you can delete the bundle's folder src/Acme.
To be able to define different database connection parameters for the various environments (as with ZF), copy the file app/config/parameters.ini to (this example uses the environment dev, of course you can to the same for any other environment!) app/config/parameters_dev.ini and adjust the other config files accordingly:
The initialization process of a new project is very easy with both of the compared frameworks. One benefit of ZF is that it eases the differentiation between different environments when it comes to configuration - all configuration options can appear in one file in multiple configuration environments that inherit default values from other environments in a defined hierarchy. With Symfony2 you have to create a separate config file and include it into your project's configuration as described above.
Symfony2 on the other hand comes with a nice example bundle that contains a sample configuration, controllers, views and even a very basic authentication infrastructure which can be used as template for your own bundles. Of course, the initial project structure of a ZF project has some default controllers as well, but they don't show you how to configure e.g. security.
The Model View Controller (MVC) pattern is one of the basic structural patterns used in application development. It basically applies the concept of Separation of Concerns to the structure of applications in a way that separates business logic (Model), the rendering of user interfaces (View) and user interaction handling (Controller) from each other. Most object-oriented frameworks provide scaffolding for MVC implementations - so do Zend Framework and Symfony2. Let's have a look how MVC is applied in both cases.
In a classical project infrastructure, ZF projects use controllers that contain multiple actions. Every HTTP request sent to the application is being handled by one (in some cases also multiple) controller's action and most of the times, one action is mapped to one view (This is of course due to the fact that in the WWW, user interaction required a reload of the complete web page - at least for a long time. Nowadays, many web pages (so-called single-page- or Ajax-applications) do not need reloads to change the displayed data and views.).
Views are implemented as templates that contain HTML markup code with inlined PHP snippets. To pass data to a view, the controller has to set this data as a member variable on its view. In the view script you can later access this data by using $this->variable.
In web development, the term Model Class is often mistaken for Persistent Entity Class. Model objects do not only represent data stored in a database, but should also contain all the business logic of your applications. I have seen many applications that do all the logic inside of controller classes and only use models to have an abstraction over the database.
ZF cannot force you to have model classes for all your logic and it also does not try to do so. What it does is giving you a utility for implementing your database abstraction: Zend_Db.
Zend_Db is a component of ZF that provides several APIs to access databases and have an abstraction for persistent records. In times of Doctrine 2, I would suggest neither to learn the use of Zend_Db nor to implement a custom database abstraction. Doctrine 2 can be integrated into ZF projects very easily as you can look up in my article from December 6th and it probably will do a better and more efficient job than a custom solution, too.
Besides my own affinity for Doctrine 2, there are several impartial reasons for not using Zend_Db. In my opinion, the biggest disadvantage is that to add custom logic to your entity objects, you end up writing subclasses of Zend_Db_Table_Row_Abstract. This is a thing I really don't like. Dealing with business logic entities that map the application domain should not require you to think about persistence at all (espacially not to subclass a certain class just to make your objects persistable)! You might say "but this is Active Record!" now. Yes, you are right - Zend_Db_Table_Row implements the Active Record pattern. But: Active Record has not heard a word about separation of concerns. Hence it is just a collection of bad OO code.
Using Symfony2, you split your application into one or more bundles. Each bundle has its own controller and model classes, configuration and views. Similar to ZF's modules, controllers and the related model classes are grouped into bundles together with views used by these controllers. This way it is easy to reuse code from other projects by just copying the required bundle.
One difference regarding controllers is the definition of the term controller in Symfony2: A controller is a PHP function that houses all the logic necessary to return a Response object that represents a particular page. (from the Symfony2 Glossary)
Thus a controller does not have to be a full-blown class with differnt actions but only a function handling a specific type of requests. Inside your controller functions, you have to create and return a Response object. How you do this is up to you. There are cases in which you use a templating language (Symfony2 comes with Twig which might take some getting used to it but is very powerful eventually) for rendering HTML but you can always just serialize some data to provide it via a REST API, too.
As with ZF, views are implemented using templates in Symfony2. To use a template, you call the render method in your controller and pass all data required to replace the placeholders in the template. The render method will create a Response object for you which can be returned by your action directly.
When it comes to model classes, there are no restrictions in Symfony2. It is recommended to use Doctrine 2 (which also is included in the distribution package of Symfony2) as your applications' ORM system. Doctrine 2 is already integrated into Symfony2 which makes the configuration really easy. If you follwed the steps in the Project Setup section above, you even configured Doctrine 2 already!
Real MVC is hard to implement the correct way. This is espacially true when it comes to web applications. One major component missing to a real MVC implementation in classic web applications is the synchronity of model and view (which is normally done using an Observer Pattern). Using PHP, HTTP and HTML, you normally render a web page once and the user has to reload the page to see whether there have been changes on the displayed data. By using Ajax in combination with XMPP or any other RealTime-Web implementation, you can imitate this mechanisms. Doing so, you will end up with two MVC implementations: One on the server side and one inside the browser.
After the comparison of ZF and Symfony2 regarding MVC, you cannot say that one does a better job at it. Both frameworks help you separating your code, but the real work has still to be done by the developer using the framework.
Dependency Injection (DI) has been a buzzword in the last few years (again, PHP adopted this technique some years after the Java world did) and still is, so we will have a look on how the ZF and Symfony2 are handling objects dependent on each other.
There is no real DI mechanism in Zend Framework by now. It comes however with multiple components that do something similar to dependency injection. We will have a short look at two of them: The Zend_Registry and Zend_Application_Resources.
The Zend_Registry is a container for services that should be available globally in an application. You can access the registry statically, store values in it and access them somewhere else. This approach can be seen as an implementation of the Service Locator pattern. If you have external dependencies in your controller and/or model classes, you can just read them from the registry every time you need them. Two downsides of the Zend_Registry is that it does support lazy initialization of dependencies and that it cannot provide non-shared objects (to achive this, you can always put factory objects into the registry!).
Another mechanism related to DI is provided by the package Zend_Application_Resource. Resources are dependencies configured at the time the Zend_Application is being bootstrapped. You can access all application resources in your controller by calling $this->getFrontController()->getParam('bootstrap')->getResource($resourceName).
Symfony2 is shipped with a dependency injection component which can be used as a standalone package, too. Every Symfony2 project uses it since the framework itself makes use of it in its core components. Besides that, you can benefit from DI in your own bundles as well. Symfony2's dependency injection container is configured via extensions that specify their services and the objects required to build these services. Imagine for example a user management bundle which sends welcome emails to new users. Therefore there might be a service called Acme\UserBundle\WelcomeMailer which requires a mailer object to perform its work. In this case you would create an extension for the DI container and define your service like this:
To access the welcome mailer in a controller, you just call $this->get('welcome.mailer.acme.user') and receive a lazily created instance of the class Acme\UserBundle\WelcomeMailer. Objects defined as arguments of a service will be provided to the service's constructor as parameters. If you want to use the welcome mailer somewhere else, just define it as an argument of this other class and you will have an instance of the service injected.
As we have seen, the winner of this discipline is Symfony2. It enables developers to define their objects' dependencies explicitely in a very flexible way. Zend Framework on the other side provides mechanisms that ease the distribution of service objects, but does not implement lazi dependency initialization or and injection of dependencies at all.
These were just a few differences between Symfony2 and Zend Framework 1. If you got interested in Symfony2 by this article, you should have a look at the framework's website and read the Symfony2 bible.
All in all I prefer Symfony2 for new projects because it makes me write better OO code. Zend Framework is fine, too, but it looks kind of outdated to me. Anyways I'm also excited to see how ZF 2 (currently beta) works and will spend some time comparing it to Symfony2 as well - maybe in another blog article.
Dass Firebug in JavaScript programmiert wurde dürfte den meisten bekannt sein. Das gleiche gilt für den WebInspector von WebKit, wie er in Safari oder Google Chrome zu finden ist. Es dürfte also nicht wundern, dass für mobile Geräte mit Weinre von Patrick Mueller bereits 2010 eine Portierung des WebInspectors geschaffen wurde, die über eine JS-Include auf der im Website-Header im Mobilen Browser Remote Debugging Funktionalität zur Verfügung stellt. Somit kann bequem über dem Desktop eine Mobile Webseite debugged werden. Weinre läuft heute als PhoneGap Projekt, ist sozusagen Standard und ist natürlich auf GitHub zu finden.
Das Ganze hat aber leider eben leider Grenzen, was Features wie Breakpoints, Backtraces und Profiling angeht, d.h. genau die nützlichen Features, die normalerweis unter dem “Script”-Tab im Debugger-Panel zu finden sind.
Der nächste konsequente Schritt war also, den Debugger direkt in den Browser Runtime zu heben und eine Remote API anzubieten bzw. eine Verbindung zu dem ohnehin schon existierenden V8 DebuggerProtocol zu schaffen, dass sich allerdings nur auf JavaScript Debugging beschränkt. Das Gesamtpaket nennt sich dann WebKit Remote Debugging Protocol. Währenddessen arbeitete Google auch am ChromeDevToolsProtocol was aber mittlerweile deprecated ist.
Seit Frühjahr diesen Jahres bietet nun WebKit sein Remote Debugging Feature an, welcher praktisch alle bekannten WebInspector Features unterstützt - dazu zählen:
Das Feature kann bereits seit einigen Chrome Versionen getestet werden. Eine aktuelle Chrome Version bevorzugt kann eine Debugger-Instanz mit chrome --remote-debugging-port=9222 gestartet wird.
Sodann ist eine zweite Browserinstanz für den Remote Web Inspector nötig - diese muss jedoch Ihr eigenes Nutzerprofil verwenden, um Probleme zu vermeiden: chrome --user-data-dir=<existierendes Verzeichnis>
Mit Navigation auf http://localhost:9222 im zweiten Browserfenster findet sich nun eine Thumbnail-Übersicht der geöffneten Tabs des zu debuggenden Browsers. Ein weiterer Klick auf das ein Thumbnail lädt nun den Debugger auf die komplette Seite, mit dem wie gewohnt gearbeitet werden kann.

Somit kann zusammenfassend folgendes zur Funktionsweise gesagt werden:
In iPhone oder Android-WebKits sucht man den Debugger derzeit noch vergebens (about:debug), auch wenn es bereits einige ROMs für Android mit Web Inspector Support gibt. Blackberrys Playbook hingegen besitzt schon entsprechende WebKit Funktionalität.
Der Debugger bietet für den Browser eine vereinfachte, aber noch experimentelle JavaScript API, die z.B. auch durch Chrome Extensions angesprochen werden kann. Nach Google’s Vorstellungen sollen damit auch WebIDEs wie Cloud9 zum bereits integrierten JavaScript Debugger (lib-v8debug) einen vollwertigen “WebInspector” erhalten.
Opera demonstrierte bereits 2008 mit DragonFly und Scope einen funktionierenden Remote Debugger, mit dem es möglich ist sich an an einen Opera Mobile oder auch Desktop Opera via TCP-Port ranzuhängen und nicht nur JavaScript zu debuggen. Nachteil an der ganzen Sache: Im Mobile Web dominiert derzeit WebKit.

Ein ähnliches Projekt existiert seit Anfang diesen Jahres mit Firebug Crossfire, was ähnliche Möglichkeiten bieten soll. Zudem unterstützen die JavaScript Development Tools (JSDT) für Eclipse bereits Crossfire. Derzeit befindet sich das Projekt jedoch noch in der Alpha-Phase, aber darf bereits getestet werden.
Für den, der nodejs debuggen muss, gibt es mit dem NodeInspector eine schicke Lösung, mit der es möglich ist, dies bequem im Browser zu erledigen. NodeInspector ist wie ebenfalls wie Weinre eine Adaption von WebInspector.
Für JavaScript Debugging in der IDE, d.h. bequem Breakpoints in den Quelldateien des geöffneten Projekts setzen, haben wir zum einen die ChromeDevTools als Eclipse-Plugin. Zum anderen hat IntelliJ mit IDEA 10.5 und PHPStorm 3 das V8 DebuggerProtocol bereits implementiert.

Eine weitere einfache JavaScript-Konsole stellt z.B. JSConsole bereit, dass zum Debuggen von iPhone oder Android-Mobile Apps benutzt werden kann.
Today's topic is deployment. It's called one-click deployment for a reason: Developers are lazy.
It's hard to do less than clicking on one button, so that's our goal.
With the growing need for lower time-to-market and faster response to user feedback it is inevitable to not be limited by technical factors (there are enough other obstacles already). The focus lies on reproducible results.
So, what do we need? Actually, not much. Disregarding the tools and practices that build the foundation of agile software development, you only need a central build server. But you've already got that one covered, right?
If you don't, you should get one. It's a huge help to discover errors quickly and be alerted instantly. This usually leads to a shorter time frame until a fix is done. Tests are run continuously and new parts are integrated into the whole code base.
Everything written here is based on Apache ant, so the easy choices here are Hudson and Jenkins. We're focusing on Jenkins here, but we've successfully used some variation of this continuous integration/deployment script on both.
We've also used CruiseControl/phpUnderControl and Atlassian Bamboo in the past for continuous integration, so the deployment parts should work as well.
Back to the hard facts. We're using the Template for Jenkins Jobs for PHP Projects here for our basic checks, so let's assume you got it installed and your build server is working.
The typical workflow for a developer now consists of these steps:
There's not much deployment in this, so a few more steps:
There are a few preconditions in our environment that haven't been named yet. Not all of them are hard requirements, but they make some things a lot easier:
The frontend nodes use a setup including varnish, nginx, PHP 5.3+APC, ZF 1.11, Dojo 1.6 and Doctrine 2.1.
The backend nodes use MySQL(Master+Slave), Apache Solr, RabbitMQ, memcached and ejabberd.
It basically executes these steps:
And that's it.
The manually executed task is called deploy-to-staging and consists of these steps:
Here's one caveat: We've set up our staging (and production) nodes to include a directory (like /opt/repository) in /etc/apt/sources.list and puppet periodically checks if there are new packages in this directory, and installs it. Of course you could just call dpkg -i through ssh as well.
So far, so good. After waiting 5mins we've got our "release 1.32c" deployed to all 4 staging nodes and the testers can do their work.
We're not quite done yet though. The testers really liked release 1.32c and we want to deploy to live now!
So this means:
In greater detail:
If everything went well, you just deployed a new release!
The first thing we noticed is the build time. The build used to take 15 minutes because of massive disk I/O. Mostly all the analysis/metrics tools are to blame, if you have a few of those, every single one has to read and check all of your hundreds of files even if you exclude the external dependencies and libraries (which is a good idea, anyway). We put the files on a ram disk and brought the build from 15 minutes down to 4. Good enough.
The setup is quite complex (as you've seen if you're still reading). It takes a bit to get used to and there are some moving parts. But so far it's working nicely.
Jenkins is a single point of failure. If your build server goes the way of the dodo, it's very hard to get a release going. There's an easy fix, however: Have a second machine ready that's running an identical copy of your Jenkins setup. If your main build server is down you can still use that one then. As your developer VMs are using the same ant build.xml for daily work, even using that as a last resort is possible.
There are also some goodies that aren't crucial, but nice:
Having talked with developers from other companies there seem to be quite a few similar setups including chef, rake, phing or even make - so you're surely not forced to use ant or a debian-based distribution.
Good luck simplifying your own deployment!
In yesterday's article of our advent calendar, we explained the concepts underlying Doctrine 2. In today's article, we want to use that knowledge and create a simple Zend Framework (ZF) application that uses Doctrine 2 to persist its business objects.
While explaining how to integrate Doctrine 2 into Zend Framework, we will create a generic sandbox that can be used for future projects building up on these technologies.
Since this article is not about how to setup a ZF project, the following steps will require you to have a clean but working project with
the usual folder structure.
To use Doctrine 2 you will have to get a copy of its source code first. You can get one either from the project's website or by cloning the git repository. In my opinion, downloading the source package from the
website is a lot easier (you don't have to take care of all the project's git submodules etc.). So download and extract the archive into a
temporary directory. After that, move the folder Doctrine from the archive's root into the library of your new
ZF application. Now, your project structure should look like this:
The first thing that will occur to you if you look at the Doctrine 2 source code is that 100% of the code is
namespaced (for a (German) introduction to namespaces have a look at the article "PHP 5.3 Features in Real Life" from a colleague of mine). This is pretty nice for people who are not scared of new
language constructs but for many people that are using ZF it might look odd at first. I am sure that you will get familiar with the syntax
differences really fast, but ZF (1) does not - because it does support real namespacing yet (however this will change with version 2).
Therefore we have to do some additional work that enables us to autoload classes that reside in namespaces. Luckily, Doctrine 2 comes with
a neat set of helper classes bundled in the project Doctrine Common which
also includes a class loader that fulfills our needs. The class loader is called Doctrine\Common\ClassLoader and is really easy to use:
This code snippet creates and registers a new class loader that looks for classes in the namespace Doctrine. These classes should be placed in a folder called Doctrine which is part of the current include path. Every namespace separator will be transformed into a directory separator when looking for the classes, so make sure to keep your class-, namespace-, file- and folder-names in sync!
I recommend putting the initialization of the class loader into your application's bootstrap class because this way it can be used for cli scripts, too. As you might have seen, there are several packages inside the Doctrine folder that we placed in your library. The folders ORM, DBAL and Common contain the Doctrine 2 classes required by the framework. The fourth folder Symfony contains some classes borrowed from the Symfony2 framework. To load all these classes, we have to initialize multiple class loaders:
The initialization of the loaders responsible for Symfony2 and entity classes requires a second argument, that indicates the directory in which the classes of the namespaces can be found. If you do not provide this argument, the class loader just looks in the directories of your include path for folder names matching the given namespace.
The next thing we will do is creating an entity manager. To do so, we have to initialize a configuration object (of the type
Doctrine\ORM\Configuration) and pass it to the entity manager. Since we want to create a project that can be configured easily,
we separate the configuration data from the initialization code. Let's begin with the initialization code and add the required configuration
directives to our application.ini file later.
Instead of describing each single option here, I add some detailed comments in the initialization code:
From now on, you can access the entity manager by requesting it from the Zend_Registry. This should probably be done via a
dependency injection system, but this article will not cover how to implement dependency injection or even a dependency injection container.
To make this bootstrap code work, you will have to add the following directives to your application.ini:
Basically, this is all you have to do to integrate Doctrine 2 into your ZF application. It is fully functional with this
configuration, so let us take a snapshot of the project now and declare it as our sandbox for future ZF-Doctrine 2 projects.
\
Next, I want to show you how to create entity classes within your project and how to initialize a database scheme from these entities.
If you have read my yesterday's article, the following part will not look very new to you. I will create two entity classes: User and Group which have a n:m relationship called membership.
To write create tables in the database for these entities, we will use Doctrine's console tools which are really handy. Create a new
script named doctrine.php in your application's bin directory and copy the following code snippet into it.
This script sets up a Zend_Application first, bootstraps it and creates a normal Doctrine 2 console. You might want to have a
look at the original console script which is included in the Doctrine 2 archive we downloaded before. I added the ZF initialization
to be able to use the application's configuration here.
When you run the script now, the output should look like this:
All actions related to your database's schema have the prefix orm:schema-tool. Create your schema now by executing
$ php bin/doctrine.php orm:schema-tool:create
If you have no errors in your configuration, your database should have three new tables now: user, group and group_user.
Now you are ready to implement your application's logic. You can write code that queries, modifies and creates user and group objects and have all data persisted by Doctrine 2. To end this article, I just want to give you a feeling for how you might interact with Doctrine 2 in your business logic.
I hope this article helps you setting up the infrastructure for your next project and covers everything you have to know to begin using Doctrine 2. The sandbox we set up can be downloaded here. Make sure to include the current versions of ZF and Doctrine 2 after downloading it.
Object-relational mapping (ORM) frameworks have been around for several years now and for some people, ORM is already outdated by now. As we have seen with other technologies and concepts before, PHP is not exactly what we call an early adopter among the programming languages. Thus it took some time for ORM to grow up in the PHP context.
There have been some frameworks before Doctrine 2 that implement ORM (remember e.g. Propel) specific tasks but most of them lack the required maturity to be used in large projects. With Doctrine 2, PHP takes a huge step into the right direction – Doctrine 2 is fast, extensible and easy to use.
This article will take you on a tour through the main concepts of Doctrine 2 in the first part and then explain how to use it in a real world application in the second part. Since at the time of writing Zend Framework 1.11.xx (ZF) is very popular, we will integrate Doctrine 2 into a ZF project.
To understand Doctrine 2, we have to take a look at some relevant terms (or in this case objects), study their behavior and practice their usage. We start with some introductory phrases on ORM systems and then go on to the concepts underlying Doctrine 2: Entity Objects, the Entity Manager, Repositories and Proxies.
Since the beginning of Object-Orientation, people had to manage the persistence of their application's state resp.
their objects. In the context of Web Application Development, this usually involves a Database server which is being
consulted using a Query Language. One example for this pattern is a PHP application that uses some kind of SQL server
by sending SQL queries to it. Another one is an application using a CouchDB server by querying it via its REST API.
Due to the author's laziness, we will talk in terms of relational databases from now on. Keep in mind, that you can
accomplish almost everything mentioned here with NoSQL databases, too.
ORM relates value objects that exist in an application's business logic to database records.
Thus every object that should be persistent is saved in one row of a database table. The most common approach is to
map classes to tables and the classes' objects to rows in the these tables.
Besides writing objects to a database, ORM systems are also intended to ease the process of finding data stored in the
database. When talking in terms of ORM, finding data always means making the framework fetch one or many objects
that meet a certain criteria.
The objects that are being managed by an ORM system are called Entity Objects. Every entity object relates to one entry in a table. In Doctrine 2, the classes that represent entities do not have to fulfill special requirements like inheriting from a certain super class (as you might have seen in other database abstraction frameworks like Zend_Db). When creating a new entity class with Doctrine 2, all you have to do is to write down a regular PHP class with properties. Besides this, you have to provide some hints on how these attributes should be persisted. The information how entity attributes relate to columns in the DB is called Metadata. Metadata can be described in different ways: By default there are metadata drivers for descriptions in XML, YAML and PHP. The fourth and most popular driver is based on DocBlock annotations (since in PHP, annotations aren't a language feature as in Java (see Wikipedia), they are contained by the classes' and attributes' DocBlocks). We will use annotations to describe our entities metadata. To get an impression on how easy this is, take a look at the following example.
This example contains all it needs to tell Doctrine 2 about the new entity User. With this class, you can create,
find, delete and modify user objects and persist their state to the underlying database. But keep in mind: as long
as you don't need any persistence features, you can use your user objects just like any other objects!
The next two objects resp. object types we will describe are responsible for doing the ORM functionality: persisting and finding.
To use ORM functionality, the Entity Manager (Doctrine\ORM\EntityManager) is the main access point to Doctrine 2. The entity manager is
responsible – as you might have guessed – for managing entities and for building a facade for the whole framework.
To accomplish its tasks, the entity manager uses some helpers. The Unit of Work object for example collects entities
that should be written back to the database and is capable of doing this in batches. This way, database operation
can be executed with almost no overhead and therefore are really fast.
Another dependency of the entity manager is the Event Manager. To be as extensible as possible, Doctrine 2 comes with an event system that publishes all important state changes to the outside as events. You can register for such events and extend the life cycle of your entity objects at one single point.
The entity manager's API combines methods for managing entities (find, persist, contains, copy, detatch, merge,
remove and refresh), methods that control the use of transations (beginTransaction, commit, flush, rollback and
transactional) and some helper methods for creating custom queries and accessing some of the entity manager's dependencies.
The following example shows how to query an object from the entity manager, modify it and write the changes back into the database.
Creating a new persistent object is almost as easy as modifying it:
For finding entities, Repositories are used. Every entity class has its own repository which is responsible for finding entities of that type. By default, repositories have some handy methods for fetching entities that match certain criteria:
find: Finds an entity by its primary key / identifierfindAll: Finds all entities of the repository's entity typefindBy / findOneBy: Finds all resp. one entity that matches the passed criteria:findBy<attribute> / findOneBy<attribute>: Magic methods that ease the filtering by a single attribute:
To access a repository, all you have to do is ask the entity manager for one. If you have implemented your own
repository, it will be returned by Doctrine\ORM\EntityManager::getRepository(). Otherwise, Doctrine 2 will provide
a generic repository. The main reason to implement custom repository classes is to group custom queries for an entity
type to make them reusable. For custom query logic, there are several mechanisms you can use: You can either use
Doctrine's query builder that implements an API similar to Zend_Db_Select or queries written in the Doctrine Query
Language (DQL) or you can even execute plain SQL queries. With these options, it is also possible to migrate old
applications which use complex queries by just wrapping these queries into the methods of custom repositories.
When traversing a graph of entity objects (which is required when entities are having relations to other entities),
it would be very expensive (in the sense of “requiring many database queries”) to fetch every depending entity with
an additional query. Therefore Doctrine 2 uses the concept of Proxy objects that represent regular entity objects
which have not been populated with data from the database. Take a look at the following example where the entity
Group aggregates a list of User objects in its member property. When accessing the members list, Doctrine 2 provides a
collection of proxy objects instead of complete User objects. When an object of this collection is being asked for
one of its properties, Doctrine loads the object's data from the database. This way, the users' data is not loaded
until it is really needed.
This section describes some advanced concepts that are required when mapping entity classes that have relationships to
other entity classes. Possible relationship types are association and inheritance. Inheritance is the mechanism used for
representing subtypes in object-oriented programming languages. An example would be a class User that implements
methods every user of a software should have and a class Administrator inheriting from User that adds methods for
determining the administrator's access rights.
Association is a weaker relation type. It means that an entity object can be related to other entity objects of other types. In terms of relational databases, there are three types of association which differ in the number of entities an object is related to: 1:1, 1:n and n:m relationships. n and m are placeholders and mean multiple.
To put objects of an entity type into relation, you just have to mention this relation in the entity class' mapping
information. The simplest case is a unidirectional 1:1 relationship. In the following example we describe a User entity
which has its access information (user credentials) encapsulated into another entity class called UserCredential. Since
every user has at most one credential object and every credential object may only be associated to one user object,
this is a 1:1 relationship.
If the relationship should be bidirectional, include the OneToOne attribute in the other class, too, and add an
attribute which denotes the attribute of the other entity that mapps the related object:
This way, you can access the user object from the credentials object, too.
Most of the times, developers have to deal with relationships which include many objects on at least one side.
These relationships are called 1:n or n:m relationships. This means that either one or multiple entities are standing
in relationship with an arbitrary number of entities of another type. To accomplish this, you have to use the mapping
keywords OneToMany or ManyToMany when describing your entities. Besides that, the mapping works the exact same way as
with 1:1 relationships.
There are however some tricks you should know when dealing with collections of associated entity objects. Consider
the following relationship between the entity classes User and Group:
When a group has at least one member, the group object will have a collection of the type
Doctrine\Common\Collections\ArrayCollection set as its members property. This collection contains
all user objects (or proxy objects as we have seen before) and can be modified intuitively with the methods add and
removeElement. To honor object-orientation, you might want to introduce custom methods for these tasks. If you do so,
you get into trouble when the group object does not have any users associated. In this case, the collection will simply be
set to null. To avoid checks whether the collection has already be initialized, you should to this by yourself
in the entity class' constructor:
It is also important to notice that one entity has to update the other entity's state as well when a relationship between to objects is created or removed. Take care to do this only in one class to avoid endless recursion loops! This class is called the Owning Side of the relationship. When implementing a bidirectional relationship, the other class is called the Inverse Side. It is important to determine owning and inverse side and implement the the classes accordingly to avoid greater trouble during debugging.
There are some more features implemented by Doctrine 2 enabling developers to specify their entities' relationships including sorting, pre-fetching and indexing. These topics are not covered in this article but are explained very understandable in the Doctrine 2 documentation.
Subtyping can be implemented in different ways using Doctrine 2. The main difference between these implementations is how the inheritance is mapped to the database. The options are to have one table for every class (Class Table Inheritance), to have one table for all classes in a hierarchy (Single Table Inheritance) and to have a table for every specialized sub-class of a given super-class (Mapped Super Class).We will give a short overview on all three alternatives, you have to pick the right one yourself. This decision should be made based on how many common attributes there are in your sub-classes.
Introducing a mapped superclass is probably the easiest way for specifying inheritance but might lead to many duplicate columns in your database schema. The superclass of your entities is not being declared as an entity itself (and might also be declared abstract) but provides attributes and optionally methods that will be available in all subclasses. When creating the database schema, Doctrine 2 merges all attributes and relationships of the superclass into the definitions of the subclasses and processes them as regular entities.
After creating the database from this mapping information, your tables will look like this:
When having entities that are very similar besides some few attributes, you might want to store them together in one database table. This approach is called Single Table Inheritance. To distinguish between the different types, there is always a column marked as discriminator column and a discriminator map that tells Doctrine 2 which values in the discriminator indicate what entity types.
These definitions cause the existing of one single table called User with all the attributes declared inside the classes User and Administrator plus a column type – the discriminator column. When working with entities of these types, Doctrine will manage the type flag automatically for you.
The resulting database schema looks as illustrated by the following diagram:
Having each entity type stored in its own table is always good for keeping your schema extensible. When you have to create a new subtype, Doctrine 2 will just create a new table for this type and it can inherit the logic and common attributes of a superclass. The only overhead you have with this approach is that all tables that correspond to subtypes have to maintain a relationship to their supertype's table. Using class table inheritance, the example with the entities User and Administrator looks like this:
Besides the inheritance type, there is no difference to the example using single table inheritance. The outcome on the resulting database scheme is huge. Now you have to separate tables which store users and administrators. Every record in the table Administrator has a corresponding record in the User table.
This was the first part of this article. Stay tuned for part II which will be published tomorrow (on 6th of December 2011)! In the second part, we will integrate Doctrine 2 into a Zend Framework application and include a generic sandbox (ZF-)project with Doctrine 2!
Here is a short example how a test for jsTestDriver could look like
MathmaticsTest = TestCase("MathmaticsTest");
MathmaticsTest.prototype.testAdd = function() {
var mathmatics = new school.Mathmatics();
assertEquals(3, mathmatics.add(1,2));
}
MathmaticsTest.prototype.testSub = function() {
var mathmatics = new school.Mathmatics();
assertEquals(1, mathmatics.sub(4,3));
}
MathmaticsTest.prototype.testDiv = function() {
var mathmatics = new school.Mathmatics();
assertEquals(4, mathmatics.div(8,2));
}
MathmaticsTest.prototype.testMultiple = function() {
var mathmatics = new school.Mathmatics();
assertEquals(9, mathmatics.multiple(3,3));
}



















