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!
Related
This is my code
<?php
class Connection
{
function __construct()
{
if(isset($_SERVER['SERVER_NAME']))
{
switch($_SERVER['SERVER_NAME'])
{
case 'www.hashstar.com':
$this->default = $this->dev;
break;
case 'www.hashstar.in':
$this->default = $this->prod;
break;
}
}
else
{
$this->default = $this->dev;
}
}
public $dev = array(
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'dbname',
);
public $prod = array(
'host' => 'localhost',
'login' => 'db_admin',
'password' => 'Admin#.2017',
'database' => 'db_main',
);
public function establish_connection()
{
$connection = new mysqli($this->host, $this->user, $this->pass, $this->db);
if($connection == TRUE)
{
return $connection;
}
else
{
die("Could Not Establish Connection! ".$connection->error);
}
}
}
?>
The problem with this code is that i have declared here varaibles 1st for offline and 2nd for online as i am using git i have to again and again change the codes before pushing to master branch. I even tried to use the .gitignore feature but it isn't working as well but still i wan to set the variables dynamically according to the server host.
I have tried using the switch case thing but its giving an syntactical error while compiling. Can anyone help mw with this code.
Any helps appreciated.
Set your database credentials in a new file that you will then add to .gitignore like so :
$dbConfig = array(
"host" => "localhost",
...
)
then simply access to your $dbConfig in your Connection class
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)));
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 .
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);
}
?>
I want to create a database connection programmatically without using the config file. I have a form wherein the user enters the database details like the hostname, username, password and the database name. On the basis of these details a new test connection is made and if it passes it should generate the necessary files.
This is what I have tried:
// Create Test DB Connection
Yii::$app->set('id', [
'class' => 'yii\db\Connection',
'dsn' => $dsn,
'username' => $form->username,
'password' => $form->password,
'charset' => 'utf8'
]);
try {
// Check DB Connection
if (Yii::$app->db->getIsActive()) {
// Write Config
$config['components']['db']['class'] = 'yii\db\Connection';
$config['components']['db']['dsn'] = $dsn;
$config['components']['db']['username'] = $username;
$config['components']['db']['password'] = $password;
$config['components']['db']['charset'] = 'utf8';
Configuration::setConfig($config);
$success = TRUE;
return $this->redirect(['init']);
}else{
$errorMsg = 'Incorrect Configurations';
}
} catch (Exception $e) {
$errorMsg = $e->getMessage();
}
I have tested this again and again and even with correct configurations it is giving an error.
All the help is appreciated. Thanks in advance!
You can define a new connection this way:
$db = new yii\db\Connection([
'dsn' => 'mysql:host=localhost;dbname=example',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
$db->open();
After the DB connection is established, one can execute SQL statements like the following eg:
$command = $db->createCommand('SELECT * FROM post');
$posts = $command->queryAll();
// or
$command = $connection->createCommand('UPDATE post SET status=1');
$command->execute();
you can look at this for doc and guide
http://www.yiiframework.com/doc-2.0/guide-db-dao.html
http://www.yiiframework.com/doc-2.0/yii-db-connection.html
I realised my mistake. When using Yii::$app->set() for setting up the db connection, you have to even manually open the connection using Yii::$app->db->open(). Yii doesn't open up the connection for you.