Path

ez components / documentation / api reference / 2008.1 / database


Database

[ Tutorial ] [ Class tree ] [ Element index ] [ ChangeLog ] [ Credits ]

Source for file factory.php

Documentation is available at factory.php

  1. <?php
  2. /**
  3.  * File containing the ezcDbFactory class.
  4.  *
  5.  * @package Database
  6.  * @version 1.4
  7.  * @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
  8.  * @license http://ez.no/licenses/new_bsd New BSD License
  9.  */
 10.  
 11. /**
 12.  * ezcDbFactory manages the list of known database drivers
 13.  * and is used to create their instances.
 14.  *
 15.  * Example:
 16.  * <code>
 17.  * $dbparams = array(
 18.  *     'type'   => 'mysql',
 19.  *     'dbname' => 'test',
 20.  *     'user'   => 'john',
 21.  *     'pass'   => 'topsecret' );
 22.  * $db = ezcDbFactory::create( $dbparams );
 23.  * $db->query( 'SELECT * FROM tbl' );
 24.  * </code>
 25.  *
 26.  * Instead of passing an array with those parameters, you can also pass a DSN:
 27.  *
 28.  * <code>
 29.  * $dsn = "mysql://root@localhost/geolocation";
 30.  * $db = ezcDbFactory::create( $dsn );
 31.  * </code>
 32.  *
 33.  * Other examples of DSNs are:
 34.  * <code>
 35.  * $dsn = "sqlite:///tmp/ezc.sqlite"; // Disk based databases for SQLite.
 36.  * $dsn = "sqlite://:memory:";        // In memory databases for SQLite.
 37.  * </code>
 38.  *
 39.  * Note that this class does not deal with character sets automatically, you
 40.  * have to make sure that you do that yourself. For MySQL that means running
 41.  * a query "SET NAMES" for example. See the tutorial for some hints on this.
 42.  *
 43.  * @see create()
 44.  *
 45.  * @package Database
 46.  * @version 1.4
 47.  */
 48. class ezcDbFactory
 49. {
 50.     /**
 51.      * List of supported database implementations.
 52.      *
 53.      * The list is an array with the form 'dbname' => 'HandlerClassName'
 54.      * This list may be extended using {@link addImplementation()}.
 55.      *
 56.      * @var array(string=>string) 
 57.      */
 58.     static private $implementations array'mysql'  => 'ezcDbHandlerMysql',
 59.                                              'pgsql'  => 'ezcDbHandlerPgsql',
 60.                                              'oracle' => 'ezcDbHandlerOracle',
 61.                                              'sqlite' => 'ezcDbHandlerSqlite',
 62.                                              'mssql' => 'ezcDbHandlerMssql');
 63.  
 64.     /**
 65.      * Adds a database implementation to the list of known implementations.
 66.      *
 67.      * $implementationName is the name of the implemenation. This name should
 68.      * be short and uniquely identify the database. $className is the class name
 69.      * of the class that implements the handler for this database.
 70.      *
 71.      * Example:
 72.      * <code>
 73.      * class DB2Handler
 74.      * {
 75.      * }
 76.      * ezcDbFactory::addImplementation( 'db2', 'DB2Handler' );
 77.      * // ...
 78.      * $dbparams = array( 'handler' => 'db2', ... );
 79.      * $db = ezcDbFactory::create( $dbparams );
 80.      * </code>
 81.      *
 82.      * @param string $implementationName 
 83.      * @param string $className 
 84.      * @return void 
 85.      */
 86.     static public function addImplementation$implementationName$className )
 87.     {
 88.         self::$implementations[$implementationName$className;
 89.     }
 90.  
 91.     /**
 92.      * Returns a list with supported database implementations.
 93.      *
 94.      * Example:
 95.      * <code>
 96.      * ezcDbFactory::getImplementations();
 97.      * </code>
 98.      *
 99.      * @return array(string) 
100.      */
101.     static public function getImplementations()
102.     {
103.         $list array();
104.         foreach self::$implementations as $name => $className )
105.         {
106.             $list[$name;
107.         }
108.         return $list;
109.     }
110.  
111.     /**
112.      * Creates and returns an instance of the specified ezcDbHandler implementation.
113.      *
114.      * Supported database parameters are:
115.      * - phptype|type|handler|driver: Database implementation
116.      * - user|username:               Database user name
117.      * - pass|password:               Database user password
118.      * - dbname|database:             Database name
119.      * - host|hostspec:               Name of the host database is running on
120.      * - port:                        TCP port
121.      * - charset:                     Client character set
122.      * - socket:                      UNIX socket path
123.      *
124.      * The list above is actually driver-dependent and may be extended in the future.
125.      * You can specify any parameters your database handler supports.
126.      *
127.      * @throws ezcDbHandlerNotFoundException if the requested database handler could not be found.
128.      * @param   mixed  $dbParams Database parameters
129.      *                  (driver, host, port, user, pass, etc).
130.      *                  May be specified either as array (key => val ....) or as DSN string.
131.      *                  Format of the DSN is the same as accepted by PEAR::DB::parseDSN().
132.      * @return ezcDbHandler 
133.      */
134.     static public function create$dbParams )
135.     {
136.         if is_string$dbParams ) )
137.         {
138.             $dbParams self::parseDSN$dbParams );
139.         }
140.  
141.         $impName null// implementation name
142.  
143.         foreach $dbParams as $key => $val )
144.         {
145.             if in_array$keyarray'phptype''type''handler''driver' ) ) )
146.             {
147.                  $impName $val;
148.                  break;
149.             }
150.         }
151.  
152.         if $impName === null || !array_key_exists$impNameself::$implementations ) )
153.         {
154.             throw new ezcDbHandlerNotFoundException$impNamearray_keysself::$implementations ) );
155.         }
156.  
157.         $className self::$implementations[$impName];
158.         $instance new $className$dbParams );
159.  
160.         return $instance;
161.     }
162.  
163.     /**
164.      * Returns the Data Source Name as a structure containing the various parts of the DSN.
165.      *
166.      * Additional keys can be added by appending a URI query string to the
167.      * end of the DSN.
168.      *
169.      * The format of the supplied DSN is in its fullest form:
170.      * <code>
171.      *  phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true
172.      * </code>
173.      *
174.      * Most variations are allowed:
175.      * <code>
176.      *  phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644
177.      *  phptype://username:password@hostspec/database_name
178.      *  phptype://username:password@hostspec
179.      *  phptype://username@hostspec
180.      *  phptype://hostspec/database
181.      *  phptype://hostspec
182.      *  phptype(dbsyntax)
183.      *  phptype
184.      * </code>
185.      *
186.      * This function is 'borrowed' from PEAR /DB.php .
187.      *
188.      * @param string $dsn Data Source Name to be parsed
189.      *
190.      * @return array an associative array with the following keys:
191.      *   + phptype:  Database backend used in PHP (mysql, odbc etc.)
192.      *   + dbsyntax: Database used with regards to SQL syntax etc.
193.      *   + protocol: Communication protocol to use (tcp, unix etc.)
194.      *   + hostspec: Host specification (hostname[:port])
195.      *   + database: Database to use on the DBMS server
196.      *   + username: User name for login
197.      *   + password: Password for login
198.      */
199.     public static function parseDSN$dsn )
200.     {
201.         $parsed array(
202.             'phptype'  => false,
203.             'dbsyntax' => false,
204.             'username' => false,
205.             'password' => false,
206.             'protocol' => false,
207.             'hostspec' => false,
208.             'port'     => false,
209.             'socket'   => false,
210.             'database' => false,
211.         );
212.  
213.         if is_array$dsn ) )
214.         {
215.             $dsn array_merge$parsed$dsn );
216.             if !$dsn['dbsyntax')
217.             {
218.                 $dsn['dbsyntax'$dsn['phptype'];
219.             }
220.             return $dsn;
221.         }
222.  
223.         // Find phptype and dbsyntax
224.         if ( ( $pos strpos$dsn'://' ) ) !== false )
225.         {
226.             $str substr$dsn0$pos );
227.             $dsn substr$dsn$pos );
228.         }
229.         else
230.         {
231.             $str $dsn;
232.             $dsn null;
233.         }
234.  
235.         // Get phptype and dbsyntax
236.         // $str => phptype(dbsyntax)
237.         if preg_match'|^(.+?)\((.*?)\)$|'$str$arr ) )
238.         {
239.             $parsed['phptype']  $arr[1];
240.             $parsed['dbsyntax'!$arr[2$arr[1$arr[2];
241.         }
242.         else
243.         {
244.             $parsed['phptype']  $str;
245.             $parsed['dbsyntax'$str;
246.         }
247.  
248.         if !count$dsn ) )
249.         {
250.             return $parsed;
251.         }
252.  
253.         // Get (if found): username and password
254.         // $dsn => username:password@protocol+hostspec/database
255.         if ( ( $at strrpos(string) $dsn'@' ) ) !== false )
256.         {
257.             $str substr$dsn0$at );
258.             $dsn substr$dsn$at );
259.             if ( ( $pos strpos$str':' ) ) !== false )
260.             {
261.                 $parsed['username'rawurldecodesubstr$str0$pos ) );
262.                 $parsed['password'rawurldecodesubstr$str$pos ) );
263.             }
264.             else
265.             {
266.                 $parsed['username'rawurldecode$str );
267.             }
268.         }
269.  
270.         // Find protocol and hostspec
271.  
272.         if preg_match'|^([^(]+)\((.*?)\)/?(.*?)$|'$dsn$match ) )
273.         {
274.             // $dsn => proto(proto_opts)/database
275.             $proto       $match[1];
276.             $proto_opts  $match[2$match[2false;
277.             $dsn         $match[3];
278.         }
279.         else
280.         {
281.             // $dsn => protocol+hostspec/database (old format)
282.             if strpos$dsn'+' !== false )
283.             {
284.                 list$proto$dsn explode'+'$dsn);
285.             }
286.             if strpos$dsn'/' !== false )
287.             {
288.                 list$proto_opts$dsn explode'/'$dsn);
289.             }
290.             else
291.             {
292.                 $proto_opts $dsn;
293.                 $dsn null;
294.             }
295.         }
296.  
297.         // process the different protocol options
298.         $parsed['protocol'!empty$proto ) ) $proto 'tcp';
299.         $proto_opts rawurldecode$proto_opts );
300.         if $parsed['protocol'== 'tcp' )
301.         {
302.             if strpos$proto_opts':' !== false )
303.             {
304.                 list$parsed['hostspec']$parsed['port'explode':'$proto_opts );
305.             }
306.             else
307.             {
308.                 $parsed['hostspec'$proto_opts;
309.             }
310.         }
311.         elseif $parsed['protocol'== 'unix' )
312.         {
313.             $parsed['socket'$proto_opts;
314.         }
315.  
316.         // Get dabase if any
317.         // $dsn => database
318.         if $dsn )
319.         {
320.             if ( ( $pos strpos$dsn'?' ) ) === false )
321.             {
322.                 // /database
323.                 $parsed['database'rawurldecode$dsn );
324.             }
325.             else
326.             {
327.                 // /database?param1=value1&param2=value2
328.                 $parsed['database'rawurldecodesubstr$dsn0$pos ) );
329.                 $dsn substr$dsn$pos );
330.                 if strpos$dsn'&'!== false )
331.                 {
332.                     $opts explode'&'$dsn );
333.                 }
334.                 else
335.                 // database?param1=value1
336.                     $opts array$dsn );
337.                 }
338.                 foreach $opts as $opt )
339.                 {
340.                     list$key$value explode'='$opt );
341.                     if !isset$parsed[$key) )
342.                     {
343.                         // don't allow params overwrite
344.                         $parsed[$keyrawurldecode$value );
345.                     }
346.                 }
347.             }
348.         }
349.         return $parsed;
350.     }
351. }
352. ?>
Last updated: Wed, 18 Jun 2008