# Introduction

## About Doctrine

Doctrine is a Object Relational Mapping and database abstraction framework for PHP. The DBAL part of Doctrine derives from MDB2. The key idea is to provide very intuitive and easy-to-use persistency solution (eg. RoR ActiveRecord) with all the advanced features from the more heavy-weight solutions (eg. Hibernate).

Doctrine Query Language implements EJB 3 OQL specificiation and expands it a bit further (it has special LIMIT and OFFSET clauses).

### Example

You might not understand exactly what's happening at this stage, but this example is to give you a general idea of the power of Doctrine.

    <?php

        // include the doctrine library
        require_once('lib/Doctrine.php');

        // register the doctrine autoload function
        spl_autoload_register(array('Doctrine', 'autoload'));

        // define the user class
        class User extends Doctrine_Record {
            public function setTableDefinition() {
                // set 'user' table columns, note that
                // id column is always auto-created

                $this->hasColumn('name','string',30);
                $this->hasColumn('username','string',20);
                $this->hasColumn('password','string',16);
                $this->hasColumn('created','integer',11);
            }
        }

        // create a new user
        $user = new User();
        $user->username = "pookey";
        $user->password = "a password!";
        $user->created = time();

        // save the user
        $user->save();

        // lets find the user....
        $query = new Doctrine_Query();
        $query->query('SELECT u.* FROM User u WHERE u.username = ?');
        $users = $query->execute(array('pookey'));
        if (count($users))
        {
          // we found our user!
        }
        else
        {
          // we didn't find our user, oh no!
        }
    ?>

## Features

### General Features

- Fully object-oriented following best practices and design patterns
- Multiple databases
- Database connection pooling with connection-record -registry
- Runtime configuration (no XML needed!)
- Very modular structure (only uses the needed features)
- The runtime components can be compiled into a single fileM
- Leveled configuration (attributes can be set at global, connection and table levels)

### Database Abstraction

- A DSN (data source name) or array format for specifying database servers
- Datatype abstraction and on demand datatype conversion
- supports PDO
- Database query profiling
- Query caching
- Sequence / autoincrement emulation
- Replace emulation
- RDBMS management methods (creating, dropping, altering)
- SQL function call abstraction
- SQL expression abstraction
- Pattern matching abstraction
- Portable error codes
- Nested transactions
- Transaction isolation abstraction
- Transaction savepoint abstraction
- Index/Unique Key/Primary Key support
- Ability to read the information schema
- Reverse engineering schemas from an existing database
- LIMIT / OFFSET emulation

### Object Relational Mapping

#### General Features

- Validators
- Transactional errorStack for easy retrieval of all errors
- EventListeners
- UnitOfWork pattern (easy saving of all pending objects)
- Uses ActiveRecord pattern
- State-wise records and transactions
- Importing existing database schemas to Doctrine ActiveRecord objects
- Exporting Doctrine ActiveRecords to database (= automatic table creation)

#### Mapping

- Composite, Natural, Autoincremented and Sequential identifiers
- PHP Array / Object data types for columns (automatic serialization/unserialization)
- Gzip datatype for all databases
- Emulated enum datatype for all databases
- Datatype abstraction
- Column aggregation inheritance
- One-class-one-table inheritance as well as One-table
- One-to-many, many-to-one, one-to-one and many-to-many relations
- Self-referencing relations even for association table relations
- Relation aliases

#### Object population

- DQL (Doctrine Query Language), an EJB 3 spec compliant OQL
- The limit-subquery-algorithm
- OO-style query API for both DQL and raw SQL
- Object population from database views
- Object population through raw SQL

#### Transactions and locking

- Pessimistic offline locking
- Savepoints, transaction isolation levels and nested transactions
- Transactional query optimization (gathering of DELETE statements)

## Requirements

Doctrine requires PHP >= 5.1, and it doesn't require any external libraries. It runs on both windows and *nix based platforms.

For database abstraction Doctrine uses PDO which is bundled with php by default. You will need PDO support for whatever database you intend to use, and if you want to be able to run the included unit tests, you will need SQLite support.

Doctrine also requires a little adodb-hack for table creation, which comes with doctrine.

## Community

Doctrine has 3 mailing lists, an IRC channel, a forum, and a wiki/trac.

