Connecting to AWS RDS via PDO - php

I have been trying to connect my PHP application to a MySQL database on AWS RDS via PDO. I have seen a similar question here: Unable to connect to AWS RDS through PDO but this is over 4 years old with no definitive answers.
I have tried this a couple of ways. Firstly, passing the host name as '<my-db-name.eu-west-2.rds.amazonaws.com:3306' and secondly passing the port explicitly in the dsn string via
$dsn = $dsn = "mysql:host=" . $this->host . ";port=". $this->port . ";dbname=" . $this->name . ";charset=utf8";
(commented out below). Neither works!
The code snippet is:
$dsn = null;
$options = null;
$this->host = SYSTEM_CONFIG["database"]["host"];
$this->type = SYSTEM_CONFIG["database"]["type"];
$this->name = SYSTEM_CONFIG["database"]["name"];
$this->user = SYSTEM_CONFIG["database"]["user"];
$this->pass = SYSTEM_CONFIG["database"]["pass"];
/* New */
$this->port = SYSTEM_CONFIG["database"]["port"];
switch ($this->type) {
case "SQLSRV":
$dsn = "sqlsrv:Server=" . $this->host . ";Database=" . $this->name;
$options = [
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => true,
PDO::ATTR_STRINGIFY_FETCHES => false
];
break;
default:
$dsn = "mysql:host=" . $this->host . ";dbname=" . $this->name;
//$dsn = "mysql:host=" . $this->host . ";port=". $this->port . ";dbname=" . $this->name . ";charset=utf8";
$options = [
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_STRINGIFY_FETCHES => false
];
}
try {
$this->pdo = new PDO($dsn, $this->user, $this->pass, $options);
} catch (PDOException $e) {
$this->logError($e);
} catch (Exception $e) {
$this->logError($e);
}
One thing that does work is to pass the IP address and port as the host name in the form
$this->host = "<IP-address>:3306"
However, I only found the IP address by pinging the host name and I am not sure if this is static or a dynamic IP address (the latter would be no good in a config file!).
Any help on this would be much appreciated!

Have got the code working now, although quite frustratingly I never got to the bottom of why it wasn't working in the first place! I suspect it was something to do with not picking up on the port number properly - maybe a typo somewhere that got 'accidently' corrected (rather than deliberately) when I was trying things out. This code now works (just for MySQL):
$dsn = null;
$options = null;
$this->host = SYSTEM_CONFIG["database"]["host"];
$this->type = SYSTEM_CONFIG["database"]["type"];
$this->name = SYSTEM_CONFIG["database"]["name"];
$this->user = SYSTEM_CONFIG["database"]["user"];
$this->pass = SYSTEM_CONFIG["database"]["pass"];
$this->port = SYSTEM_CONFIG["database"]["port"];
switch ($this->type) {
case "SQLSRV":
// Other untested code...
break;
default:
$dsn = "mysql:host={$this->host};port={$this->port};dbname={$this->name};charset=utf8";
$options = [
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_STRINGIFY_FETCHES => false
];
}
try {
$this->pdo = new PDO($dsn, $this->user, $this->pass, $options);
} catch (PDOException $e) {
$this->logError($e);
} catch (Exception $e) {
$this->logError($e);
}

Related

Using LOB data in PHP with PDO instead of OCI_Connect

I was using OCI_Connect to connect to my Oracle database.
Because of some internal plicies, i need to change it to PDO.
With OCI_Connect, i can read LOB data from database with "->load()" function in the result, something like this:
$this->Conn = oci_connect($this->User, $this->Pass, $this->Name, 'AL32UTF8');
$sql = "select field from table";
$s = oci_parse($this->Conn, $sql);
$res = oci_fetch_array($s, OCI_ASSOC + OCI_RETURN_NULLS)
echo $res[0]['FIELD']->load();
and it worked very well.
Now i need to do the same stuff with PDO, and because all my queries may change the number and name of the fields, i cannot bind the variables before executing it.
What i'm using now to connect:
$dbTns = "(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = $server)(PORT = $port)) (CONNECT_DATA = (SERVICE_NAME = $service_name) (SID = $sid)))";
$paramArray = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);
$this->PDO = new PDO("oci:dbname=" . $dbTns . ";charset=utf8", $db_username, $db_password, $paramArray );
With PDO, everything works fine, but i can't use the "->load()" function in the LOB field, as it does not exists here.
Is there an equivalent way to get the data after the query run?
Any suggestions are welcome.
(yes, i did search for a solution before posting that question here)

Optimize PHP PDO Transaction from CURL Stream

