This is a awkward issue, and I'm running out of alternatives to workaround.
I have a server running Wamp 3.0.6, with PHP 5.6.
My code must connect in a MySQL (local) and a PostgreSQL (remote server).
Everything is working fine, and seemingly out of nowhere it stops returning data from PG. After few seconds or minutes, it just works again.
Even when I'm not able to get data from PG, phpPgAdmin keeps working.
Here is my connection function:
function pdo_pgsql($sql){
$host = '000.000.000.000';
$user = 'user';
$pass = 'pass';
$db = 'db';
try {
$PDO = new PDO( 'pgsql:host=' . $host . ';dbname=' . $db . ';port=5432', $user, $pass, array(
PDO::ATTR_PERSISTENT => true
));
}
catch ( PDOException $e ) {
echo 'Error: ' . $e->getMessage(); exit;
}
$result = $PDO->query( $sql );
if (is_array($result)){
$row = $result->fetchAll( PDO::FETCH_ASSOC );
}else{
$row = $result;
}
return $row;
}
Any suggestion to help me with this?
Thanks
I have the same problem, and I found the solution, it is the PDO::ATTR_PERSISTENT need to be set to false.
This fixed my problem.
Related
Forgive me, as I've not worked in php for years. I'm picking up some old code to get working again and I'm having a strange issue.
I'm writing in php with wordpress. As I am editing the code, I've noticed the php tag is closing after the following:
<?php
$databaseHost = "Localhost";
$databaseName = "testDB";
$databaseUser = "TESTUSER";
$databasePassword = "TESTPASS";
$coin_id = (isset($_POST['coin_id'])) ? $_POST['coin_id'] : '';
try {
$db = new PDO('mysql:host=' . $databaseHost . ';dbname=' . $databaseName . ';charset=utf8', $databaseUser, $databasePassword);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$request = "SELECT
_7UR_participants_database.city,
_7UR_participants_database.state,
_7UR_participants_database.country,
_7UR_participants_database.zip,
_7UR_participants_database.coin_id,
FROM _7UR_participants_database GROUP BY _7UR_participants_database.coin_id ASC";
$stmt = $db->query($request);
$item_info = $stmt->fetchAll();
} catch (PDOException $e) {
echo "Exception: " . $e->getMessage();
exit;
} // Try / catch end
?>
Everything after that > following $db- is not included in the php. The php tag is closing with that last >. Do I need to escape the character or something of that nature?
since your formatting is hard to undertand i rewrite it on my liking that it "migth" actually works
$dsn = "mysql:host=localhost;dbname=testDB;charset=utf8mb4"; // most cool kids use charset=utf8mb4
$options = [
PDO::ATTR_EMULATE_PREPARES => false, // turn off emulation mode for "real" prepared statements
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array
];
try {
$dbh = new PDO($dsn, "TESTUSER", "TESTPASS", $options);
} catch (Exception $e) {
error_log($e->getMessage());
echo ("Error Code: " . $e->getCode() . "<br>"); // never use echo on public release build it would leak your database credential this is optional great for troubleshooting
echo ("Error Message: " . $e->getMessage() . "<br>");
exit('Something weird happened');//
}
$request = $dbh->prepare("SELECT
_7UR_participants_database.city,
_7UR_participants_database.state,
_7UR_participants_database.country,
_7UR_participants_database.zip,
_7UR_participants_database.coin_id,
FROM _7UR_participants_database GROUP BY _7UR_participants_database.coin_id ASC";
$request->execute([]); // you do not have something like this also i never put value since i don't know what your doing
$item_info = $request->fetchAll(); // store the fetched on $item_info also you need to indicate what data type you fetching by default it always PDO::FETCH_ASSOC
This script
<?php
/* Connect to a MySQL database using driver invocation */
$dsn = 'mysqldg';
$user = 'odbc_dg';
$password = '999999999';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
?>
gives the error *Connection failed: invalid data source name*
I have created an entry in /etc/odbc.ini as follows:
[mysqldg]
Description = DGDB
Driver = mysql537
Database = dg1
Servername = 99.99.99.99
UID = odbc_dg
PWD = 999999
SSLKeyFile = /etc/mysql/ssl/ck.pem
SSLCertFile = /etc/mysql/ssl/cc.pem
SSLCAFile = /etc/mysql/ssl/c1.pem
/etc/odbcinst.ini has the following entry:
[mysql537]
Description = MySQL driver for Plesk
Driver = /usr/lib/odbc2/lib/libmyodcb5w.so
Setup = /usr/lib/odbc2/lib/libmyodbc5w.so
The entry in odbcinst.ini works with a non-DSN connection.
I'm obviously missing something, can anyone help? Thanks.
UPDATED....
I have tried Your Common Sense's code as follows:
<?php
$host = '46.99.199.199';
$db = 'dg';
$user = 'odbc_dg';
$pass = '999999';
$charset = 'utf8mb4';
$options = array(
PDO::MYSQL_ATTR_SSL_KEY => '/etc/mysql/ssl/ck.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/etc/mysql/ssl/cc.pem',
PDO::MYSQL_ATTR_SSL_CA => '/etc/mysql/ssl/c1.pem'
);
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
?>
... but I get a connection fail message - Connection failed: SQLSTATE[HY000] [2002]
I think the problem is that the keys I have supplied only work with ODBC
For example this code, which uses odbc_connect works....
<?php
ini_set ('error_reporting', E_ALL);
ini_set ('display_errors', '1');
error_reporting (E_ALL|E_STRICT);
$user = "odbc_dg";
$pass = "99999";
$connection = "Driver= {mysql537};Server=46.99.199.199;Database=dgdb;UID=dgdb;PWD=999999;sslca=/etc/mysql/ssl/c1.pem;sslkey=/etc/mysql/ssl/ck.pem;sslcert=/etc/mysql/ssl/cc.pem";
$con = odbc_connect($connection, $user, $pass);
$sql="SELECT Id from stk_item";
$rs=odbc_exec($con,$sql);
if (!$rs) {
exit("Error in SQL");
}
echo "<table><tr>";
echo "<th>Companyname</th>";
echo "<th>Contactname</th></tr>";
while (odbc_fetch_row($rs)) {
echo odbc_result($rs, "Id"), "\n";
}
odbc_close($con);
echo "</table>";
?>
My problem is that I want to connect to the remote database via pdo because that's the only type of connection allowed in the Drupal synchronising code.
what is the best way for create a connection between PHP and SQL server that are seperate?(two server: server a SQL and server b PHP)
notice that I use wamp.
I read some articles like below but I want to know is there any new idea?
I test this code that works perfectly:
try{
$user = 'user';
$password = 'pass';
$server="localhost";//or server IP
$database="database";
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $password);
} catch (PDOException $e) {
echo "Failed : " . $e->getMessage() . "\n";
exit;
}
I use PDO_ODBC Method:
1- Install ODBC on server that has wamp and enable PHP_PDO_ODBC extension on your wamp
2- Use this code that supports UTF-8:
try{
$hostname = "IP";
$dbname = "database";
$username = "username";
$pw = "password";
$pdo = new PDO ("odbc:Driver={SQL Server Native Client 10.0};Server=$hostname;Database=$dbname; Uid=$username;Pwd=$pw;");
} catch (PDOException $e) {
echo "Failed : " . $e->getMessage() . "\n";
exit;
}
$query = $pdo->prepare("select field_name from table");
$query->execute();
for($i=0; $row = $query->fetch(); $i++){
echo iconv("CP1256","UTF-8", $row['field_name'])."<br>";
}
3- replace these Items with yours:
IP-database-username-password-field_name-table
4- sometimes you need use "SQL SERVER" instead of "SQL Server Native Client 10.0" and sometimes you need use "IP,port" instead of "IP" and sometimes you need use "ISO-8859-6" instead of "CP1256".
From the PHP manual: http://php.net/manual/en/pdo.construct.php
Example #1 Create a PDO instance via driver invocation
<?php
/* Connect to a SQL Server database using driver invocation */
$dsn = "sqlsrv:Server=12345abcde.database.windows.net;Database=testdb", "UserName#12345abcde", "Password";
try {
$dbh = new PDO($dsn);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
?>
Just change the HOST ip to the IP and port of your mysql server.
I've seen a number of questions asking similar but these are usually answered by having access to the server to install extra packages such as FreeTDS. We don't have such access as out linux server is hosted with 1and1.
My code (from an earlier question by someone else on here) is:
try {
$hostname = "xx.xx.xx.xx";
$port = xxxxx;
$dbname = "ClientDatabase";
$username = "uuuu";
$pw = "pppp";
$dbh = new PDO ("dblib:host=$hostname:$port;dbname=$dbname","$username","$pw");
} catch (PDOException $e) {
echo "Failed to get DB handle: " . $e->getMessage() . "\n";
exit;
}
$stmt = $dbh->prepare("select name from master..sysdatabases where name = db_name()");
$stmt->execute();
while ($row = $stmt->fetch()) {
print_r($row);
}
unset($dbh); unset($stmt);
The error message I get is:
Failed to get DB handle: could not find driver
The MSSQL server is accessible so I can add features to that if necessary.
The MSSQL server is also running IIS7 but doesn't run PHP. I know very little about IIS7 but would it be easier to run the PHP scripts on there rather than the hosted linux box?
Could anyone advise if I can actually connect to the MSSQL server in anyway?
Thanks in advance,
Dave
Have you tried mssql_connect?
Here's the syntax:
mssql_connect ([ string $servername [, string $username [, string $password [, bool $new_link = false ]]]] )
In your case it would be:
$link = mssql_connect($hostname, $username, $pw);
mssql_select_db($dbname, $link);
Note that $hostname should contain MSSQL Instance Name. e.g. 'KALLESPC\SQLEXPRESS'
After much trial and error I'm in.
try {
$hostname = "localhost";
$port = 123456;
$dbname = "ClientDatabase";
$username = "uuuu";
$pw = "pppp";
$dbh = new PDO ("sqlsrv:Server=$hostname,$port;Database=$dbname","$username","$pw");
} catch (PDOException $e) {
echo "Failed to get DB handle: " . $e->getMessage() . "\n";
exit;
}
$stmt = $dbh->prepare("select name from master..sysdatabases where name = db_name()");
$stmt->execute();
while ($row = $stmt->fetch()) {
print_r($row);
}
unset($dbh); unset($stmt);
Thanks to those who answered and those who answered similar questions by others. Got there.... eventually.
Cheers
Dave
I'm doing an operation that inserts hundreds of records into a MySQL database.
After inserting exactly 176 records I get this error:
[PDOException] SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Any ideas of how could I solve it?
The process is with PHP.
I would venture to say the problem is with wait_timeout. It is set to 30 seconds on my shared host and on my localhost is set for 28800.
I found that I can change it for the session, so you can issue the query: SET session wait_timeout=28800
UPDATE The OP determined that he also needed to change the variable interactive_timeout as well. This may or may not be needed for everyone.
The code below shows the setting before and after the change to verify that it has been changed.
So, set wait_timeout=28800 (and interactive_timeout = 28800) at the beginning of your query and see if it completes.
Remember to insert your own db credentials in place of DB_SERVER, DB_USER, DB_PASS, DB_NAME
UPDATE Also, if this does work, you want to be clear on what you are doing by setting wait_timeout higher. Setting it to 28800 is 8 hours and is a lot.
The following is from this site. It recommends setting wait_timeout to 300 - which I will try and report back with my results (after a few weeks).
wait_timeout variable represents the amount of time that MySQL will
wait before killing an idle connection. The default wait_timeout
variable is 28800 seconds, which is 8 hours. That's a lot.
I've read in different forums/blogs that putting wait_timeout too low
(e.g. 30, 60, 90) can result in MySQL has gone away error messages. So
you'll have to decide for your configuration.
<?php
$db = new db();
$results = $db->query("SHOW VARIABLES LIKE '%timeout%'", TRUE);
echo "<pre>";
var_dump($results);
echo "</pre>";
$results = $db->query("SET session wait_timeout=28800", FALSE);
// UPDATE - this is also needed
$results = $db->query("SET session interactive_timeout=28800", FALSE);
$results = $db->query("SHOW VARIABLES LIKE '%timeout%'", TRUE);
echo "<pre>";
var_dump($results);
echo "</pre>";
class db {
public $mysqli;
public function __construct() {
$this->mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (mysqli_connect_errno()) {
exit();
}
}
public function __destruct() {
$this->disconnect();
unset($this->mysqli);
}
public function disconnect() {
$this->mysqli->close();
}
function query($q, $resultset) {
/* create a prepared statement */
if (!($stmt = $this->mysqli->prepare($q))) {
echo("Sql Error: " . $q . ' Sql error #: ' . $this->mysqli->errno . ' - ' . $this->mysqli->error);
return false;
}
/* execute query */
$stmt->execute();
if ($stmt->errno) {
echo("Sql Error: " . $q . ' Sql error #: ' . $stmt->errno . ' - ' . $stmt->error);
return false;
}
if ($resultset) {
$result = $stmt->get_result();
for ($set = array(); $row = $result->fetch_assoc();) {
$set[] = $row;
}
$stmt->close();
return $set;
}
}
}
Thanks #mseifert.
Your idea worked by doing the same with two variables.
interactive_timeout & wait_timeout
I copied the config from a local database:
SHOW VARIABLES LIKE '%timeout%'
Local db:
Remote db:
I did this inside the connect and disconnect and worked:
mysql_query("SET SESSION interactive_timeout = 28800;");
$result = mysql_query("SHOW VARIABLES LIKE 'interactive_timeout';");
$row = mysql_fetch_array($result);
$interactive_timeout = $row["Value"];
echo("interactive_timeout" . " = " . $interactive_timeout . "\n");
mysql_query("SET SESSION wait_timeout = 28800;");
$result = mysql_query("SHOW VARIABLES LIKE 'wait_timeout';");
$row = mysql_fetch_array($result);
$wait_timeout = $row["Value"];
echo("wait_timeout" . " = " . $wait_timeout . "\n");
Surprisingly it worked with GoDaddy.
I will accept your answer as valid #mseifert since you gave me the original idea.
Thanks a lot.
Let us hope this is useful in the future to solve the 2006 MySQL error for other developers.
In my case, when I got this error on the client side, the server side was
(Got a packet bigger than 'max_allowed_packet' bytes)
So I increase the value of the max_allowed_packet, and so far, no more issues.
On Google Cloud Platform, I edit the DB and add a Database flag and set the value to
max_allowed_packet=134217728
(which is 2^27 = 128M)
As you can only input numbers.
On regular instances, you can follow the doc here :
https://dev.mysql.com/doc/refman/8.0/en/packet-too-large.html
Assume your codes is:
// your codes
$pdo = db::connection()->getPdo();
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($params);
So add below codes before your sql query:
$pdo = db::connection()->getPdo();
// Increase interactive_timeout
$prepend_sql = "SET SESSION interactive_timeout = 28800;";
$stmt = $pdo->prepare($prepend_sql);
$stmt->execute($params);
// Increase wait_timeout
$prepend_sql = "SET SESSION wait_timeout = 28800;";
$stmt = $pdo->prepare($prepend_sql);
$stmt->execute($params);
// your codes
/* $pdo = db::connection()->getPdo(); */
$stmt = $pdo->prepare($sql);
$result = $stmt->execute($params);
Another possible reason would be your client is trying to connect using SSL. while the MySQL/MariaDB server is not expecting that.
a solution is to check if the connection is active, if not re-establishing the connection, here it worked perfectly
<?php
require_once ('config.php');
class DB {
private static $instance;
private function __construct() {
;
}
public static function getInstance() {
if (!isset(self::$instance)) {
try {
self::$instance = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
} catch (PDOException $e) {
echo $e->getMessage();
}
}
try {
$testConn = self::$instance->prepare('SELECT 1');
$testConn->execute();
$testConn = $testConn->fetchAll(PDO::FETCH_ASSOC)[0];
} catch (Exception $ex) {
try {
self::$instance = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
} catch (PDOException $e) {
echo $e->getMessage();
}
}
return self::$instance;
}
public static function prepare($sql) {
return self::getInstance()->prepare($sql);
}
public static function lastInsertId() {
return self::getInstance()->lastInsertId();
}
}