I am writing a database class which is going to connect to my pdo database. This class is using this config file to get the information needed:
<?php
return [
'host' => '127.0.0.1',
'username' => 'root',
'password' => '',
'database_name' => 'books',
'database_type' => 'mysql',
'options' => []
];
And this is the database class:
<?php
class DB
{
public static function connect($config)
{
try {
return new PDO([
$config['database_type'] . ':host=' . $config['host'] . ';dbname=' . $config['database_name'],
$config['username'],
$config['password'],
$config['options']
]);
} catch(PDOException $e) {
die($e->getMessage());
}
}
}
I am getting this error:
Fatal error: Uncaught TypeError: PDO::__construct() expects parameter
1 to be string, array given in and etc...
I am wondering what I did wrong, sicne I don't see any syntax mistakes in my code.
You have an extra set of brackets:
return new PDO([
...
]);
... shouldn't have the [ and ] respectively; they're turning your four function parameters into a single array parameter. You want simply
return new PDO(
...
);
HTH!
Related
Given the code
$connectionParams = array(
'dbname' => $this->dbname,
'user' => $this->dbuser,
'password' => $this->dbpass,
'host' => $this->dbhost,
'driver' => 'mysqli',
);
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams);
var_dump($conn);
How can I get the underlying mysqli handle from $conn (which is a Doctrine\DBAL\Connection)?
I have found *a way* to access it, but its obviously not the way it's supposed to be done, so I'm up for suggestions:
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams);
foreach((array)$conn->getWrappedConnection() as $mysqli){
// TODO: find official way of getting the handle.
// here we are casting it to (array) to access its PRIVATE PROPERTIES
// it's a fugly hack.
break;
}
var_dump($mysqli);
You can get it this way:
$mysqli = $conn->getWrappedConnection()->getWrappedResourceHandle();
I have connected my appication with aws rds with the script below:
function db_connect() {
$result = new mysqli($_SERVER['RDS_HOSTNAME'], $_SERVER['RDS_USERNAME'], $_SERVER['RDS_PASSWORD'], $_SERVER['RDS_DB_NAME'], $_SERVER['RDS_PORT']);
if (!$result) {
throw new Exception('Could not connect to database server');
} else {
return $result;
}
}
It was working fine then i had to change it due to a new feature which someone else wrote the code for:
$dbOptions = array(
'db_host' => 'RDS_HOSTNAME',
'db_user' => 'RDS_USERNAME',
'db_pass' => 'RDS_PASSWORD',
'db_name' => 'RDS_DB_NAME'
);
I didn't add the port because he didn't and i never connected to database with an array and key like this, how do i go about adding port like at what position.
I was forgetting the $_SERVER variable:
$dbOptions = array(
'db_host' => $_SERVER['RDS_HOSTNAME'],
'db_user' => $_SERVER['RDS_USERNAME'],
'db_pass' => $_SERVER['RDS_PASSWORD'],
'db_name' => $_SERVER['RDS_DB_NAME']
);
I am having problems with a connection to the database, specifically, when I try to access the system and the database does not respond.
I am getting an error in my services.php file.
And this is the code:
try{
$di->set('db', function () use ($config) {
$config = $config->get('database')->toArray();
$dbClass = 'Phalcon\Db\Adapter\Pdo\\' . $config['adapter'];
if (stripos($config['adapter'], 'Mysql')!== false) {
$mi_conf = array(
"host" => $config['host'],
"username" => $config['username'],
"password" => $config['password'],
"dbname" => $config['dbname'],
"options" => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
)
);
} else {
$mi_conf = array(
"dbname" => '//'.$config['host'].'/'.$config['dbname'],
"username" => $config['username'],
"password" => $config['password'],
'charset' => 'utf8'
);
}
unset($config['adapter']);
return new $dbClass($mi_conf);
});
} catch (Exception $e) {
$error .= 'db, ';
return null;
}
I do not know if it will be necessary to change there or I have to make changes to each call from each model.
Any advice?
Thank you.
The code looks without errors.
Use setShared to avoid connecting to the database multiple times, or use the "persistent" attribute on the configuration to take effect. Maybe it does the trick. By the way, change the try catch to the moment where the service was created, so you can catch the exception.
$di->setShared('db', function () use ($config) {
try {
$config = $config->get('database')->toArray();
$dbClass = 'Phalcon\Db\Adapter\Pdo\\' . $config['adapter'];
if (stripos($config['adapter'], 'Mysql') !== false) {
$mi_conf = array(
"host" => $config['host'],
"username" => $config['username'],
"password" => $config['password'],
"dbname" => $config['dbname'],
"persistent" => false,
"options" => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
),
);
} else {
$mi_conf = array(
"dbname" => '//' . $config['host'] . '/' . $config['dbname'],
"username" => $config['username'],
"password" => $config['password'],
"persistent" => false,
'charset' => 'utf8',
);
}
unset($config['adapter']);
return new $dbClass($mi_conf);
} catch (Exception $e) {
$error .= 'db, ';
return null;
}
});
I'm setting timezone to php and mysql to internacionalize my CakePHP application.
When the server receives a request from a client, before process request, it connects to a GeoIp location server and gets the Timezone. Then I use date_default_timezone_set() to set php timezone. The problem comes up when I want to set database timezone. Once Cakephp connected, I need to execute sql query like SET time_zone='-06:00'.
In /lib/Cake/Model/Datasource/Database/Mysql.php I can see at connect() function the following code:
try {
$this->_connection = new PDO(
$dsn,
$config['login'],
$config['password'],
$flags
);
$this->connected = true;
if (!empty($config['settings'])) {
foreach ($config['settings'] as $key => $value) {
$this->_execute("SET $key=$value");
}
}
} catch (PDOException $e) {
throw new MissingConnectionException(array(
'class' => get_class($this),
'message' => $e->getMessage()
));
}
There is a $config['settings'] array that can be configured to do it. But I don't know how to fill settings array and where it's the best place to do that.
What I need is modify default datasource config on-the-fly
You can add an additional key to config array located at app/Config/database.php like this:
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'db_user',
'password' => 'db_pass',
'database' => 'db_name',
'prefix' => '',
'settings' => array(
'time_zone' => "'+01:00'", // note the quotes!
)
);
Related: CakePHP switch database (using same datasource) on the fly?
I solved it in the following way.
First of all, adding setOptions() method into DATABASE_CONFIG class as follows:
public function setOptions ($datasource, array $options){
$this->{$datasource} = array_merge($this->{$datasource}, $options);
}
Afterwards, extending ConnectionManager class to initialize it:
class ConnectionManagerCustomConfig extends ConnectionManager
{
public static function initialize(){
self::_init();
}
}
Now I initialize the class and add new options:
ConnectionManagerCustomConfig::initialize();
$configClass = ConnectionManagerCustomConfig::$config;
$configClass->setOptions('default', array(
'settings' => array(
'time_zone' => $offset
)
));
I'm getting a problem using ZF2 and DbAdapter.
I'm making a select statement and trying to get te exception when happen some error.
I have my select statement inside a block try... catch... but the problem is when I set a "wrong query", the exception is not threw.
Here my service:
return array(
'db' => [
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=my_dbname;host=localhost',
'username' => 'root',
'password' => 'root',
'driver_options' => [
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'',
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]
],
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => function ($serviceManager) {
$adapterFactory = new Zend\Db\Adapter\AdapterServiceFactory();
$adapter = $adapterFactory->createService($serviceManager);
\Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter);
return $adapter;
}
),
),
);
Here my query:
try {
$db = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
$sql = "SELECT * FROM `table`";
$statement = $db->query($sql);
$res = $statement->execute();
} catch (PDOException $e) {
echo $e->getMessage();
}
Reivaldo, welcome to stackoverflow!
Since Zend DB drivers utilizing custom statement instances, Exceptions thrown by PDO and other possible errors handled internally and converting to Zend\Db\Adapter\Exception instances if necessary.
Check out this example.
Instead of catching the PDOException in your code, always catch possible exceptions from most specific one to most generic one. This is a good practice.
For example:
try {
// code to throw exceptions
} catch (\Zend\Db\Adapter\Exception $e) {
echo $e->getMessage();
} catch (\Exception $e) {
// This is not an adapter exception, anyway its an exception.
echo $e->getMessage();
} finally {
// This block always executed, an exception thrown or not.
}
You may also want to read some documentation about exception handling.