I'm using CURL to request large XML Files from an API.
To prevent memory leaks I use this CURL option to stream the data and send it to the function curlCallback:
curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($splitter, 'curlCallback'));
In the curlCallback I prepare the incoming XML Stream and call the function below to store every main XML Node in the MySQL Database. Everything works well but:
I want to optimize the efficiency to store the data in the MySQL Database. This is the actual code:
public function processLine($str) {
$prdData = simplexml_load_string($str);
// connect to mysql db
$servername = "localhost";
$username = "";
$password = "";
$dbname = 'temp';
$db = new \PDO('mysql:host=' . $servername . ';dbname=' . $dbname . ';charset=utf8mb4',
$username,
$password,
array(
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_PERSISTENT => false
)
);
try {
$stmt = $db->prepare("INSERT IGNORE INTO Product (PRDNO, DSCRD ,DSCRF, DSCRLONGD, DSCRLONGF, PRTNO, SMCAT, DEL, BNAMD) VALUES (:prdno, :dscrd, :dscrf, :dscrlongd, :dscrlongf, :prtno, :smcat, :del, :bnamd)");
// MySQL Transaction
$db->beginTransaction();
$stmt->bindParam(':prdno', $prdData->PRDNO);
$stmt->bindParam(':dscrd', $prdData->DSCRD);
$stmt->bindParam(':dscrf', $prdData->DSCRF);
$stmt->bindParam(':dscrlongd', $prdData->DSCRLONGD);
$stmt->bindParam(':dscrlongf', $prdData->DSCRLONGF);
$stmt->bindParam(':prtno', $prdData->PRTNO);
$stmt->bindParam(':smcat', $prdData->SMCAT);
$stmt->bindParam(':del', $prdData->DEL);
$stmt->bindParam(':bnamd', $prdData->BNAMD);
$stmt->execute();
$db->commit();
} catch (PDOException $e) {
error_log(date("d.m.Y H:i:s") . ' | ' . $e->getMessage() . PHP_EOL, 3, '/var/www/html/log/import.log');
$db->rollBack();
}
}
How can I optimize this to just send one transaction including for example 100 Rows?

PHP PDO_SQLSRV: encoding error with column containing accented chars

I'm getting back "�" instead of accented chars in my PSO_SQLSRV querys. This is how i connect to the db:
$dsn = 'sqlsrv:Server=' . $this->host . ';Database=' . $this->dbname;
`$options` = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
} catch (PDOException $e) {
new DatabaseErrorHandler($e);
}
I tried adding PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8 to my $options array, but nothing changes. Db collation is Latin1_General_CI_AS.
I'm using Microsoft driver php_pdo_sqlsrv_56_nts.dll with PHP 5.6.14

PHP (Bluemix) Secure Gateway, how to connect and get data?

So I have a secure gateway on bluemix.
The secure gateway is connecting to LDAP Service on my local premise.
In the secure gateway I have configured a mutual TLS.
For Now, I'm using React\socket-client to connect, and it connect successfully. I just now lost on how to query data in the LDAP. There will be always cannot connect to LDAP Server.
$loop = React\EventLoop\Factory::create();
$tcpConnector = new React\SocketClient\TcpConnector($loop);
$dnsResolverFactory = new React\Dns\Resolver\Factory();
$dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);
$dnsConnector = new React\SocketClient\DnsConnector($tcpConnector, $dns);
$secureConnector = new React\SocketClient\SecureConnector($dnsConnector, $loop, array(
'verify_peer' => true,
'verify_peer_name' => true,
'allow_self_signed' => true,
'cafile' => <CACERT>,
'local_pk' => <PK_CERT>,
'local_cert' => <LOCALCERT>
));
$secureConnector->create(<Secure Gateway Link>)->then(function(React\Stream\Stream $stream)
{
//I'M CONNECTED HERE
//Secure gateway status is establishing connection and not closing
$ldap_server = "ldap://0.0.0.0";
$basedn = "<xxx>";
$auth_user = "<xxx>";
$auth_pass = "<xxx>";
if (!($connect = #ldap_connect($ldap_server)))
{
throw new Exception("Cannot connect to LDAP");
} else
{
try
{
//In order to avoid unable bind to server
ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
$bind = ldap_bind($connect, $auth_user, $auth_pass);
if (!$bind)
{
if (ldap_get_option($connect, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error))
{
throw new Exception("Error Binding to LDAP: $extended_error");;
} else
{
throw new Exception("Error Binding to LDAP: No additional information is available.");
}
} else
{
//connected to LDAP and do search
//never goes here
}
} catch (Exception $exc)
{
$exc->getMessage();
$stream->end();
}
}
}, function($err)
{
echo $err . '<br>';
die();
});
$loop->run();
I'm translating nodejs code on https://developer.ibm.com/bluemix/2015/04/17/securing-destinations-tls-bluemix-secure-gateway/
to this code....
I can use another packet if I have to, I just don't know what to use.
Please help me..
thanks in advance

Jommla connect to another database using Multisites extension

I'm using Joomla 2.5 and Multisites extensions. When I'm on page X Joomla is using X-database, on page Y using Y-database - it's ok. Unfortunately I have to switch to another database. How I said $db = JFactory::getDbo(); connect to current site database, because Multisites extension works that every page has his own configuration file with database parameters. Any ideas?
Here is solution:
$option['driver'] = 'mysqli';
$option['host'] = 'localhost';
$option['user'] = 'root';
$option['password'] = '';
$option['database'] = 'joomla';
$option['prefix'] = 'a45gy_';
JFactory::destroy();
$db = JDatabase::getInstance($option);
if (JError::isError($db)) {
jexit('Database Error: ' . $db->toString());
}
if ($db->getErrorNum() > 0) {
JError::raiseError(500, 'JDatabase::getInstance: Could not connect to database <br />');
}
parent::setDbo($db);
try it.
$dbX = JDatabase::getInstance(array ('host' => $host, 'user' => $user, 'password' => $pass, 'database' => $database, 'prefix'=>null));
$dbY = JDatabase::getInstance(array ('host' => $host, 'user' => $user, 'password' => $pass, 'database' => $database, 'prefix'=>null));

Categories