📄 common.php
字号:
<?php
//
// +----------------------------------------------------------------------+
// | PHP version 4.0 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2001 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Stig Bakken <ssb@fast.no> |
// | |
// +----------------------------------------------------------------------+
//
// $Id: common.php,v 1.59.2.3 2001/11/13 01:26:42 ssb Exp $
//
// Base class for DB implementations.
//
/**
* DB_common is a base class for DB implementations, and must be
* inherited by all such.
*/
class DB_common extends PEAR
{
// {{{ properties
var $features; // assoc of capabilities for this DB implementation
var $errorcode_map; // assoc mapping native error codes to DB ones
var $type; // DB type (mysql, oci8, odbc etc.)
var $prepare_tokens;
var $prepare_types;
var $prepared_queries;
var $prepare_maxstmt = 0;
var $last_query = '';
var $fetchmode = DB_FETCHMODE_ORDERED;
var $fetchmode_object_class = 'stdClass';
var $limit_from = null; // for limit queries, the row to start fetching
var $limit_count = null; // for limit queries, the number of rows to fetch
var $options = array(
'persistent' => false, // persistent connection?
'optimize' => 'performance', // 'performance' or 'portability'
'debug' => 0 // numeric debug level
);
/*
var $features['limit'] => 'emulate' // 'emulate' => emulate with fetch row by number
// 'alter' => alter the query
// false => no support for limit queries
*/
var $dbh;
// }}}
// {{{ toString()
function toString()
{
$info = get_class($this);
$info .= ": (phptype=" . $this->phptype .
", dbsyntax=" . $this->dbsyntax .
")";
if ($this->connection) {
$info .= " [connected]";
}
return $info;
}
// }}}
// {{{ constructor
function DB_common()
{
$this->PEAR('DB_Error');
$this->features = array();
$this->errorcode_map = array();
$this->fetchmode = DB_FETCHMODE_ORDERED;
}
// }}}
// {{{ quoteString()
/**
* Quotes a string so it can be safely used within string delimiters
* in a query (preserved for compatibility issues, quote() is preffered).
*
* @see quote()
*/
function quoteString($string)
{
$string = $this->quote($string);
if ($string{0} == "'") {
return substr($string, 1, -1);
}
return $string;
}
/**
* Quotes a string so it can be safely used in a query. It will return
* the string with single quotes around. Other backend quote styles
* should override this method.
*
* @param $string the input string to quote
*
* @return string The NULL string or the string quotes
* in magic_quote_sybase style
*/
function quote($string)
{
return ($string === null) ? 'NULL' : "'".str_replace("'", "''", $string)."'";
}
// }}}
// {{{ provides()
/**
* Tell whether a DB implementation or its backend extension
* supports a given feature.
*
* @param $feature name of the feature (see the DB class doc)
*
* @return bool whether this DB implementation supports $feature
*/
function provides($feature)
{
return $this->features[$feature];
}
// }}}
// {{{ errorCode()
/**
* Map native error codes to DB's portable ones. Requires that
* the DB implementation's constructor fills in the $errorcode_map
* property.
*
* @param $nativecode the native error code, as returned by the backend
* database extension (string or integer)
*
* @return int a portable DB error code, or FALSE if this DB
* implementation has no mapping for the given error code.
*/
function errorCode($nativecode)
{
if (isset($this->errorcode_map[$nativecode])) {
return $this->errorcode_map[$nativecode];
}
//php_error(E_WARNING, get_class($this)."::errorCode: no mapping for $nativecode");
// Fall back to DB_ERROR if there was no mapping.
return DB_ERROR;
}
// }}}
// {{{ errorMessage()
/**
* Map a DB error code to a textual message. This is actually
* just a wrapper for DB::errorMessage().
*
* @param $dbcode the DB error code
*
* @return string the corresponding error message, of FALSE
* if the error code was unknown
*/
function errorMessage($dbcode)
{
return DB::errorMessage($this->errorcode_map[$dbcode]);
}
// }}}
// {{{ raiseError()
/**
* This method is used to communicate an error and invoke error
* callbacks etc. Basically a wrapper for PEAR::raiseError
* without the message string.
*
* @param mixed integer error code, or a PEAR error object (all
* other parameters are ignored if this parameter is
* an object
*
* @param int error mode, see PEAR_Error docs
*
* @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the
* error level (E_USER_NOTICE etc). If error mode is
* PEAR_ERROR_CALLBACK, this is the callback function,
* either as a function name, or as an array of an
* object and method name. For other error modes this
* parameter is ignored.
*
* @param string Extra debug information. Defaults to the last
* query and native error code.
*
* @param mixed Native error code, integer or string depending the
* backend.
*
* @return object a PEAR error object
*
* @see PEAR_Error
*/
function &raiseError($code = DB_ERROR, $mode = null, $options = null,
$userinfo = null, $nativecode = null)
{
// The error is yet a DB error object
if (is_object($code)) {
return PEAR::raiseError($code, null, null, null, null, null, true);
}
if ($userinfo === null) {
$userinfo = $this->last_query;
}
if ($nativecode) {
$userinfo .= " [nativecode=$nativecode]";
}
return PEAR::raiseError(null, $code, $mode, $options, $userinfo,
'DB_Error', true);
}
// }}}
// {{{ setFetchMode()
/**
* Sets which fetch mode should be used by default on queries
* on this connection.
*
* @param $fetchmode int DB_FETCHMODE_ORDERED or
* DB_FETCHMODE_ASSOC, possibly bit-wise OR'ed with
* DB_FETCHMODE_FLIPPED.
*
* @param $object_class string optional The class of the object
* to be returned by the fetch methods when
* the DB_FETCHMODE_OBJECT mode is selected.
* If no class is specified by default a cast
* to object from the assoc array row will be done.
* There is also the posibility to use and extend the
* 'DB_Row' class.
*
* @see DB_FETCHMODE_ORDERED
* @see DB_FETCHMODE_ASSOC
* @see DB_FETCHMODE_FLIPPED
* @see DB_FETCHMODE_OBJECT
* @see DB_Row::DB_Row()
*/
function setFetchMode($fetchmode, $object_class = null)
{
switch ($fetchmode) {
case DB_FETCHMODE_OBJECT:
if ($object_class) {
$this->fetchmode_object_class = $object_class;
}
case DB_FETCHMODE_ORDERED:
case DB_FETCHMODE_ASSOC:
$this->fetchmode = $fetchmode;
break;
default:
return $this->raiseError('invalid fetchmode mode');
}
}
// }}}
// {{{ setOption()
function setOption($option, $value)
{
if (isset($this->options[$option])) {
$this->options[$option] = $value;
return DB_OK;
}
return $this->raiseError("unknown option $option");
}
// }}}
// {{{ getOption()
function getOption($option)
{
if (isset($this->options[$option])) {
return $this->options[$option];
}
return $this->raiseError("unknown option $option");
}
// }}}
// {{{ prepare()
/**
* Prepares a query for multiple execution with execute(). With
* some database backends, this is emulated.
*/
function prepare($query)
{
$tokens = split("[\&\?\!]", $query);
$token = 0;
$types = array();
for ($i = 0; $i < strlen($query); $i++) {
switch ($query[$i]) {
case '?':
$types[$token++] = DB_PARAM_SCALAR;
break;
case '&':
$types[$token++] = DB_PARAM_OPAQUE;
break;
case '!':
$types[$token++] = DB_PARAM_MISC;
break;
}
}
$this->prepare_tokens[] = &$tokens;
end($this->prepare_tokens);
$k = key($this->prepare_tokens);
$this->prepare_types[$k] = $types;
$this->prepared_queries[$k] = &$query;
return $k;
}
// }}}
// {{{ execute()
function execute($stmt, $data = false)
{
$realquery = $this->executeEmulateQuery($stmt, $data);
if (DB::isError($realquery)) {
return $realquery;
}
$result = $this->simpleQuery($realquery);
if (DB::isError($result) || $result === DB_OK) {
return $result;
} else {
return new DB_result($this, $result);
}
}
// }}}
// {{{ executeEmulateQuery()
/**
* @return a string containing the real query run when emulating
* prepare/execute. A DB error code is returned on failure.
*/
function executeEmulateQuery($stmt, $data = false)
{
$p = &$this->prepare_tokens;
if (!isset($this->prepare_tokens[$stmt]) ||
!is_array($this->prepare_tokens[$stmt]) ||
!sizeof($this->prepare_tokens[$stmt]))
{
return $this->raiseError(DB_ERROR_INVALID);
}
$qq = &$this->prepare_tokens[$stmt];
$qp = sizeof($qq) - 1;
if ((!$data && $qp > 0) ||
(!is_array($data) && $qp > 1) ||
(is_array($data) && $qp > sizeof($data)))
{
$this->last_query = $this->prepared_queries[$stmt];
return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
}
$realquery = $qq[0];
for ($i = 0; $i < $qp; $i++) {
$type = $this->prepare_types[$stmt][$i];
if ($type == DB_PARAM_OPAQUE) {
if (is_array($data)) {
$fp = fopen($data[$i], 'r');
} else {
$fp = fopen($data, 'r');
}
$pdata = '';
if ($fp) {
while (($buf = fread($fp, 4096)) != false) {
$pdata .= $buf;
}
}
} else {
if (is_array($data)) {
$pdata = &$data[$i];
} else {
$pdata = &$data;
}
}
$realquery .= ($type != DB_PARAM_MISC) ? $this->quote($pdata) : $pdata;
$realquery .= $qq[$i + 1];
}
return $realquery;
}
// }}}
// {{{ executeMultiple()
/**
* This function does several execute() calls on the same
* statement handle. $data must be an array indexed numerically
* from 0, one execute call is done for every "row" in the array.
*
* If an error occurs during execute(), executeMultiple() does not
* execute the unfinished rows, but rather returns that error.
*/
function executeMultiple( $stmt, &$data )
{
for($i = 0; $i < sizeof( $data ); $i++) {
$res = $this->execute($stmt, $data[$i]);
if (DB::isError($res)) {
return $res;
}
}
return DB_OK;
}
// }}}
// {{{ modifyQuery()
/**
* This method is used by backends to alter queries for various
* reasons. It is defined here to assure that all implementations
* have this method defined.
*
* @access private
*
* @param query to modify
*
* @return the new (modified) query
*/
function modifyQuery($query) {
return $query;
}
// }}}
// {{{ modifyLimitQuery()
function modifyLimitQuery($query, $from, $count)
{
return $query;
}
// }}}
// {{{ query()
/**
* Send a query to the database and return any results with a
* DB_result object.
*
* @access public
*
* @param the SQL query
*
* @return object a DB_result object or DB_OK on success, a DB
* error on failure
*
* @see DB::isError
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -