Connecting to PGSQL over SSL via Red Bean PHP - php

$dbh = new PDO('pgsql:localhost=host;port=26257;dbname=bank;sslmode=require;sslcert=[path]/client.maxroach.crt;sslkey=[path]/client.maxroach.key;sslrootcert=[path]/ca.crt;',
'maxroach', null, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => true,
));
This a pdo method, i need configure red bean connection for ssl pgsql connection
R::setup( "pgsql:host=$ip;port=$port;dbname=$dbname",$user, $password, $frozen ); ?

You definitely need to write the full path to certificates and keys,
otherwise nothing will work.
$crt = $_SERVER["DOCUMENT_ROOT"]."/client.crt";
$key = $_SERVER["DOCUMENT_ROOT"]."/client.key";
$ca = $_SERVER["DOCUMENT_ROOT"]."/ca.crt";
R::setup( "pgsql:host=$ip;port=$port;dbname=$dbname;sslmode=verify-ca;sslcert=$crt;sslkey=$key;sslrootcert=$ca;",$user, $password, $frozen );
sslmode=verify-ca; better use sslmode=verify-full

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)

Connect to MariaDB by using PDO with accept server cert

I can connect the database with Maria client with --ssl options on application server:
mariadb -h [Address] -P [Port] -u [DB admin user] -p --ssl
But tried to connect the same database on same server with PHP PDO, we got the error message with:
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client[client_ed25519]
I have added below options to PDO connection for simulate the --ssl options
PDO::MYSQL_ATTR_SSL_CA => true,
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
Here is my testing code piece:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$options = [
PDO::MYSQL_ATTR_SSL_CA => true,
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
];
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password, $options);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>
Database version: MariaDB 10.5

Stream very large Blob from MySQL to PHP and create a file

We have a MySQL database that has some very large files stored in blob fields, such as some videos that are over 700MB. File sizes range from .5 MB PDFs to JPEGS, etc...
I'm trying to use PHP to retrieve these columns and create a file on the server that will be later offered up as a download.
I'm currently using the following method:
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE => 1024*1024*500
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
$stmt = $pdo->prepare('SELECT a.TITLE, a.ATTVERSION, a.ATTACHMENTID, a.CONTENTTYPE, a.FILESIZE, d.DATA FROM ATTACHMENTS a
LEFT JOIN ATTACHMENTDATA d ON d.ATTACHMENTID=a.ATTACHMENTID
WHERE a.ATTACHMENTID= ?');
$stmt->execute([$fileid]);
$file = $stmt->fetch();
file_put_contents($storage_dir . "/" . $filename, $file['DATA']);
This works for smaller files (note I'm setting the buffer size to 500MB), but larger files get truncated and corrupted.
I next tried the LOB and unbuffered query approach:
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
$stmt = $pdo->prepare('SELECT a.TITLE, a.ATTVERSION, a.ATTACHMENTID, a.CONTENTTYPE, a.FILESIZE, d.DATA FROM ATTACHMENTS a
LEFT JOIN ATTACHMENTDATA d ON d.ATTACHMENTID=a.ATTACHMENTID
WHERE a.ATTACHMENTID= ?');
$stmt->execute([$fileid]);
$stmt->bindColumn(1, $title, PDO::PARAM_STR, 256 );
$stmt->bindColumn(2, $attversion, PDO::PARAM_INT);
$stmt->bindColumn(3, $attid, PDO::PARAM_INT);
$stmt->bindColumn(4, $contenttype, PDO::PARAM_STR, 256);
$stmt->bindColumn(5, $filesize, PDO::PARAM_INT);
$stmt->bindColumn(6, $data, PDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);
file_put_contents($storage_dir . "/" . $filename, $data)
With this option, I only get 1MB files, and it seems to be ignoring the MYSQL_ATTR_USE_BUFFERED_QUERY => false and since I'm not setting a buffer size, it's defaulting to 1MB. Can anyone offer any advice or see anything glaring? MySQL is on a different server, but I'd be open to doing this another way as well and calling a bash script or something via PHP.
This was initially done on php 5.4.16, which seemed to not support the unbuffered stream. After upgrading to php 8.0.11, I now have this working, with the exception of increasing PHP memory using ini_set.

Connecting To Mongo Replica Set With Doctrine MongoODM Module

We are in the process of updating our API's MongoDB hosting provider from mLab to MongoDB Atlas.
I have updated our connection server to PHP 7.4 with MongoDB PHP extension 1.7.4.
I have updated our API framework from Apigility to Laminas API Tools using the DoctrineMongoODMModule
I can successfully connect using the mongo shell using the following syntax:
mongo "mongodb+srv://test-server-dbteb.mongodb.net/<dbname>" --username <username>
I have looked far and wide to find a sample configuration of the DoctrineMongoODMModule with it's configuration file to connect to a MongoDB Atlas replica set using the mongo+srv:// protocol with no success to this point. Currently the errors are Failed to parse MongoDB URI.
If anyone has had a similar experience, any help would be greatly appreciated.
I had the same issue and im still looking forward to get a real solution.
I directly edited the ConnectionFactory.php in the doctrine-mongo-odm-module (src/DoctrineMongoODMModule/Service/ConnectionFactory.php) with the following code
//...
if (empty($connectionString)) {
$connectionString = 'mongodb+srv://'; //prev: 'mongodb://'
$user = $options->getUser();
$password = $options->getPassword();
$dbName = $options->getDbName();
if ($user && $password) {
$connectionString .= $user . ':' . $password . '#';
}
$connectionString .= $options->getServer() /*. ':' . $options->getPort()*/;
if ($dbName) {
$connectionString .= '/' . $dbName;
}
} else {
// parse dbName from the connectionString
$dbStart = strpos($connectionString, '/', 11);
if ($dbStart !== false) {
$dbEnd = strpos($connectionString, '?');
$dbName = substr(
$connectionString,
$dbStart + 1,
$dbEnd ? ($dbEnd - $dbStart - 1) : PHP_INT_MAX
);
}
}
//...
and in my connection file:
//...
'odm_default' => array(
'server' => '<host>',
'port' => '',
'connectionString' => null,
'user' => '<user>',
'password' => '<psw>',
'dbname' => '<db>',
'options' => array()
),
//...
I think this is the worst possible solution (editing vendor' files) but in my case worked, take that as a temporary fix

How do I shorten the MySQL Connect Time Out - Failover Scenario

I have a fail-over scenario in a Wordpress plugin, where a PHP script on my web server tries to connect to a backup database if the production one is offline.
Currently the fallback seems to take up to 60 seconds. Is this the PHP default? How would I set the time out to something like 10 seconds?
Here is the relevant portion of the script...
try
{
$DBblue = new \PDO('mysql:host='.$samhost.';'.'dbname='.$DBblue, $samuser, $sampass);
$DBgreen = new \PDO('mysql:host='.$samhost.';'.'dbname='.$DBgreen, $samuser, $sampass);
}
catch (\PDOException $pde)
{
// Fallback Database connection
$althost = get_option('fallback_host');
$altuser = get_option('fallback_user');
$altpass = get_option('fallback_password');
$DBblue = new \PDO('mysql:host='.$althost.';'.'dbname='.$DBblue, $altuser, $altpass);
$DBgreen = new \PDO('mysql:host='.$althost.';'.'dbname='.$DBgreen, $altuser, $altpass);
}
Try this:
$DBblue = new \PDO('mysql:host='.$samhost.';'.'dbname='.$DBblue, $samuser, $sampass, array(
PDO::ATTR_TIMEOUT => "10",
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
$DBgreen = new \PDO('mysql:host='.$samhost.';'.'dbname='.$DBgreen, $samuser, $sampass, array(
PDO::ATTR_TIMEOUT => "10",
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
PDO::ATTR_TIMEOUT => "10" ->>> Set timeout to 10 seconds.
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ->>> Throw exception.
More Information : http://php.net/manual/en/pdo.setattribute.php

Categories