zend/db.php,Zend Framework入门教程之Zend_Db数据库操作详解

本文详细介绍了如何在Zend Framework中使用Zend_Db进行数据库操作,包括连接不同数据库、查询、更新和删除,以及核心的工厂方法的工作原理。实例演示了MySQL和SQLite的连接,展示了如何执行SQL查询并解析源码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文实例讲述了Zend Framework中Zend_Db数据库操作方法。分享给大家供大家参考,具体如下:

引言:Zend操作数据库通过Zend_Db_Adapter

它可以连接多种数据库,可以是DB2数据库、MySQli数据库、Oracle数据库。等等。

只需要配置相应的参数就可以了。

下面通过案例来展示一下其连接数据库的过程。

连接mysql数据库

代码:<?php

require_once 'Zend/Db.php';

$params = array('host'=>'127.0.0.1',

'username'=>'root',

'password'=>'',

'dbname'=>'test'

);

$db = Zend_Db::factory('PDO_Mysql',$params);

点评:

这是连接mysql的代码案例,提供相应的参数就可以了。连接不同的数据库,提供不同的参数。下面是sqlite的例子

代码:<?php

require_once 'Zend/Db.php';

$params = array('dbname'=>'test.mdb');

$db = Zend_Db::factory('PDO_Sqlite',$params);

点评:

sqlite明显参数不一样了,只需要提供数据库名字就可以了。

连接完数据库之后,就可以查询数据库信息以及操作数据库信息了。

如果查询呢?

下面是查询的代码案例:<?php

require_once 'Zend/Db.php';

$params = array('host'=>'127.0.0.1',

'username'=>'root',

'password'=>'',

'dbname'=>'test'

);

$db = Zend_Db::factory('PDO_Mysql',$params);

$sql = $db->quoteInto('SELECT * FROM user WHERE id','5');

$result = $db->query($sql); //执行SQL查询

$r_a = $result->fetchAll(); //返回结果数组

print_r($r_a);

点评:

执行完上述代码,就会展示出数据库中前五条记录的信息。

那么这其中的玄机是什么呢?

我们来看一下源码。

我们来看看Db.php中的factory方法public static function factory($adapter, $config = array())

{

if ($config instanceof Zend_Config) {

$config = $config->toArray();

}

/*

* Convert Zend_Config argument to plain string

* adapter name and separate config object.

*/

if ($adapter instanceof Zend_Config) {

if (isset($adapter->params)) {

$config = $adapter->params->toArray();

}

if (isset($adapter->adapter)) {

$adapter = (string) $adapter->adapter;

} else {

$adapter = null;

}

}

/*

* Verify that adapter parameters are in an array.

*/

if (!is_array($config)) {

/**

* @see Zend_Db_Exception

*/

require_once 'Zend/Db/Exception.php';

throw new Zend_Db_Exception('Adapter parameters must be in an array or a Zend_Config object');

}

/*

* Verify that an adapter name has been specified.

*/

if (!is_string($adapter) || empty($adapter)) {

/**

* @see Zend_Db_Exception

*/

require_once 'Zend/Db/Exception.php';

throw new Zend_Db_Exception('Adapter name must be specified in a string');

}

/*

* Form full adapter class name

*/

$adapterNamespace = 'Zend_Db_Adapter';

if (isset($config['adapterNamespace'])) {

if ($config['adapterNamespace'] != '') {

$adapterNamespace = $config['adapterNamespace'];

}

unset($config['adapterNamespace']);

}

// Adapter no longer normalized- see http://framework.zend.com/issues/browse/ZF-5606

$adapterName = $adapterNamespace . '_';

$adapterName .= str_replace(' ', '_', ucwords(str_replace('_', ' ', strtolower($adapter))));

print_r($adapterName);exit;

/*

* Load the adapter class. This throws an exception

* if the specified class cannot be loaded.

*/

if (!class_exists($adapterName)) {

require_once 'Zend/Loader.php';

Zend_Loader::loadClass($adapterName);

}

/*

* Create an instance of the adapter class.

* Pass the config to the adapter class constructor.

*/

$dbAdapter = new $adapterName($config);

/*

* Verify that the object created is a descendent of the abstract adapter type.

*/

if (! $dbAdapter instanceof Zend_Db_Adapter_Abstract) {

/**

* @see Zend_Db_Exception

*/

require_once 'Zend/Db/Exception.php';

throw new Zend_Db_Exception("Adapter class '$adapterName' does not extend Zend_Db_Adapter_Abstract");

}

return $dbAdapter;

}

点评:这个方法就是核心了,代码量不多,但是作用很明确,它会通过你提供的两个参数,自动生成相应的数据库连接类的对象。具有一定的灵活性,机动性。

主要是其中的$adapterName = $adapterNamespace . '_';

$adapterName .= str_replace(' ', '_', ucwords(str_replace('_', ' ', strtolower($adapter))));

/*

* Load the adapter class. This throws an exception

* if the specified class cannot be loaded.

*/

if (!class_exists($adapterName)) {

require_once 'Zend/Loader.php';

Zend_Loader::loadClass($adapterName);

}

这段代码会引入相应的数据库连接类,比如前面的两个例子,就是分别引入了Zend目录下Db目录下Adapter目录下Pdo目录下的mysql.php类。

不同的数据库,会引入不同的数据库文件。

我们来看看mysql.php类中的内容:<?php

/**

* Zend Framework

*

* LICENSE

*

* This source file is subject to the new BSD license that is bundled

* with this package in the file LICENSE.txt.

* It is also available through the world-wide-web at this URL:

* http://framework.zend.com/license/new-bsd

* If you did not receive a copy of the license and are unable to

* obtain it through the world-wide-web, please send an email

* to license@zend.com so we can send you a copy immediately.

*

* @category Zend

* @package Zend_Db

* @subpackage Adapter

* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)

* @license http://framework.zend.com/license/new-bsd New BSD License

* @version $Id: Mysql.php 24593 2012-01-05 20:35:02Z matthew $

*/

/**

* @see Zend_Db_Adapter_Pdo_Abstract

*/

require_once 'Zend/Db/Adapter/Pdo/Abstract.php';

/**

* Class for connecting to MySQL databases and performing common operations.

*

* @category Zend

* @package Zend_Db

* @subpackage Adapter

* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)

* @license http://framework.zend.com/license/new-bsd New BSD License

*/

class Zend_Db_Adapter_Pdo_Mysql extends Zend_Db_Adapter_Pdo_Abstract

