This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
mysql_connect (localhost / 127.0.0.1) on Windows platform
I just updated my Apache and PHP versions on a development machine and PDO has totally crapped out.
This is the dead simple PDO class:
class PDO_DBH {
public static function openSesame() {
echo '<p>start openSesame: </p>'.microtime(true);
$db_username = 'root';
$db_password = 'pass';
try {
$dbh = new PDO('mysql:host=localhost;dbname=DB_NAME', $db_username, $db_password);
$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
echo '<p>end successful openSesame: </p>'.microtime(true);
return $dbh;
} catch (PDOException $e) {
echo '<p>end failed openSesame: </p>'.microtime(true);
return 'PDO database access error!';
}
}
}
Prior to upgrading, and currently on other dev machines, a typical page will load in a second, two at most.
Now, via the wonders of microtime(true), I am seeing each connection opening requires about a full second.
A typical page may create a new $dbh and then $dbh = null; it 20 times as different objects and methods go about retrieving the data they need. This has never been a problem on other machines or on my webhost.
Where have I gone wrong here?
It was just a guess - but on windows machines changing to 127.0.0.1 instead of localhost does the trick.
Related
We're developing a PHP application that connects both to a PostgreSQL server and an IBM i server with DB2. While the PDO connection to PGSQL works just fine, the connection to DB2 can only fetch from tables; trying to Insert or Delete results in the following error:
SQLSTATE[HY000]: General error: -7008 (SQLExecute[4294960288] at /build/php7.0-ltLrbJ/php7.0-7.0.33/ext/pdo_odbc/odbc_stmt.c:260)
This error happens both on our development and production environments. Both servers are Ubuntu (different versions, but not by much); I'm using the ODBC driver for PDO.
We tried to connect to other IBM i servers, and with different users, but the exact same problem still arises. Can Select, but not Insert. Googling the error code doesn't yield any useful result, and as you can see the error message itself it's as unhelpful as can be. The code in the SQLExecute particularly doesn't appears anywhere, not even a single result (there is a result from an IBM page, but it's actually a different error code).
The code is pretty simple, but perhaps there is some obvious and glaring error there.
The test script:
include("DB2.php");
$oDAO = new DAO();
$res = $oDAO->ejecuta("INSERT INTO <Library>.<File> VALUES (1,0,1)");
The DAO:
class DAO{
var $link;
public function __construct(){
// función constructora, inicia la conexión
$this->link = new PDO("odbc:DRIVER={IBM i Access ODBC Driver};SYSTEM=<System>;PROTOCOL=TCPIP",
'<user>', '<pass>');
$this->link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
private function begin() { $this->link->beginTransaction(); }
private function rollback() { $this->link->rollBack(); }
private function commit() { $this->link->commit(); }
public function ejecuta($query){
try{
$this->begin();
$oResult = $this->link->query($query);
if($oResult){
$bResult = true;
$this->commit();
}else{
$bResult = false;
$this->rollback();
}
}
catch (Exception $e){
echo $e->getMessage();
$bResult = false;
$this->rollback();
}
return $bResult;
}
}
Frankly, we're out of options and I already wasted two weeks with this. We just need to insert and delete records. So any help is welcome.
The symptoms you describe are consistent with attempting to modify the database under commitment control, but without journaling enabled.
There are three common ways to deal with this:
Turn journaling on. This is pretty extreme, since the folks who administer the database would have to do this, and if they've got journaling turned off, it's likely they either don't really know how to deal with journals, or don't want to. But it's the only practical way to have full commitment control on Db2 for i.
Connect with autocommit on. This will add an implicit commit to any database-modifying SQL statements executed with this connection. In my experience, this is the most common and convenient way to handle the situation.
Add WITH NC to each relevant SQL statement. In principle, this gives you statement-by-statement control over whether to suspend commitment control. In practice, if you are thinking of doing this in the first place, you probably don't have journaling enabled, and thus you will have to do this on each and every database-modifying SQL statement. This is why most people gravitate toward option 2.
I have an app that has to use more than one database for reasons of client protection and archiving with a core one for administration - eg user detail storage. I appreciate the need to migrate from the mysql extension (soon to be deprecated) and I first tried mysqli but could not get away from the persistent connection, even using the change_user function, probably because the same user/pass combo is used so cross-database joins are possible.
I am implementing many stored procedures during the migration to reduce bottlenecks. MYSQL now assigns SPs to each specific database, so it is important to be connected to the right one when making a CALL. That means putting full database.table references in queries is not practical
So I have turned to PDO.
I created a test script:
$db_host="localhost";
$db_username='root';
$db_pass='';
$add='admin';
$db_name='host_base_name'.$add;
try{
$db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_username,$db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$result= $db->query("SELECT firstname from centralusers WHERE usr_id='1'");
while($row=$result->fetch(PDO::FETCH_ASSOC)){echo $row['firstname']."<br>";}
}
catch(PDOException $e){echo $e->getMessage();}
$add='test';
$db_name='host_base_name_'.$add;
try{
$db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_username,$db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$result= $db->query("SELECT stage_desc from action_stage WHERE stage_id='1'");
while($row=$result->fetch(PDO::FETCH_ASSOC)){echo $row['stage_desc']."<br>";}
}
catch(PDOException $e){echo $e->getMessage();}
And that successfully does the switch - I tried across three databases but have not shown the third for economy.
However, in the development code my script has a 'require' file which contains a function to handle the connection. it is sent the last part of the table name via the call (a process that has worked fine in the mysql extension. Here is that code;
function db_connect($add) {
$db=NULL;
$db_host="localhost";
$db_username='root';
$db_pass='';
$db_name='host_base_name_'.$add;
try{
$db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_username,$db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}
catch(PDOException $e){echo $e->getMessage();}
return $db;
}
After the second call (to change the database) my next query produces an error that the table cannot be found - and gives the 'host_base_name_ 'part of the table reference as the original. I thought the NULL call would have destroyed the instance.
If I put the $db=NULL; in the calling script, just before the function I get a "Call to a member function query() on a non-object " Scream error.
Why does one work and not the other because they seem identical and how could I work round this?
Have separate PDOs for each database
$db_host="localhost";
$db_username='root';
$db_pass='';
$add='admin';
$db_name1='host_base_name'.$add1;One database
$db_name2='host_base_name'.$add2;Other database
try{
//PDO for one database
$db1= new PDO('mysql:host='.$db_host.';dbname='.$db_name1,$db_username,$db_pass);
$db1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
//PDO for other database
$db2= new PDO('mysql:host='.$db_host.';dbname='.$db_name1,$db_username,$db_pass);
$db2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
For those coming across this in future, I found I could indeed replace the function call with a class and create a new connection to a different database. Along the way I discovered the tremendous speed improvement by replacing 'localhost' with '127.0.0.1' -halving the execution of a test script from 0.0060 seconds to 0.0029 which can be significant in complex scripts.
So here is my class - because it is included anyway at the top of the script, I put the main connection parameters at the head of the include so they could be used in the class. The $db_name is modified in the script so it refers to the correct database.
$db_host='127.0.0.1';
$db_user='root';
$db_pass='';
$db_name='host_base_name';
class databaseConnect{
public function connect($db_host, $db_user,$db_pass,$db_name){
try{
$db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_user,$db_pass, array(PDO::ATTR_PERSISTENT=>false));
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}
catch(PDOException $e){echo "Error: ".$e->getMessage()."<br />"; die(); }
return $db;
}
}
I get the new database connection instance (in this case to 'host_base_nametest' using the code below I replace $con with another variable when I have to switch databases, essentially giving me totally flexible and transportable database naming within the connection:
$add='test'; // in production this comes from another variable
$db_inst=$db_name.$add; //builds the database name
$con=new databaseConnect; //calls the class
$db=$con->connect($db_host, $db_user,$db_pass,$db_inst); //gets the new instance
I'm writing a simple blogging web app for my portfolio and I've come across this strange problem. I wrote a PHP script to connect to a database and read and write data to a database by RESTful calls.
I've done this before in other programs with no problems, but in this one I get an error. I wrote a simple test page to check that the RESTful calls would work before I started using them in my main app. Instead of working, I got an error back from my PHP script.
The error goes like this:
Warning: mysqli_connect() [function.mysqli-connect]: (HY000/2002): Can't connect to local MySQL server through socket '/No-MySQL-hostname-was-specified' (2) in /home/releesquirrel/storage.electricsquirrel.net/SimpleBlog/php/model_SimpleBlog.php on line 35
The code leading up to line 35 goes like this:
class model_SimpleBlog {
// Properties
// Database Info
private $serverName = "mysql.electricsquirrel.net";
private $userName = "esqrl_client";
private $userPassword = "fakepassword";
private $dbaseName = "esquirrel_simpleblog";
// Methods
public function model_SimpleBlog() {
//
}
// Load the ten latest entries after an offset
public function loadEntries($offset) {
$result = false;
// Connect to the Database Server
$connection = mysqli_connect($serverName, $userName, $userPassword, $dbaseName);
I've changed the password for privacy but that's the code that's throwing the error. I'm completely stumped. I've used code similar to this with no problems before, and I've tried googling the error code with no luck.
Does anybody know why I'm getting this error and what I can do to fix my code?
In PHP, you need to refer to object variables with $this->:
$connection = mysqli_connect($this->serverName, $this->userName, $this->userPassword, $this->dbaseName);
$serverName, for instance, looks for a variable with that name in the scope of the function. Obviously none exists.
See the manual for more information on PHP object properties.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I've been advised to use anti-sql injection methods, as I am inserting values inside my database. I've looked around the web, and my first failed attempt is this, of which I need some help, with the PDO method. I found examples online to be waaay too empty of substance for me to understand (btw, I ran a line and it told me PDO is enabled):
Is this good in any way, shape or form?
<?php
include ('config.php');
// Host, User, Pass, DB
$con=mysqli_connect("127.0.0.1","*****","*****","*****");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQLi: " . mysqli_connect_error();
}
$host = 'localhost';
$dbname = '****';
$user = '****';
$pass = '*****';
try {
# MS SQL Server and Sybase with PDO_DBLIB
$DBH = new PDO("mssql:host=$host;dbname=$dbname, $user, $pass");
$DBH = new PDO("sybase:host=$host;dbname=$dbname, $user, $pass");
# MySQL with PDO_MYSQL
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
# SQLite Database
$DBH = new PDO("sqlite:my/database/path/database.db");
}
catch(PDOException $e) {
echo $e->getMessage();
}
Also, I get this error upon submitting my form:
Fatal error: Call to a member function prepare() on a non-object in /home/product/*****/*****/*****/processForm-test.php on line 68
One big problem in your code is that it's using both mysqli_connect and PDO to create database connections. Don't do that; that's not supported. Use one or the other.
The lines you have that make PDO connections attempt to connect to four separate databases, SQL Server, Sybase, MySQL and SQLLite, all running on localhost. But you are keeping a handle to only the last one, since you're assigning the database connection to the same variable.
That variable $DBH is your reference to the database session (connection), if the connect succeeds. If it doesn't succeed, that gets assigned a value of false, which you can test, before you proceed.
I think all you need is a single PDO connection to MySQL, like this:
<?php
include ('config.php');
$host = 'localhost';
$dbname = '****';
$user = '****';
$pass = '*****';
try {
# MySQL with PDO_MYSQL
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
}
catch(PDOException $e) {
echo "Connect failed: " . $e->getMessage();
}
I'm extrapolating here, but the most likely explanation for the error message you are getting is that you've got a line of code (not shown in your code sample) like this:
$sth = $DBH->prepare($sql);
The issue is that $DBH is not a reference to valid database connection. $DBH has a value of 'false', and that's because the attempt to connect to the database failed. And false is not an object, so there's no way it can have a method named 'prepare' associated with it.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
and the database is MYSQL
Sometimes when your MySQL connection opened for too long, the connection to the DB will be dropped when the time without a query exceeds the wait_timeout value in my.cnf. You will get "MySQL server has gone away" timeout error.
This is how I implement auto reconnect in my code:
class databaseClass {
var $conn;
var $db;
public function __construct() {
$this->connect();
}
public function connect() {
$this->conn = mysql_connect(DB_HOST, DB_USER, DB_PASS);
$this->db = mysql_select_db(DB_NAME, $this->conn);
}
public function disconnect() {
mysql_close($this->conn);
}
public function reconnect() {
$this->disconnect();
$this->connect();
}
public function queryCompanyExist($company) {
//auto reconnect if MySQL server has gone away
if (!mysql_ping($this->conn)) $this->reconnect();
$query = "SELECT name FROM company WHERE name='$company'";
$result = mysql_query($query);
if (!$result) print mysql_error() . "\r\n";
return mysql_fetch_assoc($result);
}
}
Refer here for more infomation about mysql_ping
From the C mysql API:
my_bool reconnect = 0;
mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);
See http://dev.mysql.com/doc/refman/5.6/en/auto-reconnect.html
From PHP mysqli in php.ini set the global:
mysqli.reconnect = On
See http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.reconnect
For the PHP PDO mysql driver it should be available through PDO::setAttribute but I am unable to find documentation indicating that it is implemented. The code appears to be attempting to respect the MYSQL_OPT_RECONNECT which is now required by mysql but to have failed to do so in the initial implementation (https://bugs.php.net/bug.php?id=58863). The intent of the patch in 58863 is to allow:
new PDO('mysql:host=xxx', 'xx', 'xx',array(PDO::MYSQL_OPT_RECONNECT=>true));
The reasons why the reconnect occurs are various but commonly because a pooled set of connections contains a mature connection which has timed out due to a lack of use. By default mysql connections time out after 8 hours. See: http://dev.mysql.com/doc/refman/5.6/en/gone-away.html
For side effects of a reconnection see: http://dev.mysql.com/doc/refman/5.6/en/auto-reconnect.html
You can use the mysql_ping() function to test the status of the connection and reconnect when it returns false. mysql_ping() will even reconnect for you if you're using a MySQL before 5.0.13 as mentioned on that documentation page; "Since MySQL 5.0.13, automatic reconnection feature is disabled.".
You can write a function which will ping the database via connection and in case it down, reconnect it again and then proceed the query or whatever you want, also take a look on mysqli php library, it can be useful for you.
PS. Also could be useful to implement Singleton design pattern in order to maintain the database connection, once created it will connect to database and then you can implement the method called getConnection which each time will proceed with the check I've described above.
PPS. You can use an exception, try you query, whenever it fails catch an exception, reconnect and try again.
You should be checking if the query fails anyway. By checking the error code you can tell if it failed because of no connection and reconnect. Just make sure you keep track of reconnection attempts so you don't get stuck in a loop.
Why do you need to "reconnect" in the first place? How/Why are you getting disconnected? In PHP you connect at the beginning of the script and the connection is closed automatically at the end of the script.
There's no need to call mysql_close in your script at all (and it would be silly to "automatically reconnect" if you explicitly closed the connection).
You can try mysql_pconnect is that's what you're looking for. The connection will then stay open permanently, and other scripts that connect can use the connection.