New issues in PDO Class - php

I have a code which connect my DB class.
<?php
require('DB.php');
$pdo = new PDO(
'mysql:dbname=MYDB;host=localhost',
'MYUSER',
'MYPASS',
array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
)
);
DB::$c = $pdo;
?>
MY DB.php is here http://pastebin.com/VjNNVbCm
This code was working fine till last day. Now i see a error message. See the log
PHP Fatal error: Access to undeclared static property: DB::$c in /home/domain/ .... /inc/config.php on line 13

The issues is solved by upgrading PHP in to 5.5 .

Related

DBAL connect immediately

In PDO (And likewise DBAL) if there's a problem authenticating with the server it will throw an exception containing a trace including the database username and password.
Needless to say, this is a problem, and in PDO I would wrap it in a try block and re-throw the error without the stack trace. Problem solved.
However, DBAL doesn't actually initiate the connection until the first query is called, so it misses the try block completely and spews my database credentials the first chance it gets!
How can I force DBAL to connect immediately so I can catch any authentication errors?
\Doctrine\DBAL\Connection::connect()
Obvious in retrospect.
My database is ibm db2 so I use the odbc pdo connection with dbal. This is how I set up my connection, notice that the PDO is in a try catch block
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
$connPdo = null;
try {
$connPdo = new PDO('odbc:'.SYSTEM_DSN_NAME, DB_USERNAME, DB_PASSWORD, array(
PDO::ATTR_PERSISTENT => TRUE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
);
} catch (PDOException $e) {
echo $e->getMessage() . '</br>';
}
$config = new Configuration();
$connectionParams = array(
'user' => DB_USERNAME,
'password' => DB_PASSWORD,
'pdo' => $connPdo,
'driverClass' =>'Doctrine\DBAL\Driver\PDOIbm\Driver',
);
$connection = DriverManager::getConnection($connectionParams, $config);
$queryBuilder = $connection->createQueryBuilder();

PDO with extended PDOStatement cannot disconnect the connection when set NULL

Tested in PHP 5.5.22 and 5.5.25
When using PDO that has extended PDOStatement, MySQL keep connection until when PHP script are finished.
use PDO;
$dbinfoCode = array(
'userid' => 'userid',
'password' => 'password',
'engine' => 'mysql',
'host' => '192.168.100.2',
'database' => 'test',
);
for ($i = 0; $i < 10000; $i++) {
$dsn = sprintf("%s:host=%s;dbname=%s", $dbinfo['engine'], $dbinfo['host'], $dbinfo['database']);
$pdo = new PDO($dsn, $dbinfo['userid'], $dbinfo['password'], $options);
$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array($pdo)));
$pdo = null;
}
class PDOStatement2 extends PDOStatement {
}
I can see increasingly stacked "Sleep" processes on MySQL query. Finally, MySQL throw error "Too many connections".
SHOW PROCESSLIST;
If there is no setAttribute about PDO::ATTR_STATEMENT_CLASS, The MySQL connection is disconnected in working order.
$pdo = new PDO($dsn, $dbinfo['userid'], $dbinfo['password'], $options);
//$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array($pdo)));
$pdo = null;
I have no idea about it wheather is this a bug or has another solutions.
Finally, I found the solution.
$pdo object on following statement will be duplicated
$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array($pdo)));
Use &$pdo instead of $pdo.
$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array(&$pdo)));

Setting connection charset in Doctrine DBAL with comparison to PHP PDO