{

/**

* PDO type.

*

* @var string

*/

protected $_pdoType = 'mysql';

/**

* Keys are UPPERCASE SQL datatypes or the constants

* Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.

*

* Values are:

* 0 = 32-bit integer

* 1 = 64-bit integer

* 2 = float or decimal

*

* @var array Associative array of datatypes to values 0, 1, or 2.

*/

protected $_numericDataTypes = array(

Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,

Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,

Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,

'INT' => Zend_Db::INT_TYPE,

'INTEGER' => Zend_Db::INT_TYPE,

'MEDIUMINT' => Zend_Db::INT_TYPE,

'SMALLINT' => Zend_Db::INT_TYPE,

'TINYINT' => Zend_Db::INT_TYPE,

'BIGINT' => Zend_Db::BIGINT_TYPE,

'SERIAL' => Zend_Db::BIGINT_TYPE,

'DEC' => Zend_Db::FLOAT_TYPE,

'DECIMAL' => Zend_Db::FLOAT_TYPE,

'DOUBLE' => Zend_Db::FLOAT_TYPE,

'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE,

'FIXED' => Zend_Db::FLOAT_TYPE,

'FLOAT' => Zend_Db::FLOAT_TYPE

);

/**

* Override _dsn() and ensure that charset is incorporated in mysql

* @see Zend_Db_Adapter_Pdo_Abstract::_dsn()

*/

protected function _dsn()

{

$dsn = parent::_dsn();

if (isset($this->_config['charset'])) {

$dsn .= ';charset=' . $this->_config['charset'];

}

return $dsn;

}

/**

* Creates a PDO object and connects to the database.

*

* @return void

* @throws Zend_Db_Adapter_Exception

*/

protected function _connect()

{

if ($this->_connection) {

return;

}

if (!empty($this->_config['charset'])) {

$initCommand = "SET NAMES '" . $this->_config['charset'] . "'";

$this->_config['driver_options'][1002] = $initCommand; // 1002 = PDO::MYSQL_ATTR_INIT_COMMAND

}

parent::_connect();

}

/**

* @return string

*/

public function getQuoteIdentifierSymbol()

{

return "`";

}

/**

* Returns a list of the tables in the database.

*

* @return array

*/

public function listTables()

{

return $this->fetchCol('SHOW TABLES');

}

/**

* Returns the column descriptions for a table.

*

* The return value is an associative array keyed by the column name,

* as returned by the RDBMS.

*

* The value of each array element is an associative array

* with the following keys:

*

* SCHEMA_NAME => string; name of database or schema

* TABLE_NAME => string;

* COLUMN_NAME => string; column name

* COLUMN_POSITION => number; ordinal position of column in table

* DATA_TYPE => string; SQL datatype name of column

* DEFAULT => string; default expression of column, null if none

* NULLABLE => boolean; true if column can have nulls

* LENGTH => number; length of CHAR/VARCHAR

* SCALE => number; scale of NUMERIC/DECIMAL

* PRECISION => number; precision of NUMERIC/DECIMAL

* UNSIGNED => boolean; unsigned property of an integer type

* PRIMARY => boolean; true if column is part of the primary key

* PRIMARY_POSITION => integer; position of column in primary key

* IDENTITY => integer; true if column is auto-generated with unique values

*

* @param string $tableName

* @param string $schemaName OPTIONAL

* @return array

*/

public function describeTable($tableName, $schemaName = null)

{

// @todo use INFORMATION_SCHEMA someday when MySQL's

// implementation has reasonably good performance and

// the version with this improvement is in wide use.

if ($schemaName) {

$sql = 'DESCRIBE ' . $this->quoteIdentifier("$schemaName.$tableName", true);

} else {

$sql = 'DESCRIBE ' . $this->quoteIdentifier($tableName, true);

}

$stmt = $this->query($sql);

// Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection

$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);

$field = 0;

$type = 1;

$null = 2;

$key = 3;

$default = 4;

$extra = 5;

$desc = array();

$i = 1;

$p = 1;

foreach ($result as $row) {

list($length, $scale, $precision, $unsigned, $primary, $primaryPosition, $identity)

= array(null, null, null, null, false, null, false);

if (preg_match('/unsigned/', $row[$type])) {

$unsigned = true;

}

if (preg_match('/^((?:var)?char)\((\d+)\)/', $row[$type], $matches)) {

$row[$type] = $matches[1];

$length = $matches[2];

} else if (preg_match('/^decimal\((\d+),(\d+)\)/', $row[$type], $matches)) {

$row[$type] = 'decimal';

$precision = $matches[1];

$scale = $matches[2];

} else if (preg_match('/^float\((\d+),(\d+)\)/', $row[$type], $matches)) {

$row[$type] = 'float';

$precision = $matches[1];

$scale = $matches[2];

} else if (preg_match('/^((?:big|medium|small|tiny)?int)\((\d+)\)/', $row[$type], $matches)) {

$row[$type] = $matches[1];

// The optional argument of a MySQL int type is not precision

// or length; it is only a hint for display width.

}

if (strtoupper($row[$key]) == 'PRI') {

$primary = true;

$primaryPosition = $p;

if ($row[$extra] == 'auto_increment') {

$identity = true;

} else {

$identity = false;

}

++$p;

}

$desc[$this->foldCase($row[$field])] = array(

'SCHEMA_NAME' => null, // @todo

'TABLE_NAME' => $this->foldCase($tableName),

'COLUMN_NAME' => $this->foldCase($row[$field]),

'COLUMN_POSITION' => $i,

'DATA_TYPE' => $row[$type],

'DEFAULT' => $row[$default],

'NULLABLE' => (bool) ($row[$null] == 'YES'),

'LENGTH' => $length,

'SCALE' => $scale,

'PRECISION' => $precision,

'UNSIGNED' => $unsigned,

'PRIMARY' => $primary,

'PRIMARY_POSITION' => $primaryPosition,

'IDENTITY' => $identity

);

++$i;

}

return $desc;

}

/**

* Adds an adapter-specific LIMIT clause to the SELECT statement.

*

* @param string $sql

* @param integer $count

* @param integer $offset OPTIONAL

* @throws Zend_Db_Adapter_Exception

* @return string

*/

public function limit($sql, $count, $offset = 0)

{

$count = intval($count);

if ($count <= 0) {

/** @see Zend_Db_Adapter_Exception */

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");

}

$offset = intval($offset);

if ($offset < 0) {

/** @see Zend_Db_Adapter_Exception */

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");

}

$sql .= " LIMIT $count";

if ($offset > 0) {

$sql .= " OFFSET $offset";

}

return $sql;

}

}

这里又引入了一个Abstract类,抽象类<?php

/**

* Zend Framework

*

* LICENSE

*

* This source file is subject to the new BSD license that is bundled

* with this package in the file LICENSE.txt.

* It is also available through the world-wide-web at this URL:

* http://framework.zend.com/license/new-bsd

* If you did not receive a copy of the license and are unable to

* obtain it through the world-wide-web, please send an email

* to license@zend.com so we can send you a copy immediately.

*

* @category Zend

* @package Zend_Db

* @subpackage Adapter

* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)

* @license http://framework.zend.com/license/new-bsd New BSD License

* @version $Id: Abstract.php 24593 2012-01-05 20:35:02Z matthew $

*/

/**

* @see Zend_Db_Adapter_Abstract

*/

require_once 'Zend/Db/Adapter/Abstract.php';

/**

* @see Zend_Db_Statement_Pdo

*/

require_once 'Zend/Db/Statement/Pdo.php';

