<?php
/**
* PDO4You is a class that implements the Singleton design pattern for connecting the database using the PDO extension (PHP Data Objects)
*
* @author Giovanni Ramos <giovannilauro@gmail.com>
* @copyright 2010-2013, Giovanni Ramos
* @since 2010-09-07
* @license http://opensource.org/licenses/MIT
* @link http://github.com/giovanniramos/PDO4YOU
* @package PDO4YOU
* @category PDO
* @version 3.1
*
* */
class PDO4You extends PDO4You_pagination
{
/**
* Stores the name of the server machine on which the database resides
*
* @access private static
* @var string
*
* */
private static $datahost;
/**
* Stores the name of the port on which the server is running
*
* @access private static
* @var string
*
* */
private static $dataport;
/**
* Stores the name of the current instance of the connection
*
* @access private static
* @var string
*
* */
private static $connection;
/**
* Stores an object instance PDO connection
*
* @access private static
* @var object
*
* */
private static $instance;
/**
* Stores object instances PDO connection
*
* @access private static
* @var array
*
* */
private static $handle = array();
/**
* Stores the definition of persistent connection
*
* @access private static
* @var boolean
*
* */
private static $persistent = false;
/**
* Stores the ID of the last inserted row or sequence value
*
* @access private
* @var string
*
* */
private static $lastId;
/**
* Stores the total of affected rows in last CRUD operation
*
* @access private
* @var string
*
* */
private static $rowCount;
/**
* Stores messages Exception thrown
*
* @access private
* @var array
*
* */
private static $exception = array(
'code-1044' => 'Access denied for user: \'%1$s\'',
'code-1045' => 'Failed communication with the database using: \'%1$s\'@\'%2$s\'',
'code-2002' => 'No connection could be made because the destination machine actively refused. This host is not known.',
'code-2005' => 'No communication with the host provided. Check your settings.',
'unrecognized' => 'The Adapter/DSN Instance was not recognized.',
'no-database' => 'Database unknown. Check your settings.',
'no-instance' => 'No instance of object PDO4You available. Unable to access the methods.',
'no-argument-sql' => 'The SQL argument is missing.',
'no-instruction-json' => 'The SQL statement is missing in JSON format.',
'not-implemented' => 'Method not implemented.',
'critical-error' => 'Critical error detected in the system.',
'json-error-depth' => 'Maximum stack depth exceeded.',
'json-error-state-mismatch' => 'Mismatch or arithmetic operation modes impossible to be represented.',
'json-error-ctrl-char' => 'Attribute control unexpected was found.',
'json-error-syntax' => 'The query is poorly formatted JSON provided.'
);
/**
* The constructor is set to private, preventing direct instance of the class
*
* @access private
*
* */
private function PDO4You()
{
}
/**
* Method Singleton connection
*
* @access private static
* @param string $alias Pseudonym of a connection instance
* @param string $driver Driver DSN connection
* @param string $user Username of the database
* @param string $pass Password of the database
* @param string $option Configuration the connection driver
* @return void
* @throws PDOException Throws an exception in case of connection failures
*
* */
private static function singleton($alias, $driver, $user, $pass, $option)
{
try {
try {
$instance = @ new PDO($driver, $user, $pass, $option);
$instance->setAttribute(PDO::ATTR_ERRMODE, ($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] == '::1') ? PDO::ERRMODE_EXCEPTION : PDO::ERRMODE_SILENT);
self::setHandle($alias, $instance);
self::setInstance($alias);
} catch (PDOException $e) {
$error = self::getErrorInfo($e);
if ($e->getMessage() == 'could not find driver' || $e->getMessage() == 'invalid data source name') {
throw new PDOException(self::$exception['unrecognized']);
} elseif ($error['code'] == '2005') {
throw new PDOException(self::$exception['code-2005']);
} elseif ($error['code'] == '2002') {
throw new PDOException(self::$exception['code-2002']);
} elseif ($error['code'] == '1044') {
throw new PDOException(sprintf(self::$exception['code-1044'], $user));
} elseif ($error['code'] == '1045') {
throw new PDOException(sprintf(self::$exception['code-1045'], $user, $pass));
} else {
throw $e;
}
}
} catch (PDOException $e) {
self::stackTrace($e);
}
}
/**
* Method for setting a connection instance
*
* @access public static
* @param string $alias Pseudonym of a connection instance
* @return void
*
* */
public static function setInstance($alias)
{
self::$instance = self::getHandle($alias == null ? 'standard' : $alias);
}
/**
* Method to get a single instance of the database per connection
*
* @access public static
* @param string $alias Pseudonym that will be used as a pointer to an instance of established connection
* @param string $type Connection type if using "Initial Setup" or "Full DSN"
* @param string $user Username of the database
* @param string $pass Password of the database
* @param string $option Configuration the connection driver
* @return object
* @throws Exception Throws an exception in case of connection failures
*
* */
public static function getInstance($alias = 'standard', $type = null, $user = null, $pass = null, Array $option = null)
{
try {
try {
if (!array_key_exists($alias, self::$handle)) {
if ($alias == 'standard') {
$dir = dirname(__FILE__);
$file = $dir . '/PDO4You.settings.ini';
if (file_exists($file)) {
if (is_readable($file)) {
$datafile = parse_ini_file_advanced($file);
if (isset($datafile['adapter'])) {
if (PDO4YOU_ADAPTER == 'vcap') {
$json = json_decode(getenv("VCAP_SERVICES"), true);
$data = $datafile['adapter']['vcap'];
$part = preg_split('~[|]~', $data['vcap']);
$conf = $json[$part[0]][$part[1]]['credentials'];
$type = isset($data['type']) ? $data['type'] : null;
$host = isset($conf['hostname']) ? $conf['hostname'] : null;
$port = isset($conf['port']) ? $conf['port'] : null;
$user = isset($conf['username']) ? $conf['username'] : null;
$pass = isset($conf['password']) ? $conf['password'] : null;
$base = isset($conf['name']) ? $conf['name'] : null;
} else {
$part = preg_split('~[.]~', preg_replace('~[\s]{1,}~', null, PDO4YOU_ADAPTER));
$conf = count($part) == 2 ? @$datafile['adapter'][$part[0]][$part[1]] : @$datafile['adapter'][$part[0]];
$type = isset($conf['type']) ? $conf['type'] : null;
$host = isset($conf['host']) ? $conf['host'] : null;
$port = isset($conf['port']) ? $conf['port'] : null;
$user = isset($conf['user']) ? $conf['user'] : null;
$pass = isset($conf['pass']) ? $conf['pass'] : null;
$base = isset($conf['base']) ? $conf['base'] : null;
}
} else {
exit('The settings for existing databases, were not configured in the <strong>PDO4You.settings.ini</strong>.');
}
} else {
exit('The <strong>PDO4You.settings.ini</strong> file cannot be read.');
}
} else {
exit('The <strong>PDO4You.settings.ini</strong> file could not be found in directory:<br /> ' . $dir);
}
}
$type = strtolower($type);
switch ($type) {
case 'maria': $driver = 'mysql:' . (!(empty($base)) ? 'dbname=' . $base . ';' : null) . 'host=' . $host . ';port=' . $port . ';';
break;
case 'mysql':
case 'pgsql':
case 'cubrid': $driver = $type . ':' . (!(empty($base)) ? 'dbname=' . $base . ';' : null) . 'host=' . $host . ';port=' . $port . ';';
break;
case 'mssql':
case 'dblib':
case 'sybase': $driver = $type . ':' . (!(empty($base)) ? 'dbname=' . $base . ';' : null) . 'host=' . $host . ';';
break;
case 'sqlsrv': $driver = 'sqlsrv:' . (!(empty($base)) ? 'database=' . $base . ';' : null) . 'server=' . $host . ';';
break;
case 'oracle': $driver = 'oci:' . (!(empty($base)) ? 'dbname=' . $base : null);
break;
case 'sqlite': $driver = 'sqlite:' . (!(empty($base)) ? $base : null);
break;
default: $driver = $type;
}
$option = !is_null($option) ? $option : array(PDO::ATTR_PERSISTENT => self::$persistent, PDO::ATTR_CASE => PDO::CASE_LOWER);
self::singleton($alias, $driver, $user, $pass, $option);
}
} catch (PDOException $e) {
$error = self::getErrorInfo($e);
if ($error['state'] == '42000') {
throw new PDOException(self::$exception['no-database']);
} else {
throw $e;
}
}
} catch (PDOException $e) {
self::stackTrace($e);
}
return self::$instance;
}
/**
* Method for assigning a new object instance PDO connection
*
* @param string $alias Pseudonym to identify the connection instance
* @param PDO $instance Object PDO connection
* @return void
*
*/
private static function setHandle($alias, PDO $instance)
{
self::$handle[$alias] = $instance;
}
/**
* Method to return an object PDO connection
*
* @param string $alias Pseudonym of a connection instance
* @return object
*
*/
private static function getHandle($alias)
{
self::setConnection($alias);
return self::$handle[$alias];
}
/**
* Method to set the server name
*
* @access private static
* @param string $host Server name
* @return void
*
* */
private static function setDatahost($host)
{
self::$datahost = $host;
}
/**
* Method to retrieve the server name
*
* @access public static
* @param void
* @return string
*
* */
public static function getDatahost()
{
return self::$datahost;
}
/**
* Method to set the port number of the server
*
* @access private static
* @param string $port Port number
* @return void
*
* */
private static function setDataport($port)
{
self::$dataport = $port;
}
/**
* Method to retrieve the port number of the server
*
* @access public static
* @param void
* @return string
*
* */
public static function getDataport()
{
return self::$dataport;
}
/**
* Method to define which the current instance of connection
*
* @access private static
* @param string $alias Pseudonym of a connection instance
* @return void
*
* */
private static function setConnection($alias)
{
self::$connection = $alias;
}
/**
* Method to retrieve the name of the current instance of connection
*
* @access public static
* @param void
* @return string
*
* */
public static function getConnection()
{
return self::$connection;
}
/**
* Method for defining the type of communication with the database
* The default connection is not persistent
*
* @access public static
* @param boolean $persistent Sets a persistent connection
* @return void
*
* */
public static function setPersistent($persistent = false)
{
self::$persistent = $persistent;
}
/**
* Method to capture the error information of an Exception
*
* @access public static
* @param Exception $e Gets the message from the exception thrown
* @param boolean $debug Enables the display of the captured values
* @return array
*
* */
public static function getErrorInfo(Exception $e, $debug = false)
{
if (defined(PDO4YOU_WEBMASTER)) {
self::fireAlert(self::$exception['critical-error'], $e);
}
$info = null;
$errorInfo = null;
$message = $e->getMessage();
preg_match('~SQLSTATE[[]([[:alnum:]]{1,})[]]:?\s[[]?([[:digit:]]{1,})?[]]?\s?(.+)~', $message, $errorInfo);
$info['state'] = isset($errorInfo[1]) ? $errorInfo[1] : null;
$info['code'] = isset($errorInfo[2]) ? $errorInfo[2] : null;
$info['message'] = isset($errorInfo[3]) ? $errorInfo[3] : null;
if ($debug) {
echo '<pre>', print_r($info), '</pre>';
}
return $info;
}
/**
* Method to retrieve the name of the current driver
*
* @access public static
* @param void
* @return string
*
* */
public static function getDriver()
{
return self::$instance->getAttribute(PDO::ATTR_DRIVER_NAME);
}
/**
* Method to display details about the target server's database connected
*
* @access public static
* @param void
* @return void
*
* */
public static function getServerInfo()
{
try {
if (self::$instance instanceof PDO) {
self::setStyle();
$driver = self::getDriver();
$info = ($driver == 'sqlite' || $driver == 'mssql') ? 'not available' : self::$instance->getAttribute(PDO::ATTR_SERVER_INFO);
echo '<h7>Server Information - ', is_array($info) ? implode(', ', $info) : $info, '</h7>';
} else {
throw new PDOException(self::$exception['no-instance']);
}
} catch (PDOException $e) {
self::stackTrace($e);
}
}
/**
* Method to display the PDO drivers installed and supported by the server
*
* @access public static
* @param void
* @return void
*
* */
public static function getAvailableDrivers()
{
try {
if (self::$instance instanceof PDO) {
self::setStyle();
$info = self::$instance->getAvailableDrivers();
echo '<h7>Available Drivers: ', implode(', ', $info), '</h7>';
} else {
throw new PDOException(self::$exception['no-instance']);
}
} catch (PDOException $e) {
self::stackTrace($e);
}
}
/**
* PDO4You Style
*
* @access public static
* @param void
* @return void
*
* */
public static function setStyle()
{
$style = '<style type="text/css">';
$style.= 'body,.code { background:#FAFAFA; font:normal 12px/1.7em Bitstream Vera Sans Mono,Courier New,Monospace; margin:0; padding:0; }';
$style.= '#pdo4you h2 { display:block; color:#000; background:#FFF; font-size:20px; margin:0; padding:10px; border-bottom:solid 1px #999; }';
$style.= '#pdo4you h7 { display:block; color:#FFF; background:#000; font-size:12px; margin:0; padding:2px 5px; }';
$style.= '.pdo4you { margin:8px; padding:0; }';
$style.= '.code { font:inherit; background:#EFEFEF; border:solid 1px #DDD; border-right-color:#BBB; border-bottom:none; margin:10px 10px 0 10px; overflow:auto; }';
$style.= '.trace,.debug { background:#FFF; border:solid 1px #BBB; border-left-color:#DDD; border-top:none; margin:0 10px 15px 10px; }';
$style.= '.trace div { clear:both; }';
$style.= '.debug { padding:5px; }';
$style.= '.title { padding-left:6px; font-weight:bold; }';
$style.= '.title span { font-weight:normal; }';
$style.= '.number { color:#AAA; background:#EFEFEF; min-width:40px; padding:0 5px; margin-right:5px; float:left; text-align:right; cursor:default; }';
$style.= '.highlight { background:#FFC; }';
$style.= '</style>';
print $style;
}
}
preferences:
36.98 ms | 402 KiB | 5 Q