Are there any needs for using set names ourcharset with DBAL with PHP >=5.3.2 and <5.3.6?
Prior to PHP 5.3.6, the charset option in PDO connection was ignored.
If we were running an older version of PHP, we had to use set names ourcharset.
Actual Doctrine DBAL 2.5.1 require PHP >=5.3.2.
I can't find what Doctrine team is advising if someone have PHP <5.3.6 version.
DBAL is mostly based on PDO, but it also have some improvements over it, so I was thinking maybe this was improved... but at Doctrine DBAL documentation page I have found only this:
Up until PHP 5.3.6 PDO has a security problem when using non ascii
compatible charsets. Even if specifying the charset using “SET NAMES”,
emulated prepared statements and PDO#quote could not reliably escape
values, opening up to potential SQL injections. If you are running PHP
5.3.6 you can solve this issue by passing the driver option “charset” to Doctrine PDO MySQL driver. Using SET NAMES does not suffice!
In PDO to this time I have done:
<?php
$dsn = 'mysql:host='.$_SESSION['options']['host'].';port='.$_SESSION['options']['port'].';dbname='.$_SESSION['options']['dbname'].';charset='.$_SESSION['options']['charset'];
try {
$conn = new \PDO($dsn, $_SESSION['options']['user'], $_SESSION['options']['pass']);
if(version_compare(PHP_VERSION, '5.3.6', '<')) //is this required with DBAL?
$conn->exec("set names {$_SESSION['options']['charset']}");
} catch (\PDOException $e) {
trigger_error($e->getMessage(), E_USER_ERROR);
}
?>
With DBAL it's:
<?php
require_once "lib/autoload.php";
$config = new \Doctrine\DBAL\Configuration();
$params = array(
'dbname' => $_SESSION['options']['dbname'],
'user' => $_SESSION['options']['user'],
'password' => $_SESSION['options']['pass'],
'host' => $_SESSION['options']['host'],
'port' => $_SESSION['options']['port'],
'driver' => 'pdo_mysql',
'charset' => $_SESSION['options']['charset'],
);
try {
$conn = \Doctrine\DBAL\DriverManager::getConnection($params, $config);
} catch (\Exception $e) {
trigger_error($e->getMessage(), E_USER_ERROR);
}
?>
It looks that DBAL do not improved here anything.
So, if there is possibility that our app will used with PHP between >=5.3.2 and <5.3.6, then yes, use additional SET NAMES:
<?php
require_once "lib/autoload.php";
$config = new \Doctrine\DBAL\Configuration();
$params = array(
'dbname' => $_SESSION['options']['dbname'],
'user' => $_SESSION['options']['user'],
'password' => $_SESSION['options']['pass'],
'host' => $_SESSION['options']['host'],
'port' => $_SESSION['options']['port'],
'driver' => 'pdo_mysql',
'charset' => $_SESSION['options']['charset'],
);
if(version_compare(PHP_VERSION, '5.3.6', '<'))
$params['driverOptions'] = array(1002=>'SET NAMES '.$_SESSION['options']['charset']);
//"1002" is value of constant MYSQL_ATTR_INIT_COMMAND
try {
$conn = \Doctrine\DBAL\DriverManager::getConnection($params, $config);
} catch (\Exception $e) {
trigger_error($e->getMessage(), E_USER_ERROR);
}
?>

PDO Connection not showing all errors

I'm having trouble getting errors to display with when making a new PDO connection. It only shows an error if I put the incorrect password in my config file. It won't show errors for an incorrect database name, username, or host.
<?php
// config file
return [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'query_test',
'username' => 'root',
'password' => '',
'options' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_CLASS,
PDO::ATTR_EMULATE_PREPARES => false
]
];
// connector file
use PDO;
class MySqlConnector implements ConnectorInterface
{
public function connect(array $config)
{
extract($config);
$dsn = "mysql:{$host};dbname={$database}";
$connection = new PDO($dsn, $username, $password, $options);
return $connection;
}
}
I've tried using try/catch blocks as well as setting ini display errors and error reporting E_ALL. Can't seem to figure this out.
Change:
$connection = new PDO($dsn, $username, $password, $options);
return $connection;
to:
try {
$connection = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
return $connection;
I overlooked a simple mistake. I had "mysql:{$host}" instead of "mysql:host={$host}".
Sorry for the silly mistake but thank you for your answer!

PHP pdo exception "could not find driver" pgsql

So i always get a pdo exception when i try to create my db in the constructor of my Mapper class.
on this line:
$this->db = new PDO($dsn, $db_config['username'], $db_config['password']);
this is my dsn creation:
$db_config = array(
'driver' => 'pgsql',
'username' => $dbUser,
'password' => $dbPassword,
'schema' => 'r0628740',
'dsn' => array(
'host' => 'gegevensbanken.khleuven.be',
'dbname' => '2TX31',
'port' => '51314',
)
);
and finaly my constructor:
public function __construct(){
global $db_config;
$dsn = $db_config['driver'] . ':';
foreach($db_config['dsn'] as $key => $value){
$dsn .= $key . '=' . $value . ';';
}
try{
$this->db = new PDO($dsn, $db_config['username'], $db_config['password']);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if(($db_config['driver'] == 'pgsql') && isset($db_config['schema'])){
$this->db->query(sprintf("SET SEARCH_PATH TO %s"), $db_config['schema']);
}
}catch (PDOException $e){
var_dump($e->getLine());
error_log($e->getMessage());
}
}
The PHP contains a dll required by pgsql and pgsql_pdo driver libpq.dll...
Add PHP binary path to system path or copy de DLL into Windows\system32. On linux dependency are installed automatically.
I found article somewhere, works for me. Assuming you have installed PostgreSQL and your WAMP installation is on c:\wamp, you will need to copy:
c:\wamp\bin\php\php5.3.9\libpq.dll to c:\wamp\bin\apache\Apache2.2.11\bin.
Make sure you also have the following files:
C:\wamp\bin\php\php5.3.9\ext\php_pdo_pgsql.dll and
C:\wamp\bin\php\php5.3.9\ext\php_pgsql.dll
Also, make sure you have enabled the above 2 files as extensions, either via the WAMP menu (click on WAMP icon on taskbar: PHP > PHP extensions, find the above 2 and 'check' them).
Please note that php5.3.9 and Apache2.2.11 refer to my specific PHP and Apache versions.
Adjust those to suit your installation.
Copying this libpq.dll from c:\wamp\bin\php\php5.3.9\libpq.dll to c:\wamp\bin\apache\Apache2.2.11\bin. has worked for me

Categories