/**

* Class for connecting to SQL databases and performing common operations using PDO.

*

* @category Zend

* @package Zend_Db

* @subpackage Adapter

* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)

* @license http://framework.zend.com/license/new-bsd New BSD License

*/

abstract class Zend_Db_Adapter_Pdo_Abstract extends Zend_Db_Adapter_Abstract

{

/**

* Default class name for a DB statement.

*

* @var string

*/

protected $_defaultStmtClass = 'Zend_Db_Statement_Pdo';

/**

* Creates a PDO DSN for the adapter from $this->_config settings.

*

* @return string

*/

protected function _dsn()

{

// baseline of DSN parts

$dsn = $this->_config;

// don't pass the username, password, charset, persistent and driver_options in the DSN

unset($dsn['username']);

unset($dsn['password']);

unset($dsn['options']);

unset($dsn['charset']);

unset($dsn['persistent']);

unset($dsn['driver_options']);

// use all remaining parts in the DSN

foreach ($dsn as $key => $val) {

$dsn[$key] = "$key=$val";

}

return $this->_pdoType . ':' . implode(';', $dsn);

}

/**

* Creates a PDO object and connects to the database.

*

* @return void

* @throws Zend_Db_Adapter_Exception

*/

protected function _connect()

{

// if we already have a PDO object, no need to re-connect.

if ($this->_connection) {

return;

}

// get the dsn first, because some adapters alter the $_pdoType

$dsn = $this->_dsn();

// check for PDO extension

if (!extension_loaded('pdo')) {

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception('The PDO extension is required for this adapter but the extension is not loaded');

}

// check the PDO driver is available

if (!in_array($this->_pdoType, PDO::getAvailableDrivers())) {

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception('The ' . $this->_pdoType . ' driver is not currently installed');

}

// create PDO connection

$q = $this->_profiler->queryStart('connect', Zend_Db_Profiler::CONNECT);

// add the persistence flag if we find it in our config array

if (isset($this->_config['persistent']) && ($this->_config['persistent'] == true)) {

$this->_config['driver_options'][PDO::ATTR_PERSISTENT] = true;

}

try {

$this->_connection = new PDO(

$dsn,

$this->_config['username'],

$this->_config['password'],

$this->_config['driver_options']

);

$this->_profiler->queryEnd($q);

// set the PDO connection to perform case-folding on array keys, or not

$this->_connection->setAttribute(PDO::ATTR_CASE, $this->_caseFolding);

// always use exceptions.

$this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch (PDOException $e) {

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e);

}

}

/**

* Test if a connection is active

*

* @return boolean

*/

public function isConnected()

{

return ((bool) ($this->_connection instanceof PDO));

}

/**

* Force the connection to close.

*

* @return void

*/

public function closeConnection()

{

$this->_connection = null;

}

/**

* Prepares an SQL statement.

*

* @param string $sql The SQL statement with placeholders.

* @param array $bind An array of data to bind to the placeholders.

* @return PDOStatement

*/

public function prepare($sql)

{

$this->_connect();

$stmtClass = $this->_defaultStmtClass;

if (!class_exists($stmtClass)) {

require_once 'Zend/Loader.php';

Zend_Loader::loadClass($stmtClass);

}

$stmt = new $stmtClass($this, $sql);

$stmt->setFetchMode($this->_fetchMode);

return $stmt;

}

/**

* Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.

*

* As a convention, on RDBMS brands that support sequences

* (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence

* from the arguments and returns the last id generated by that sequence.

* On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method

* returns the last value generated for such a column, and the table name

* argument is disregarded.

*

* On RDBMS brands that don't support sequences, $tableName and $primaryKey

* are ignored.

*

* @param string $tableName OPTIONAL Name of table.

* @param string $primaryKey OPTIONAL Name of primary key column.

* @return string

*/

public function lastInsertId($tableName = null, $primaryKey = null)

{

$this->_connect();

return $this->_connection->lastInsertId();

}

/**

* Special handling for PDO query().

* All bind parameter names must begin with ':'

*

* @param string|Zend_Db_Select $sql The SQL statement with placeholders.

* @param array $bind An array of data to bind to the placeholders.

* @return Zend_Db_Statement_Pdo

* @throws Zend_Db_Adapter_Exception To re-throw PDOException.

*/

public function query($sql, $bind = array())

{

if (empty($bind) && $sql instanceof Zend_Db_Select) {

$bind = $sql->getBind();

}

if (is_array($bind)) {

foreach ($bind as $name => $value) {

if (!is_int($name) && !preg_match('/^:/', $name)) {

$newName = ":$name";

unset($bind[$name]);

$bind[$newName] = $value;

}

}

}

try {

return parent::query($sql, $bind);

} catch (PDOException $e) {

/**

* @see Zend_Db_Statement_Exception

*/

require_once 'Zend/Db/Statement/Exception.php';

throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e);

}

}

/**

* Executes an SQL statement and return the number of affected rows

*

* @param mixed $sql The SQL statement with placeholders.

* May be a string or Zend_Db_Select.

* @return integer Number of rows that were modified

* or deleted by the SQL statement

*/

public function exec($sql)

{

if ($sql instanceof Zend_Db_Select) {

$sql = $sql->assemble();

}

try {

$affected = $this->getConnection()->exec($sql);

if ($affected === false) {

$errorInfo = $this->getConnection()->errorInfo();

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception($errorInfo[2]);

}

return $affected;

} catch (PDOException $e) {

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e);

}

}

/**

* Quote a raw string.

*

* @param string $value Raw string

* @return string Quoted string

*/

protected function _quote($value)

{

if (is_int($value) || is_float($value)) {

return $value;

}

$this->_connect();

return $this->_connection->quote($value);

}

/**

* Begin a transaction.

*/

protected function _beginTransaction()

{

$this->_connect();

$this->_connection->beginTransaction();

}

/**

* Commit a transaction.

*/

protected function _commit()

{

$this->_connect();

$this->_connection->commit();

}

/**

* Roll-back a transaction.

*/

protected function _rollBack() {

$this->_connect();

$this->_connection->rollBack();

}

/**

* Set the PDO fetch mode.

*

* @todo Support FETCH_CLASS and FETCH_INTO.

*

* @param int $mode A PDO fetch mode.

* @return void

* @throws Zend_Db_Adapter_Exception

*/

public function setFetchMode($mode)

{

//check for PDO extension

if (!extension_loaded('pdo')) {

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception('The PDO extension is required for this adapter but the extension is not loaded');

}

switch ($mode) {

case PDO::FETCH_LAZY:

case PDO::FETCH_ASSOC:

case PDO::FETCH_NUM:

case PDO::FETCH_BOTH:

case PDO::FETCH_NAMED:

case PDO::FETCH_OBJ:

$this->_fetchMode = $mode;

break;

default:

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception("Invalid fetch mode '$mode' specified");

break;

}

}

/**

* Check if the adapter supports real SQL parameters.

*

* @param string $type 'positional' or 'named'

* @return bool

*/

public function supportsParameters($type)

