374 lines
11 KiB
XML
374 lines
11 KiB
XML
<chapter id="connection-management">
|
|
<title>Connection Management</title>
|
|
<sect1 id="dsn">
|
|
<title>DSN, the Data Source Name</title>
|
|
<para>
|
|
In order to connect to a database through Doctrine, you have to create a
|
|
valid DSN - data source name.
|
|
</para>
|
|
<para>
|
|
Doctrine supports both PEAR DB/MDB2 like data source names as well as PDO
|
|
style data source names. The following section deals with PEAR like data
|
|
source names. If you need more info about the PDO-style data source names
|
|
see <ulink
|
|
url="http://www.php.net/manual/en/function.PDO-construct.php">http://www.php.net/manual/en/function.PDO-construct.php.</ulink>
|
|
</para>
|
|
<para>
|
|
The DSN consists in the following parts:
|
|
</para>
|
|
<variablelist>
|
|
<title>DSN components</title>
|
|
<varlistentry>
|
|
<term>phptype</term>
|
|
<listitem>
|
|
Database backend used in PHP (i.e. mysql , pgsql etc.)
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>dbsyntax</term>
|
|
<listitem>
|
|
Database used with regards to SQL syntax etc.
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>protocol</term>
|
|
<listitem>
|
|
Communication protocol to use ( i.e. tcp, unix etc.)
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>hostspec</term>
|
|
<listitem>
|
|
Host specification (hostname[:port])
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>database</term>
|
|
<listitem>
|
|
Database to use on the DBMS server
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>username</term>
|
|
<listitem>
|
|
User name for login
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>password</term>
|
|
<listitem>
|
|
Password for login
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>proto_opts</term>
|
|
<listitem>
|
|
Maybe used with protocol
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>option</term>
|
|
<listitem>
|
|
option: Additional connection options in URI query string format. options get separated by &. The Following table shows a non complete list of options:
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<variablelist>
|
|
<title>List of Options</title>
|
|
<varlistentry>
|
|
<term>name</term>
|
|
<listitem>
|
|
Some backends support setting the client charset.
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>new_link</term>
|
|
<listitem>
|
|
Some RDBMS do not create new connections when connecting to the same
|
|
host multiple times. This option will attempt to force a new
|
|
connection
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>
|
|
The DSN can either be provided as an associative array or as a string. The
|
|
string format of the supplied DSN is in its fullest form:
|
|
</para>
|
|
<programlisting>
|
|
phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value
|
|
</programlisting>
|
|
|
|
|
|
<para>
|
|
Most variations are allowed:
|
|
</para>
|
|
<programlisting>
|
|
phptype://username:password@protocol+hostspec:110//usr/db_file.db
|
|
phptype://username:password@hostspec/database
|
|
phptype://username:password@hostspec
|
|
phptype://username@hostspec
|
|
phptype://hostspec/database
|
|
phptype://hostspec
|
|
phptype:///database
|
|
phptype:///database?option=value&anotheroption=anothervalue
|
|
phptype(dbsyntax)
|
|
phptype
|
|
</programlisting>
|
|
|
|
<para>
|
|
The currently supported database backends are:
|
|
</para>
|
|
fbsql -> FrontBase?
|
|
ibase -> InterBase? / Firebird (requires PHP 5)
|
|
mssql -> Microsoft SQL Server (NOT for Sybase. Compile PHP --with-mssql)
|
|
mysql -> MySQL?
|
|
mysqli -> MySQL? (supports new authentication protocol) (requires PHP 5)
|
|
oci8 -> Oracle 7/8/9/10
|
|
pgsql -> PostgreSQL?
|
|
querysim -> QuerySim?
|
|
sqlite -> SQLite 2
|
|
|
|
<para>
|
|
A second DSN format is supported phptype(syntax)://user:pass@protocol(proto_opts)/database
|
|
</para>
|
|
|
|
|
|
<para>
|
|
If your database, option values, username or password contain characters used to delineate DSN parts, you can escape them via URI hex encodings:
|
|
</para>
|
|
: = %3a
|
|
/ = %2f
|
|
@ = %40
|
|
+ = %2b
|
|
( = %28
|
|
) = %29
|
|
? = %3f
|
|
= = %3d
|
|
& = %26
|
|
|
|
|
|
<important>
|
|
Please note, that some features may be not supported by all database backends.
|
|
</important>
|
|
|
|
<example>
|
|
<title>Connect to database through a socket</title>
|
|
<programlisting>
|
|
mysql://user@unix(/path/to/socket)/pear
|
|
</programlisting>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Connect to database on a non standard port</title>
|
|
<programlisting>
|
|
pgsql://user:pass@tcp(localhost:5555)/pear
|
|
</programlisting>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Connect to SQLite on a Unix machine using options</title>
|
|
<programlisting>
|
|
sqlite:////full/unix/path/to/file.db?mode=0666
|
|
</programlisting>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Connect to SQLite on a Windows machine using options</title>
|
|
<programlisting>
|
|
sqlite:///c:/full/windows/path/to/file.db?mode=0666
|
|
</programlisting>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Connect to MySQLi using SSL</title>
|
|
<programlisting>
|
|
mysqli://user:pass@localhost/pear?key=client-key.pem&cert=client-cert.pem
|
|
</programlisting>
|
|
</example>
|
|
</sect1>
|
|
<sect1 id="new-conn">
|
|
<title>Opening a new connection</title>
|
|
|
|
<para>
|
|
Opening a new database connection in Doctrine is very easy. If you wish
|
|
to use PDO (<ulink url="http://www.php.net/PDO">www.php.net/PDO</ulink>)
|
|
you can just initalize a new PDO object:
|
|
</para>
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
|
|
$user = 'dbuser';
|
|
$password = 'dbpass';
|
|
|
|
try {
|
|
$dbh = new PDO($dsn, $user, $password);
|
|
} catch (PDOException $e) {
|
|
echo 'Connection failed: ' . $e->getMessage();
|
|
}
|
|
?>]]></programlisting>
|
|
|
|
<para>
|
|
If your database extension isn't supported by PDO you can use special
|
|
Doctrine_Adapter class (if availible). The following example uses DB2
|
|
adapter:
|
|
</para>
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
$dsn = 'db2:dbname=testdb;host=127.0.0.1';
|
|
$user = 'dbuser';
|
|
$password = 'dbpass';
|
|
|
|
try {
|
|
$dbh = Doctrine_Adapter::connect($dsn, $user, $password);
|
|
} catch (PDOException $e) {
|
|
echo 'Connection failed: ' . $e->getMessage();
|
|
}
|
|
?>]]></programlisting>
|
|
|
|
<para>
|
|
The next step is opening a new Doctrine_Connection.
|
|
</para>
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
$conn = Doctrine_Manager::connection($dbh);
|
|
?>]]></programlisting>
|
|
</sect1>
|
|
<sect1 id="lazy-conn">
|
|
<title>Lazy Connections</title>
|
|
<para>
|
|
Lazy-connecting to database is handled via Doctrine_Db wrapper. When
|
|
using Doctrine_Db instead of PDO / Doctrine_Adapter, lazy-connecting to
|
|
database is being performed (that means Doctrine will only connect to
|
|
database when needed).
|
|
</para>
|
|
|
|
<para>
|
|
This feature can be very useful when using for example page caching,
|
|
hence not actually needing a database connection on every request.
|
|
Remember connecting to database is an expensive operation.
|
|
</para>
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
// we may use PDO / PEAR like DSN
|
|
// here we use PEAR like DSN
|
|
$dbh = new Doctrine_Db('mysql://username:password@localhost/test');
|
|
// !! no actual database connection yet !!
|
|
|
|
// initalize a new Doctrine_Connection
|
|
$conn = Doctrine_Manager::connection($dbh);
|
|
// !! no actual database connection yet !!
|
|
|
|
// connects database and performs a query
|
|
$conn->query('FROM User u');
|
|
?>]]></programlisting>
|
|
</sect1>
|
|
<sect1 id="managing-conn">
|
|
<title>Managing Connections</title>
|
|
<para>
|
|
From the start Doctrine has been designed to work with multiple
|
|
connections. Unless separately specified Doctrine always uses the current
|
|
connection for executing the queries. The following example uses
|
|
openConnection() second argument as an optional connection alias.
|
|
</para>
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
// Doctrine_Manager controls all the connections
|
|
$manager = Doctrine_Manager::getInstance();
|
|
|
|
// open first connection
|
|
$conn = $manager->openConnection(new PDO('dsn','username','password'), 'connection 1');
|
|
?>]]></programlisting>
|
|
|
|
<para>
|
|
For convenience Doctrine_Manager provides static method connection()
|
|
which opens new connection when arguments are given to it and returns the
|
|
current connection when no arguments have been speficied.
|
|
</para>
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
// open first connection
|
|
$conn = Doctrine_Manager::connection(new PDO('dsn','username','password'), 'connection 1');
|
|
|
|
$conn2 = Doctrine_Manager::connection();
|
|
// $conn2 == $conn
|
|
?>]]></programlisting>
|
|
|
|
<para>
|
|
The current connection is the lastly opened connection.
|
|
</para>
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
// open second connection
|
|
$conn2 = $manager->openConnection(new PDO('dsn2','username2','password2'), 'connection 2');
|
|
|
|
$manager->getCurrentConnection(); // $conn2
|
|
?>]]></programlisting>
|
|
|
|
<para>
|
|
You can change the current connection by calling setCurrentConnection().
|
|
</para>
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
|
|
$manager->setCurrentConnection('connection 1');
|
|
|
|
$manager->getCurrentConnection(); // $conn
|
|
|
|
?>]]></programlisting>
|
|
|
|
|
|
<para>
|
|
You can iterate over the opened connection by simple passing the manager
|
|
object to foreach clause. This is possible since Doctrine_Manager
|
|
implements special IteratorAggregate interface.
|
|
</para>
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
// iterating through connections
|
|
foreach($manager as $conn) {
|
|
|
|
}
|
|
?>]]></programlisting>
|
|
</sect1>
|
|
<sect1 id="conn-component-binding">
|
|
<title>Connection-component binding</title>
|
|
|
|
<para>
|
|
Doctrine allows you to bind connections to components (= your
|
|
ActiveRecord? classes). This means everytime a component issues a query
|
|
or data is being fetched from the table the component is pointing at
|
|
Doctrine will use the bound connection.
|
|
</para>
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<?php
|
|
$conn = $manager->openConnection(new PDO('dsn','username','password'), 'connection 1');
|
|
|
|
$conn2 = $manager->openConnection(new PDO('dsn2','username2','password2'), 'connection 2');
|
|
|
|
$manager->bindComponent('User', 'connection 1');
|
|
|
|
$manager->bindComponent('Group', 'connection 2');
|
|
|
|
$q = new Doctrine_Query();
|
|
|
|
// Doctrine uses 'connection 1' for fetching here
|
|
$users = $q->from('User u')->where('u.id IN (1,2,3)')->execute();
|
|
|
|
// Doctrine uses 'connection 2' for fetching here
|
|
$groups = $q->from('Group g')->where('g.id IN (1,2,3)')->execute();
|
|
?>]]></programlisting>
|
|
</sect1>
|
|
</chapter>
|