If I create two parallel connections to two servers:
$gw03 = new mysqli('gw03.example', 'user', 'pass', 'db');
$gw04 = new mysqli('gw04.example', 'user', 'pass', 'db');
if (!$gw03->connect_errno) {
...
} else if (!$gw04->connect_errno) {
...
} else {
echo "Failed to connect to gw03: (" . $gw03->connect_errno . ") " . $gw03->connect_error . PHP_EOL;
echo "Failed to connect to gw04: (" . $gw04->connect_errno . ") " . $gw04->connect_error . PHP_EOL;
}
If gw03 is available but gw04 is not, the following is the result
Failed to connect to gw03: (2002) No route to host
Failed to connect to gw04: (2002) No route to host
The failure to connect to $gw04 seems to overwrite $gw03. Aren't $gw03 and $gw04 separate objects? What's going on here?
Unfortunately, mysqli suffers from bad design. The properties connect_errno and connect_error are not really properties. They are just shortcuts to global variables. When the second connection fails the global variable is overwritten internally.
This is a very good reason to stop checking for mysqli errors manually. When an error happens your code should throw an error instead of a warning or failing silently. This error should be properly handled by your application and logged in a secure place on the server. Don't try-catch or echo the error message to the user!
To enable mysqli error reporting you should add the following line before any new mysqli()/mysqli_connect():
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
This setting will tell mysqli to throw an exception as soon as an error is encountered. No more manual checking and no more problems with global variables overwriting themselves.
They are separate connections but the connect_errno method "returns the error code from last connect call".
https://www.php.net/manual/en/mysqli.connect-errno.php
You will want to check for a connection error right after each connection attempt.
$gw03 = new mysqli('gw03.example', 'user', 'pass', 'db');
# check $gw03 for connection error before attempting next connection
$gw04 = new mysqli('gw04.example', 'user', 'pass', 'db');
Related
DSN is:
mysql:dbname='MyDB';unix_socket='/cloudsql/ethereal-accord-123456789:us-central1:dev-Instance'
Connection failed: SQLSTATE[HY000] [2002] No such file or directory
PDO Connection Code:
try {
$conn = new PDO($dsn, $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
return $conn;
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage().' <BR>';
}
I Cannot seem to find detail information on how to setup the connections correctly.
I follow all documents and activated the permissions for the VM IP, the Client SQL API, and Admin API, and nothing..
Any Help will be appreciated.
You don't run the cloudsql proxy or you have defined another location for the socket file. You should check this.
./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306 &
$dsn = 'mysql:host=127.0.0.1;port=3306;dbname=DATABASE_NAME';
https://cloud.google.com/sql/docs/mysql/connect-external-app#pdo-tcp
I reverted my code back to MYSqli instead of PDO using these lines
$host_name = "35.222.111.111";
$database = "myDB123";
$user_name = "dbuser123";
$password = "pass12345";
$GCSocket ="/cloudsql/ethereal-accord-2000000:us-central1:dev-instance-1"; $GCPort='3306';
$connect = mysqli_connect($host_name, $user_name,$password,$database,$GCPort,$GCSocket )
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error() ."<br>";
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL ."<br>";
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL ."<br><br>";
} else {
echo 'DB is connected..! <BR>';
}
return $connect;
The issue was not with the above code, it worked all along, the issue was with permission.
I whitelisted my IP from my Compute Engine VM in the Cloud SQL Server
give permission to your Compute Engine Service Account to access the Cloud SQL
Cloud SQL Client or Cloud SQL Admin
Execute this in the Compute Engine VM:
setsebool -P httpd_can_network_connect_db 1
and voila...
here is where i found the answer!
I have spent the last 2 hours trying to solve this problem. I keep getting this error when trying to connect my php script with mySqli that is all hosted on a WAMP local host.
https://pastebin.com/HrJsnspG
;extension_dir = "./"
; On windows:
extension_dir = "C:\PHP7\ext"
I have added my pastebin above that shows my php.ini file. I changed the extensions as people have suggested on stack overflow and removed the ';' but nothing has worked, i still get the error. I have also reinstalled my WAMP server.
Any further suggestions?
<?php
$servername = "localhost";
$username = "root";
$password = "";
//create connection
$conn = new sqli($servername, $username, $password);
//check fann_get_total_connections
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected Successfully";
?>
To connect properly with MySQLi you need to create an instance of mysqli class, enable error reporting and set the correct charset.
<?php
// Connection code
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new \mysqli('localhost', 'testuser', 'password', 'dbname');
$conn->set_charset('utf8mb4');
For more information see https://phpdelusions.net/mysqli/mysqli_connect#oop
Whenever my website receives too many connections, it's showing my database information.
I have specifically told PDO not to show any error messages with PDO::ERRMODE_SILENT:
$dsn = "mysql:host=" . $database['host'] . ";dbname=" . $database['db'];
$dbh = new PDO($dsn, $database['user'], $database['pass'], array(PDO::ATTR_PERSISTENT => false));
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); // <== add this line
//echo 'Connected to Database<br/>';
Furthermore I have disabled PHP errors:
error_reporting(0);
ini_set('display_errors', '0');
Why is my PDO showing my sensitive database information to everyone when there are too many connections?
Problem is you're trying to connect to the database BEFORE you set the silent attribute. So during the connection attempt, PDO is still free to scream as loudly as it wants. You need to specify silent as part of the connection attempt itself:
$dbh = new PDO($[..snip..], array(PDO::ATTR_PERSISTENT => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT));
^^^^^^^^^^^
im trying to connect to google cloudsql from appengine, but im facing this error:
No connection could be made because the target machine actively refused it
my php file, that i have uploaded to appengine:
$sql = new mysqli(null,
'myuser', // username
'mypass'
'mydb',
null,
'/cloudsql/**:**'
);
if ($mysqli->connect_error) {
echo 'no';
die('Connect Error (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
else {
echo 'yes\n';
}
the appengine is allowed from the cloud sql.
what should i do ?
I have been trying to replicate the error you are getting but am unable to reproduce it when using code sample you provided.
Also your code sample has a few mistakes, you create your connection as $sql but then check $mysqli for connection errors, you should be checking $sql. So I have changed all occurances of $mysqli to $sql and you the more conventional way to check for a connection error is to check connect_errno and then read the message from connect_error
$sql = new mysqli(null,
'your-username', // username
'your_password_or_blank_if_using_root',
'database_name',
null,
'/cloudsql/project_id:instance_name'
);
if ($sql->connect_errno) {
echo 'no';
die('Connect Error (' . $sql->connect_errno . ') '. $sql->connect_error);
} else {
echo 'yes\n';
}
The socket file is actually /cloudsql/project_id:region:instance_id (i.e myproject-prod:us-central1:instance-1)
If you are on Flexible VM you might want to turn on debugging on one of your instances, then SSH to it, you can then verify the socket file indeed exists and try to connect over to it:
sudo apt-get update
sudo apt-get install mysql-client
mysql -u your-username -S /cloud/sql/your-socket-file -p
I'm doing this (yes, I'm using wrong connection data, it's to force a connection error )
try {
$connection = new mysqli('localhost', 'my_user', 'my_password', 'my_db') ;
} catch (Exception $e ) {
echo "Service unavailable";
exit (3);
}
But PHP is doing this php_warning:
mysqli::mysqli(): (28000/1045): Access denied for user 'my_user'#'localhost' (using password: YES)
In the example I'm using wrong connection data to force a connection error, but in the real world the database could be down, or the network could be down... etc..
Question: Is there a way, without suppressing warnings, to intercept a problem with the database connection ?
You need to tell mysqli to throw exceptions:
mysqli_report(MYSQLI_REPORT_STRICT);
try {
$connection = new mysqli('localhost', 'my_user', 'my_password', 'my_db') ;
} catch (Exception $e ) {
echo "Service unavailable";
echo "message: " . $e->message; // not in live code obviously...
exit;
}
Now you will catch the exception and you can take it from there.
For PHP 5.2.9+
if ($mysqli->connect_error) {
die('Connect Error, '. $mysqli->connect_errno . ': ' . $mysqli->connect_error);
}
You'll want to set the Report Mode to a strict level as well, just as jeroen suggests, but the code above is still useful for specifically detecting a connection error. The combination of those two approaches is what's recommended in the PHP manual.
Check $connection->connect_error value.
See the example here: http://www.php.net/manual/en/mysqli.construct.php
mysqli_report(MYSQLI_REPORT_STRICT);, as described elsewhere, gives me an error and stops the script immediately. But this below seems to provide the desired output for me...
error_reporting(E_ERROR);
$connection = new mysqli('localhost', 'my_user', 'my_password', 'my_db') ;
error_reporting(E_ERROR | E_WARNING | E_PARSE);
if($connection->connect_errno)
{
// Database does not exist, you lack permissions, or some other possible error.
if(preg_match($connection->connect_error, "Access denied for user"))
{
print("Access denied, or database does not exist.");
}
else
{
print("Error: " . $connection->connect_error);
}
}
Attempting to catch this error with try..catch() will fail.