{

switch ($type) {

case 'positional':

case 'named':

default:

return true;

}

}

/**

* Retrieve server version in PHP style

*

* @return string

*/

public function getServerVersion()

{

$this->_connect();

try {

$version = $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION);

} catch (PDOException $e) {

// In case of the driver doesn't support getting attributes

return null;

}

$matches = null;

if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $version, $matches)) {

return $matches[1];

} else {

return null;

}

}

}

这个抽象类中又有另一个核心的抽象类。一些核心的方法都在这里<?php

/**

* Zend Framework

*

* LICENSE

*

* This source file is subject to the new BSD license that is bundled

* with this package in the file LICENSE.txt.

* It is also available through the world-wide-web at this URL:

* http://framework.zend.com/license/new-bsd

* If you did not receive a copy of the license and are unable to

* obtain it through the world-wide-web, please send an email

* to license@zend.com so we can send you a copy immediately.

*

* @category Zend

* @package Zend_Db

* @subpackage Adapter

* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)

* @license http://framework.zend.com/license/new-bsd New BSD License

* @version $Id: Abstract.php 25229 2013-01-18 08:17:21Z frosch $

*/

/**

* @see Zend_Db

*/

require_once 'Zend/Db.php';

/**

* @see Zend_Db_Select

*/

require_once 'Zend/Db/Select.php';

/**

* Class for connecting to SQL databases and performing common operations.

*

* @category Zend

* @package Zend_Db

* @subpackage Adapter

* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)

* @license http://framework.zend.com/license/new-bsd New BSD License

*/

abstract class Zend_Db_Adapter_Abstract