### Mailing Lists

The 'user' mailing list is for discussing the usage of doctrine. To subscribe to this list, send a blank email to doctrine-user+subscribe@lists.pengus.net

The 'dev' mailing list is used for discussion of the development of doctrine. To subscribe to this list, send a blank email to doctrine-dev+subscribe@lists.pengus.net

The 'svn' mailing list is a read-only list, which users and developers can subscribe to to receive commit logs to the SVN repository. This list is quite high traffic, as every commit to the repository results in an email containing the changelog entry and diffs of the changed files. To subscribe to this list, send a blank email to doctrine-svn+subscribe@lists.pengus.net

### IRC

The #doctrine IRC channel can be found on the freenode network. The fastest way of getting bugs fixed and features being implemented is joining our irc channel and pointing out the issue to one of the developers.

### Wiki and Trac

A wiki/trac install can be found at http://doctrine.pengus.net/trac

### Forum

The Doctrine forum can be found here: http://www.phpbbserver.com/phpdoctrine/

## Contributing/Reporting Bugs

Doctrine is constantly under development, and is always happy for new developers to contribute to the project.

To get an account on trac to submit bugs and make suggestions, or to get access to commit to the SVN repository, please visit the IRC channel, or email the users mailing list.

If you are unsure as to wether you have found a bug or not, please consider joining us on IRC, or maining the user mailing list to confirm your problem.

## Installation

As of the time of writing, there is no stable release of doctrine. That is not to say that it's unstable, but simply that the best way to install it is to aquire it from SVN.

To get the latest copy, simple check out 'trunk' from SVN. You will need subversion install to check out doctrine. If you are unable to install subversion for whatever reason, see below for details on downloading a snapshot.

            bash $ mkdir doctrine
            bash $ cd doctrine
            bash $ svn checkout http://doctrine.pengus.net/svn/trunk .

Daily snapshots can be found at http://doctrine.pengus.net/downloads/ and the latest daily snapshot can always be found at http://doctrine.pengus.net/downloads/latest-snapshot.tar.gz

## Include and autoload

In order to use Doctrine in your project, you must first include the main library file called 'Doctrine.php'.

    <?php
      require_once('path-to-doctrine/lib/Doctrine.php');
    ?>

Doctrine supports Autoloading for including files so that you don't have to include anything more then the base file. There are two different strategies that can be used to do this, as shown below.

You can use the __autoload function to call the 'Doctrine::autoload($class)' method, for example:

    <?php
      function __autoload($class) {
        Doctrine::autoload($class);
      }
    ?>

If your project already uses autoload or you have other libraries that use it, you can use spl_autoload_register to register multiple autoloading functions.

    <?php
      spl_autoload_register(array('Doctrine', 'autoload'));
    ?>

## Compiling

Compiling is a method for making a single file of the most used doctrine runtime components. Including this compiled file instead of multiple files (in worst cases dozens of files) can improve performance by an order of magnitude.

In cases where this might fail, a Doctrine_Exception is thrown detailing the error.

    <?php
      Doctrine::compile();

      // on some other script:
      require_once('path_to_doctrine/Doctrine.compiled.php');
    ?>

## Starting a new project

Doctrine_Record is the basic component of every doctrine-based project. There should be atleast one Doctrine_Record for each of your database tables. Doctrine_Record follows the Active Record pattern

Doctrine auto-creates database tables and always adds a primary key column named 'id' to tables that don't have any primary keys specified. The only thing you need to do to create database tables is defining a class which extends Doctrine_Record and setting a setTableDefinition method with hasColumn() method calls.

Below is a short example:

We want to create a database table called 'user' with columns id(primary key), name, username, password and created. Provided that you have already installed Doctrine these few lines of code are all you need:

    <?php

        require_once('lib/Doctrine.php');

        spl_autoload_register(array('Doctrine', 'autoload'));

        class User extends Doctrine_Record {
            public function setTableDefinition() {
                // set 'user' table columns, note that
                // id column is always auto-created

                $this->hasColumn('name','string',30);
                $this->hasColumn('username','string',20);
                $this->hasColumn('password','string',16);
                $this->hasColumn('created','integer',11);
            }
        }
    ?>

We now have a user model that supports basic CRUD opperations!