{

/**

* User-provided configuration

*

* @var array

*/

protected $_config = array();

/**

* Fetch mode

*

* @var integer

*/

protected $_fetchMode = Zend_Db::FETCH_ASSOC;

/**

* Query profiler object, of type Zend_Db_Profiler

* or a subclass of that.

*

* @var Zend_Db_Profiler

*/

protected $_profiler;

/**

* Default class name for a DB statement.

*

* @var string

*/

protected $_defaultStmtClass = 'Zend_Db_Statement';

/**

* Default class name for the profiler object.

*

* @var string

*/

protected $_defaultProfilerClass = 'Zend_Db_Profiler';

/**

* Database connection

*

* @var object|resource|null

*/

protected $_connection = null;

/**

* Specifies the case of column names retrieved in queries

* Options

* Zend_Db::CASE_NATURAL (default)

* Zend_Db::CASE_LOWER

* Zend_Db::CASE_UPPER

*

* @var integer

*/

protected $_caseFolding = Zend_Db::CASE_NATURAL;

/**

* Specifies whether the adapter automatically quotes identifiers.

* If true, most SQL generated by Zend_Db classes applies

* identifier quoting automatically.

* If false, developer must quote identifiers themselves

* by calling quoteIdentifier().

*

* @var bool

*/

protected $_autoQuoteIdentifiers = true;

/**

* Keys are UPPERCASE SQL datatypes or the constants

* Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.

*

* Values are:

* 0 = 32-bit integer

* 1 = 64-bit integer

* 2 = float or decimal

*

* @var array Associative array of datatypes to values 0, 1, or 2.

*/

protected $_numericDataTypes = array(

Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,

Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,

Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE

);

/** Weither or not that object can get serialized

*

* @var bool

*/

protected $_allowSerialization = true;

/**

* Weither or not the database should be reconnected

* to that adapter when waking up

*

* @var bool

*/

protected $_autoReconnectOnUnserialize = false;

/**

* Constructor.

*

* $config is an array of key/value pairs or an instance of Zend_Config

* containing configuration options. These options are common to most adapters:

*

* dbname => (string) The name of the database to user

* username => (string) Connect to the database as this username.

* password => (string) Password associated with the username.

* host => (string) What host to connect to, defaults to localhost

*

* Some options are used on a case-by-case basis by adapters:

*

* port => (string) The port of the database

* persistent => (boolean) Whether to use a persistent connection or not, defaults to false

* protocol => (string) The network protocol, defaults to TCPIP

* caseFolding => (int) style of case-alteration used for identifiers

* socket => (string) The socket or named pipe that should be used

*

* @param array|Zend_Config $config An array or instance of Zend_Config having configuration data

* @throws Zend_Db_Adapter_Exception

*/

public function __construct($config)

{

/*

* Verify that adapter parameters are in an array.

*/

if (!is_array($config)) {

/*

* Convert Zend_Config argument to a plain array.

*/

if ($config instanceof Zend_Config) {

$config = $config->toArray();

} else {

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception('Adapter parameters must be in an array or a Zend_Config object');

}

}

$this->_checkRequiredOptions($config);

$options = array(

Zend_Db::CASE_FOLDING => $this->_caseFolding,

Zend_Db::AUTO_QUOTE_IDENTIFIERS => $this->_autoQuoteIdentifiers,

Zend_Db::FETCH_MODE => $this->_fetchMode,

);

$driverOptions = array();

/*

* normalize the config and merge it with the defaults

*/

if (array_key_exists('options', $config)) {

// can't use array_merge() because keys might be integers

foreach ((array) $config['options'] as $key => $value) {

$options[$key] = $value;

}

}

if (array_key_exists('driver_options', $config)) {

if (!empty($config['driver_options'])) {

// can't use array_merge() because keys might be integers

foreach ((array) $config['driver_options'] as $key => $value) {

$driverOptions[$key] = $value;

}

}

}

if (!isset($config['charset'])) {

$config['charset'] = null;

}

if (!isset($config['persistent'])) {

$config['persistent'] = false;

}

$this->_config = array_merge($this->_config, $config);

$this->_config['options'] = $options;

$this->_config['driver_options'] = $driverOptions;

// obtain the case setting, if there is one

if (array_key_exists(Zend_Db::CASE_FOLDING, $options)) {

$case = (int) $options[Zend_Db::CASE_FOLDING];

switch ($case) {

case Zend_Db::CASE_LOWER:

case Zend_Db::CASE_UPPER:

case Zend_Db::CASE_NATURAL:

$this->_caseFolding = $case;

break;

default:

/** @see Zend_Db_Adapter_Exception */

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception('Case must be one of the following constants: '

. 'Zend_Db::CASE_NATURAL, Zend_Db::CASE_LOWER, Zend_Db::CASE_UPPER');

}

}

if (array_key_exists(Zend_Db::FETCH_MODE, $options)) {

if (is_string($options[Zend_Db::FETCH_MODE])) {

$constant = 'Zend_Db::FETCH_' . strtoupper($options[Zend_Db::FETCH_MODE]);

if(defined($constant)) {

$options[Zend_Db::FETCH_MODE] = constant($constant);

}

}

$this->setFetchMode((int) $options[Zend_Db::FETCH_MODE]);

}

// obtain quoting property if there is one

if (array_key_exists(Zend_Db::AUTO_QUOTE_IDENTIFIERS, $options)) {

$this->_autoQuoteIdentifiers = (bool) $options[Zend_Db::AUTO_QUOTE_IDENTIFIERS];

}

// obtain allow serialization property if there is one

if (array_key_exists(Zend_Db::ALLOW_SERIALIZATION, $options)) {

$this->_allowSerialization = (bool) $options[Zend_Db::ALLOW_SERIALIZATION];

}

// obtain auto reconnect on unserialize property if there is one

if (array_key_exists(Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE, $options)) {

$this->_autoReconnectOnUnserialize = (bool) $options[Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE];

}

// create a profiler object

$profiler = false;

if (array_key_exists(Zend_Db::PROFILER, $this->_config)) {

$profiler = $this->_config[Zend_Db::PROFILER];

unset($this->_config[Zend_Db::PROFILER]);

}

$this->setProfiler($profiler);

}

/**

* Check for config options that are mandatory.

* Throw exceptions if any are missing.

*

* @param array $config

* @throws Zend_Db_Adapter_Exception

*/

protected function _checkRequiredOptions(array $config)

{

// we need at least a dbname

if (! array_key_exists('dbname', $config)) {

/** @see Zend_Db_Adapter_Exception */

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'dbname' that names the database instance");

}

if (! array_key_exists('password', $config)) {

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'password' for login credentials");

}

if (! array_key_exists('username', $config)) {

/**

* @see Zend_Db_Adapter_Exception

*/

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception("Configuration array must have a key for 'username' for login credentials");

}

}

/**

* Returns the underlying database connection object or resource.

* If not presently connected, this initiates the connection.

*

* @return object|resource|null

*/

public function getConnection()

{

$this->_connect();

return $this->_connection;

}

/**

* Returns the configuration variables in this adapter.

*

* @return array

*/

public function getConfig()

{

return $this->_config;

}

/**

* Set the adapter's profiler object.

*

* The argument may be a boolean, an associative array, an instance of

* Zend_Db_Profiler, or an instance of Zend_Config.

*

* A boolean argument sets the profiler to enabled if true, or disabled if

* false. The profiler class is the adapter's default profiler class,

* Zend_Db_Profiler.

*

* An instance of Zend_Db_Profiler sets the adapter's instance to that

* object. The profiler is enabled and disabled separately.

*

* An associative array argument may contain any of the keys 'enabled',

* 'class', and 'instance'. The 'enabled' and 'instance' keys correspond to the

* boolean and object types documented above. The 'class' key is used to name a

* class to use for a custom profiler. The class must be Zend_Db_Profiler or a

* subclass. The class is instantiated with no constructor arguments. The 'class'

* option is ignored when the 'instance' option is supplied.

*

* An object of type Zend_Config may contain the properties 'enabled', 'class', and

* 'instance', just as if an associative array had been passed instead.

*

* @param Zend_Db_Profiler|Zend_Config|array|boolean $profiler

* @return Zend_Db_Adapter_Abstract Provides a fluent interface

* @throws Zend_Db_Profiler_Exception if the object instance or class specified

* is not Zend_Db_Profiler or an extension of that class.

*/

public function setProfiler($profiler)

{

$enabled = null;

$profilerClass = $this->_defaultProfilerClass;

$profilerInstance = null;

if ($profilerIsObject = is_object($profiler)) {

if ($profiler instanceof Zend_Db_Profiler) {

$profilerInstance = $profiler;

} else if ($profiler instanceof Zend_Config) {

$profiler = $profiler->toArray();

} else {

/**

* @see Zend_Db_Profiler_Exception

*/

require_once 'Zend/Db/Profiler/Exception.php';

throw new Zend_Db_Profiler_Exception('Profiler argument must be an instance of either Zend_Db_Profiler'

. ' or Zend_Config when provided as an object');

}

}

if (is_array($profiler)) {

if (isset($profiler['enabled'])) {

$enabled = (bool) $profiler['enabled'];

}

if (isset($profiler['class'])) {

$profilerClass = $profiler['class'];

}

if (isset($profiler['instance'])) {

$profilerInstance = $profiler['instance'];

}

} else if (!$profilerIsObject) {

$enabled = (bool) $profiler;

}

if ($profilerInstance === null) {

if (!class_exists($profilerClass)) {

require_once 'Zend/Loader.php';

Zend_Loader::loadClass($profilerClass);

}

$profilerInstance = new $profilerClass();

}

if (!$profilerInstance instanceof Zend_Db_Profiler) {

/** @see Zend_Db_Profiler_Exception */

require_once 'Zend/Db/Profiler/Exception.php';

throw new Zend_Db_Profiler_Exception('Class ' . get_class($profilerInstance) . ' does not extend '

. 'Zend_Db_Profiler');

}

if (null !== $enabled) {

$profilerInstance->setEnabled($enabled);

}

$this->_profiler = $profilerInstance;

return $this;

}

/**

* Returns the profiler for this adapter.

*

* @return Zend_Db_Profiler

*/

public function getProfiler()

{

return $this->_profiler;

}

/**

* Get the default statement class.

*

* @return string

*/

public function getStatementClass()

{

return $this->_defaultStmtClass;

}

/**

* Set the default statement class.

*

* @return Zend_Db_Adapter_Abstract Fluent interface

*/

public function setStatementClass($class)

{

$this->_defaultStmtClass = $class;

return $this;

}

/**

* Prepares and executes an SQL statement with bound data.

*

* @param mixed $sql The SQL statement with placeholders.

* May be a string or Zend_Db_Select.

* @param mixed $bind An array of data to bind to the placeholders.

* @return Zend_Db_Statement_Interface

*/

public function query($sql, $bind = array())

{

// connect to the database if needed

$this->_connect();

// is the $sql a Zend_Db_Select object?

if ($sql instanceof Zend_Db_Select) {

if (empty($bind)) {

$bind = $sql->getBind();

}

$sql = $sql->assemble();

}

// make sure $bind to an array;

// don't use (array) typecasting because

// because $bind may be a Zend_Db_Expr object

if (!is_array($bind)) {

$bind = array($bind);

}

// prepare and execute the statement with profiling

$stmt = $this->prepare($sql);

$stmt->execute($bind);

// return the results embedded in the prepared statement object

$stmt->setFetchMode($this->_fetchMode);

return $stmt;

}

/**

* Leave autocommit mode and begin a transaction.

*

* @return Zend_Db_Adapter_Abstract

*/

public function beginTransaction()

{

$this->_connect();

$q = $this->_profiler->queryStart('begin', Zend_Db_Profiler::TRANSACTION);

$this->_beginTransaction();

$this->_profiler->queryEnd($q);

return $this;

}

/**

* Commit a transaction and return to autocommit mode.

*

* @return Zend_Db_Adapter_Abstract

*/

public function commit()

{

$this->_connect();

$q = $this->_profiler->queryStart('commit', Zend_Db_Profiler::TRANSACTION);

$this->_commit();

$this->_profiler->queryEnd($q);

return $this;

}

/**

* Roll back a transaction and return to autocommit mode.

*

* @return Zend_Db_Adapter_Abstract

*/

public function rollBack()

{

$this->_connect();

$q = $this->_profiler->queryStart('rollback', Zend_Db_Profiler::TRANSACTION);

$this->_rollBack();

$this->_profiler->queryEnd($q);

return $this;

}

/**

* Inserts a table row with specified data.

*

* @param mixed $table The table to insert data into.

* @param array $bind Column-value pairs.

* @return int The number of affected rows.

* @throws Zend_Db_Adapter_Exception

*/

public function insert($table, array $bind)

{

// extract and quote col names from the array keys

$cols = array();

$vals = array();

$i = 0;

foreach ($bind as $col => $val) {

$cols[] = $this->quoteIdentifier($col, true);

if ($val instanceof Zend_Db_Expr) {

$vals[] = $val->__toString();

unset($bind[$col]);

} else {

if ($this->supportsParameters('positional')) {

$vals[] = '?';

} else {

if ($this->supportsParameters('named')) {

unset($bind[$col]);

$bind[':col'.$i] = $val;

$vals[] = ':col'.$i;

$i++;

} else {

/** @see Zend_Db_Adapter_Exception */

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");

}

}

}

}

// build the statement

$sql = "INSERT INTO "

. $this->quoteIdentifier($table, true)

. ' (' . implode(', ', $cols) . ') '

. 'VALUES (' . implode(', ', $vals) . ')';

// execute the statement and return the number of affected rows

if ($this->supportsParameters('positional')) {

$bind = array_values($bind);

}

$stmt = $this->query($sql, $bind);

$result = $stmt->rowCount();

return $result;

}

/**

* Updates table rows with specified data based on a WHERE clause.

*

* @param mixed $table The table to update.

* @param array $bind Column-value pairs.

* @param mixed $where UPDATE WHERE clause(s).

* @return int The number of affected rows.

* @throws Zend_Db_Adapter_Exception

*/

public function update($table, array $bind, $where = '')

{

/**

* Build "col = ?" pairs for the statement,

* except for Zend_Db_Expr which is treated literally.

*/

$set = array();

$i = 0;

foreach ($bind as $col => $val) {

if ($val instanceof Zend_Db_Expr) {

$val = $val->__toString();

unset($bind[$col]);

} else {

if ($this->supportsParameters('positional')) {

$val = '?';

} else {

if ($this->supportsParameters('named')) {

unset($bind[$col]);

$bind[':col'.$i] = $val;

$val = ':col'.$i;

$i++;

} else {

/** @see Zend_Db_Adapter_Exception */

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception(get_class($this) ." doesn't support positional or named binding");

}

}

}

$set[] = $this->quoteIdentifier($col, true) . ' = ' . $val;

}

$where = $this->_whereExpr($where);

/**

* Build the UPDATE statement

*/

$sql = "UPDATE "

. $this->quoteIdentifier($table, true)

. ' SET ' . implode(', ', $set)

. (($where) ? " WHERE $where" : '');

/**

* Execute the statement and return the number of affected rows

*/

if ($this->supportsParameters('positional')) {

$stmt = $this->query($sql, array_values($bind));

} else {

$stmt = $this->query($sql, $bind);

}

$result = $stmt->rowCount();

return $result;

}

/**

* Deletes table rows based on a WHERE clause.

*

* @param mixed $table The table to update.

* @param mixed $where DELETE WHERE clause(s).

* @return int The number of affected rows.

*/

public function delete($table, $where = '')

{

$where = $this->_whereExpr($where);

/**

* Build the DELETE statement

*/

$sql = "DELETE FROM "

. $this->quoteIdentifier($table, true)

. (($where) ? " WHERE $where" : '');

/**

* Execute the statement and return the number of affected rows

*/

$stmt = $this->query($sql);

$result = $stmt->rowCount();

return $result;

}

/**

* Convert an array, string, or Zend_Db_Expr object

* into a string to put in a WHERE clause.

*

* @param mixed $where

* @return string

*/

protected function _whereExpr($where)

{

if (empty($where)) {

return $where;

}

if (!is_array($where)) {

$where = array($where);

}

foreach ($where as $cond => &$term) {

// is $cond an int? (i.e. Not a condition)

if (is_int($cond)) {

// $term is the full condition

if ($term instanceof Zend_Db_Expr) {

$term = $term->__toString();

}

} else {

// $cond is the condition with placeholder,

// and $term is quoted into the condition

$term = $this->quoteInto($cond, $term);

}

$term = '(' . $term . ')';

}

$where = implode(' AND ', $where);

return $where;

}

/**

* Creates and returns a new Zend_Db_Select object for this adapter.

*

* @return Zend_Db_Select

*/

public function select()

{

return new Zend_Db_Select($this);

}

/**

* Get the fetch mode.

*

* @return int

*/

public function getFetchMode()

{

return $this->_fetchMode;

}

/**

* Fetches all SQL result rows as a sequential array.

* Uses the current fetchMode for the adapter.

*

* @param string|Zend_Db_Select $sql An SQL SELECT statement.

* @param mixed $bind Data to bind into SELECT placeholders.

* @param mixed $fetchMode Override current fetch mode.

* @return array

*/

public function fetchAll($sql, $bind = array(), $fetchMode = null)

{

if ($fetchMode === null) {

$fetchMode = $this->_fetchMode;

}

$stmt = $this->query($sql, $bind);

$result = $stmt->fetchAll($fetchMode);

return $result;

}

/**

* Fetches the first row of the SQL result.

* Uses the current fetchMode for the adapter.

*

* @param string|Zend_Db_Select $sql An SQL SELECT statement.

* @param mixed $bind Data to bind into SELECT placeholders.

* @param mixed $fetchMode Override current fetch mode.

* @return mixed Array, object, or scalar depending on fetch mode.

*/

public function fetchRow($sql, $bind = array(), $fetchMode = null)

{

if ($fetchMode === null) {

$fetchMode = $this->_fetchMode;

}

$stmt = $this->query($sql, $bind);

$result = $stmt->fetch($fetchMode);

return $result;

}

/**

* Fetches all SQL result rows as an associative array.

*

* The first column is the key, the entire row array is the

* value. You should construct the query to be sure that

* the first column contains unique values, or else

* rows with duplicate values in the first column will

* overwrite previous data.

*

* @param string|Zend_Db_Select $sql An SQL SELECT statement.

* @param mixed $bind Data to bind into SELECT placeholders.

* @return array

*/

public function fetchAssoc($sql, $bind = array())

{

$stmt = $this->query($sql, $bind);

$data = array();

while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) {

$tmp = array_values(array_slice($row, 0, 1));

$data[$tmp[0]] = $row;

}

return $data;

}

/**

* Fetches the first column of all SQL result rows as an array.

*

* @param string|Zend_Db_Select $sql An SQL SELECT statement.

* @param mixed $bind Data to bind into SELECT placeholders.

* @return array

*/

public function fetchCol($sql, $bind = array())

{

$stmt = $this->query($sql, $bind);

$result = $stmt->fetchAll(Zend_Db::FETCH_COLUMN, 0);

return $result;

}

/**

* Fetches all SQL result rows as an array of key-value pairs.

*

* The first column is the key, the second column is the

* value.

*

* @param string|Zend_Db_Select $sql An SQL SELECT statement.

* @param mixed $bind Data to bind into SELECT placeholders.

* @return array

*/

public function fetchPairs($sql, $bind = array())

{

$stmt = $this->query($sql, $bind);

$data = array();

while ($row = $stmt->fetch(Zend_Db::FETCH_NUM)) {

$data[$row[0]] = $row[1];

}

return $data;

}

/**

* Fetches the first column of the first row of the SQL result.

*

* @param string|Zend_Db_Select $sql An SQL SELECT statement.

* @param mixed $bind Data to bind into SELECT placeholders.

* @return string

*/

public function fetchOne($sql, $bind = array())

{

$stmt = $this->query($sql, $bind);

$result = $stmt->fetchColumn(0);

return $result;

}

/**

* Quote a raw string.

*

* @param string $value Raw string

* @return string Quoted string

*/

protected function _quote($value)

{

if (is_int($value)) {

return $value;

} elseif (is_float($value)) {

return sprintf('%F', $value);

}

return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";

}

/**

* Safely quotes a value for an SQL statement.

*

* If an array is passed as the value, the array values are quoted

* and then returned as a comma-separated string.

*

* @param mixed $value The value to quote.

* @param mixed $type OPTIONAL the SQL datatype name, or constant, or null.

* @return mixed An SQL-safe quoted value (or string of separated values).

*/

public function quote($value, $type = null)

{

$this->_connect();

if ($value instanceof Zend_Db_Select) {

return '(' . $value->assemble() . ')';

}

if ($value instanceof Zend_Db_Expr) {

return $value->__toString();

}

if (is_array($value)) {

foreach ($value as &$val) {

$val = $this->quote($val, $type);

}

return implode(', ', $value);

}

if ($type !== null && array_key_exists($type = strtoupper($type), $this->_numericDataTypes)) {

$quotedValue = '0';

switch ($this->_numericDataTypes[$type]) {

case Zend_Db::INT_TYPE: // 32-bit integer

$quotedValue = (string) intval($value);

break;

case Zend_Db::BIGINT_TYPE: // 64-bit integer

// ANSI SQL-style hex literals (e.g. x'[\dA-F]+')

// are not supported here, because these are string

// literals, not numeric literals.

if (preg_match('/^(

[+-]? # optional sign

(?:

0[Xx][\da-fA-F]+ # ODBC-style hexadecimal

|\d+ # decimal or octal, or MySQL ZEROFILL decimal

(?:[eE][+-]?\d+)? # optional exponent on decimals or octals

)

)/x',

(string) $value, $matches)) {

$quotedValue = $matches[1];

}

break;

case Zend_Db::FLOAT_TYPE: // float or decimal

$quotedValue = sprintf('%F', $value);

}

return $quotedValue;

}

return $this->_quote($value);

}

/**

* Quotes a value and places into a piece of text at a placeholder.

*

* The placeholder is a question-mark; all placeholders will be replaced

* with the quoted value. For example:

*

*

* $text = "WHERE date < ?";

* $date = "2005-01-02";

* $safe = $sql->quoteInto($text, $date);

* // $safe = "WHERE date < '2005-01-02'"

*

*

* @param string $text The text with a placeholder.

* @param mixed $value The value to quote.

* @param string $type OPTIONAL SQL datatype

* @param integer $count OPTIONAL count of placeholders to replace

* @return string An SQL-safe quoted value placed into the original text.

*/

public function quoteInto($text, $value, $type = null, $count = null)

{

if ($count === null) {

return str_replace('?', $this->quote($value, $type), $text);

} else {

while ($count > 0) {

if (strpos($text, '?') !== false) {

$text = substr_replace($text, $this->quote($value, $type), strpos($text, '?'), 1);

}

--$count;

}

return $text;

}

}

/**

* Quotes an identifier.

*

* Accepts a string representing a qualified indentifier. For Example:

*

* $adapter->quoteIdentifier('myschema.mytable')

*

* Returns: "myschema"."mytable"

*

* Or, an array of one or more identifiers that may form a qualified identifier:

*

* $adapter->quoteIdentifier(array('myschema','my.table'))

*

* Returns: "myschema"."my.table"

*

* The actual quote character surrounding the identifiers may vary depending on

* the adapter.

*

* @param string|array|Zend_Db_Expr $ident The identifier.

* @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.

* @return string The quoted identifier.

*/

public function quoteIdentifier($ident, $auto=false)

{

return $this->_quoteIdentifierAs($ident, null, $auto);

}

/**

* Quote a column identifier and alias.

*

* @param string|array|Zend_Db_Expr $ident The identifier or expression.

* @param string $alias An alias for the column.

* @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.

* @return string The quoted identifier and alias.

*/

public function quoteColumnAs($ident, $alias, $auto=false)

{

return $this->_quoteIdentifierAs($ident, $alias, $auto);

}

/**

* Quote a table identifier and alias.

*

* @param string|array|Zend_Db_Expr $ident The identifier or expression.

* @param string $alias An alias for the table.

* @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.

* @return string The quoted identifier and alias.

*/

public function quoteTableAs($ident, $alias = null, $auto = false)

{

return $this->_quoteIdentifierAs($ident, $alias, $auto);

}

/**

* Quote an identifier and an optional alias.

*

* @param string|array|Zend_Db_Expr $ident The identifier or expression.

* @param string $alias An optional alias.

* @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.

* @param string $as The string to add between the identifier/expression and the alias.

* @return string The quoted identifier and alias.

*/

protected function _quoteIdentifierAs($ident, $alias = null, $auto = false, $as = ' AS ')

{

if ($ident instanceof Zend_Db_Expr) {

$quoted = $ident->__toString();

} elseif ($ident instanceof Zend_Db_Select) {

$quoted = '(' . $ident->assemble() . ')';

} else {

if (is_string($ident)) {

$ident = explode('.', $ident);

}

if (is_array($ident)) {

$segments = array();

foreach ($ident as $segment) {

if ($segment instanceof Zend_Db_Expr) {

$segments[] = $segment->__toString();

} else {

$segments[] = $this->_quoteIdentifier($segment, $auto);

}

}

if ($alias !== null && end($ident) == $alias) {

$alias = null;

}

$quoted = implode('.', $segments);

} else {

$quoted = $this->_quoteIdentifier($ident, $auto);

}

}

if ($alias !== null) {

$quoted .= $as . $this->_quoteIdentifier($alias, $auto);

}

return $quoted;

}

/**

* Quote an identifier.

*

* @param string $value The identifier or expression.

* @param boolean $auto If true, heed the AUTO_QUOTE_IDENTIFIERS config option.

* @return string The quoted identifier and alias.

*/

protected function _quoteIdentifier($value, $auto=false)

{

if ($auto === false || $this->_autoQuoteIdentifiers === true) {

$q = $this->getQuoteIdentifierSymbol();

return ($q . str_replace("$q", "$q$q", $value) . $q);

}

return $value;

}

/**

* Returns the symbol the adapter uses for delimited identifiers.

*

* @return string

*/

public function getQuoteIdentifierSymbol()

{

return '"';

}

/**

* Return the most recent value from the specified sequence in the database.

* This is supported only on RDBMS brands that support sequences

* (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.

*

* @param string $sequenceName

* @return string

*/

public function lastSequenceId($sequenceName)

{

return null;

}

/**

* Generate a new value from the specified sequence in the database, and return it.

* This is supported only on RDBMS brands that support sequences

* (e.g. Oracle, PostgreSQL, DB2). Other RDBMS brands return null.

*

* @param string $sequenceName

* @return string

*/

public function nextSequenceId($sequenceName)

{

return null;

}

/**

* Helper method to change the case of the strings used

* when returning result sets in FETCH_ASSOC and FETCH_BOTH

* modes.

*

* This is not intended to be used by application code,

* but the method must be public so the Statement class

* can invoke it.

*

* @param string $key

* @return string

*/

public function foldCase($key)

{

switch ($this->_caseFolding) {

case Zend_Db::CASE_LOWER:

$value = strtolower((string) $key);

break;

case Zend_Db::CASE_UPPER:

$value = strtoupper((string) $key);

break;

case Zend_Db::CASE_NATURAL:

default:

$value = (string) $key;

}

return $value;

}

/**

* called when object is getting serialized

* This disconnects the DB object that cant be serialized

*

* @throws Zend_Db_Adapter_Exception

* @return array

*/

public function __sleep()

{

if ($this->_allowSerialization == false) {

/** @see Zend_Db_Adapter_Exception */

require_once 'Zend/Db/Adapter/Exception.php';

throw new Zend_Db_Adapter_Exception(get_class($this) ." is not allowed to be serialized");

}

$this->_connection = false;

return array_keys(array_diff_key(get_object_vars($this), array('_connection'=>false)));

}

/**

* called when object is getting unserialized

*

* @return void

*/

public function __wakeup()

{

if ($this->_autoReconnectOnUnserialize == true) {

$this->getConnection();

}

}

/**

* Abstract Methods

*/

/**

* Returns a list of the tables in the database.

*

* @return array

*/

abstract public function listTables();

/**

* Returns the column descriptions for a table.

*

* The return value is an associative array keyed by the column name,

* as returned by the RDBMS.

*

* The value of each array element is an associative array

* with the following keys:

*

* SCHEMA_NAME => string; name of database or schema

* TABLE_NAME => string;

* COLUMN_NAME => string; column name

* COLUMN_POSITION => number; ordinal position of column in table

* DATA_TYPE => string; SQL datatype name of column

* DEFAULT => string; default expression of column, null if none

* NULLABLE => boolean; true if column can have nulls

* LENGTH => number; length of CHAR/VARCHAR

* SCALE => number; scale of NUMERIC/DECIMAL

* PRECISION => number; precision of NUMERIC/DECIMAL

* UNSIGNED => boolean; unsigned property of an integer type

* PRIMARY => boolean; true if column is part of the primary key

* PRIMARY_POSITION => integer; position of column in primary key

*

* @param string $tableName

* @param string $schemaName OPTIONAL

* @return array

*/

abstract public function describeTable($tableName, $schemaName = null);

/**

* Creates a connection to the database.

*

* @return void

*/

abstract protected function _connect();

/**

* Test if a connection is active

*

* @return boolean

*/

abstract public function isConnected();

/**

* Force the connection to close.

*

* @return void

*/

abstract public function closeConnection();

/**

* Prepare a statement and return a PDOStatement-like object.

*

* @param string|Zend_Db_Select $sql SQL query

* @return Zend_Db_Statement|PDOStatement

*/

abstract public function prepare($sql);

/**

* Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.

*

* As a convention, on RDBMS brands that support sequences

* (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence

* from the arguments and returns the last id generated by that sequence.

* On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method

* returns the last value generated for such a column, and the table name

* argument is disregarded.

*

* @param string $tableName OPTIONAL Name of table.

* @param string $primaryKey OPTIONAL Name of primary key column.

* @return string

*/

abstract public function lastInsertId($tableName = null, $primaryKey = null);

/**

* Begin a transaction.

*/

abstract protected function _beginTransaction();

/**

* Commit a transaction.

*/

abstract protected function _commit();

/**

* Roll-back a transaction.

*/

abstract protected function _rollBack();

/**

* Set the fetch mode.

*

* @param integer $mode

* @return void

* @throws Zend_Db_Adapter_Exception

*/

abstract public function setFetchMode($mode);

/**

* Adds an adapter-specific LIMIT clause to the SELECT statement.

*

* @param mixed $sql

* @param integer $count

* @param integer $offset

* @return string

*/

abstract public function limit($sql, $count, $offset = 0);

/**

* Check if the adapter supports real SQL parameters.

*

* @param string $type 'positional' or 'named'

* @return bool

*/

abstract public function supportsParameters($type);

/**

* Retrieve server version in PHP style

*

* @return string

*/

abstract public function getServerVersion();

}

到此,我已经晕了。你呢???

哈哈哈。。。

下面看一些简单的案例

插入数据到数据库:<?php

require_once 'Zend/Db.php';

$params = array('host'=>'127.0.0.1',

'username'=>'root',

'password'=>'',

'dbname'=>'test'

);

$db = Zend_Db::factory('PDO_Mysql',$params);

$row = array(

'username'=>'Jiqing',

'password'=>'jiqing90061234'

);

$table = 'user';

$res = $db->insert($table,$row);

if($res){

echo "成功插入新的记录!";

echo "

";

$last_insert_id = $db->lastInsertId($table);

echo "新记录的ID值为:";

echo $last_insert_id;

echo "

";

echo "其内容为:";

$sql = "select * from $table where id=$last_insert_id";

$result = $db->fetchRow($sql);

echo "

";

foreach($result as $key=>$val){

echo $key;

echo "值为:";

echo $val;

echo "

";

}

}else{

echo "插入数据有误";

}

结果为:成功插入新的记录!

新记录的ID值为:13

其内容为:

id值为:13

username值为:Jiqing

password值为:jiqing90061234

修改update方法

删除delete方法

都大同小异,首先连接数据库,然后填写相应参数,执行即可。

查询方法总结:

fetchAll()匹配查询结果,返回一个连续的数组。

fetchAssoc()匹配查询结果,返回一个联合的数组。

fetchCol()匹配结果的第一列,返回一个数组。

fetchOne()陪陪查询结果的第一列与第一行的值,返回一个字符串。

fetchRow()匹配查询结果的第一行,返回一个数组。

常用的是第一个和最后一个方法,其他的方法用的不是很多。

希望本文所述对大家基于Zend Framework框架的PHP程序设计有所帮助。

更多Zend Framework入门教程之Zend_Db数据库操作详解相关文章请关注PHP中文网!

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值