Overwriting an object closes the DB connection? - php

We're getting an error from the server saying that there are to many DB connection to the DB. I'm trying to locate the logic which causes the lack of optimization. We connect to the DB using an object called DB_Con. This object creates the connection on init.
My question is if
$Con = new DB_Con
would
$Con = null
close the connection? If so is it done right away or is it slated for garbage collection at a later time.
Also, would the following two lines of code open two DB connections or one?
$Con = new DB_Con
$Con = new DB_Con

You should only really have 1 DB Connection open per execution.
When you're done with the DB use $mysqli->close();
It's even noted on the close page that unless you explicitly close a connection the connection will not close.

Related

mysqli_insert_id() is returning 0 but inserting the data

The Code is:
class anything_i
{
/*Every variable is defined and hidden fro privacy.*/
public function connect(){
return mysqli_connect(self::HOST,self::USERNAME,self::PASSWORD,self::DATBASE);
}
public function insertData($postData){
$sqli = 'INSERT INTO `payments`(`item_name`,`price`,`email`,`date`,`time`,`detail`,`volume`,`ip`,`payment_status`) VALUES ("'.$productData['name'].'","'.$productData['price'].'","'.$postData['email'].'","'.$date.'","'.$time.'","'.$postData['list'].'","'.$productData['volume'].'","'.$ip.'","On Hold")';
if(mysqli_query($this->connect(),$sqli)){
print_r(mysqli_insert_id($this->connect()));
}else{
print_r(mysqli_error($this->connect()));
}
}
}
It is inserting the data and working fine but does not return anything other than a 0 (zero) not getting any error.
Let me clear that my table contains auto_increment and my connection is fine because it is entering data just fine. Please don't disregard the question because you found similar once answered. I also found similar questions but most of them have connection problems, some of them the no AUTO_INCREMENT column and there may be some which included another query in between. So, please read it before mentioning another answer.
Here is the proof of AUTO_INCREMENT:
I suspect this code has been migrated from the legacy mysql extension where mysql_connect():
Opens or reuses a connection to a MySQL server.
This is no longer the case with mysqli_connect():
Opens a connection to the MySQL Server.
You really need to store the connection in a variable and reuse that same connection. Currently you're starting many different connections within the same script run.
When you call mysqli_connect() it will create a new connection each time. It does not reuse the previous connection. When a new connection is created all the properties of the old one are lost.
You are calling mysqli_connect() every time you call $this->connect() so you will never get the errors or the auto-generated ID.
mysqli connection should be global to your application. It does not make sense to keep recreating the same connection because it will lead to terrible performance issues and it will cause you problems like this one. If you are using dependency injection it should be easy to create the mysqli at the start of your application and then pass it as an argument to your class' constructor.
Connecting to the database using mysqli is always the same 3 lines of code. Only the details you pass as arguments are different.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'pass', 'db_name');
$mysqli->set_charset('utf8mb4'); // always set the charset
You can then pass this to your constructor whenever you create an object and store it in a private property.
Your fixed code would like this:
<?php
class anything_i {
private mysqli $db = null;
public function connect(mysqli $db) {
$this->db = $db;
}
public function insertData($postData) {
/*
...
*/
$stmt = $this->db->prepare('INSERT INTO `payments`(`item_name`,`price`,`email`,`date`,`time`,`detail`,`volume`,`ip`,`payment_status`) VALUES (?,?,?,?,?,?,?,"On Hold")');
$stmt->bind_param('ssssssss', $productData['name'], $productData['price'], $postData['email'], $date, $time, $postData['list'], $productData['volume'], $ip);
$stmt->execute();
}
}
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'inet', '5432', 'test');
$mysqli->set_charset('utf8mb4'); // always set the charset
$obj = new anything_i($mysqli);

PHP Mysqli database connection pooling to avoid maximum user count

I surfed on Internet for past two days to create the DB pooling by PHP, but not yet achieved. I'm using PHP and MySQLi. We bought the mysqli db with 15 Maximum user connection. I want to pool the db connection to avoid the new connection. I used persistent as well as mysqli_connect. but I don't feel much different both are creating the new connection since other user already logged in. I was trying this function to get DB connection.
<?php
function getConnection(){
if ($connect){
return $connect;
}else{
$connect = new mysqli('p:xxxx','yyy','zzz','aaaa');
return $connect;
if(mysqli_connect_errno($connect))
{
echo "Server Busy";
}
}
}
?>
But above function only returns the else part. Please suggest me how to handle this. Thanks in advance. For now I'm killing the process which are in sleep mode to reduce the probability of increasing DB connection.
There is no connection pooling in PHP.
The persistent connection you are trying to use (that "p:" bit) is the most sure way to hit the maximum connection number, so get rid of it immediately.
15 concurrent connections is, actually, A LOT. Simply optimize your queries, so a typical connection would last 0.1 second, which would mean 150 concurrently executed PHP scripts which is like 1500 users on-line.
Also, you need to add
static $connect;
as the first line in your function, or is will create the new connection every time it is called, which is the actual reason why you are getting this error.
<?php
function getConnection(){
static $connect;
if (!$connect){
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$connect = new mysqli('xxxx','yyy','zzz','aaaa');
$connect->set_charset('utf8mb4');
}
return $connect;
}
Better yet, get rid of this function at all, have a separate file with the mysql connection code, and then use the $connect variable all around your code. See my article about mysqli connect for the details.
This is not how it works. See here. MySQLi will select one of available connections when you execute new mysqli('p:... The connection is persistent, not the PHP object.
function getConnection(){
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
return (new mysqli('p:xxxx','yyy','zzz','aaaa'));
}

How do I check the DB connection

I have host, database name, username and the password given as form inputs like:
$form['dbname']->getData()
I need to check if these data is correct for the mysql connection. So I chose to use mysql_connect() to check this:
$conn = mysql_connect($form['host']->getData(), $form['username']->getData(), $form['password']->getData(), $form['dbname']->getData());
if($conn) // ...
else // ...
But it displays some mysql_connect() warning with no other specific message...
What's wrong? Does the symfony 2 has any mechanism to check the connection?
Symfony uses repositories and entities to manage the database. The programmer doesn't manipulate the connection itself (Doctrine).
You could try to check a connection using PDO. Try to instance a PDO Object, and catch exceptions (PDOException for connection errors). However, you're "breaking" the framework's philosophy, trying to initiate an "extern" DB connection. If you need to work with several connections in Symfony, I suggest this reference :
http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html
use the following format to receive the connection error if there is any.
$con = mysql_query() or die(mysql_error());

Pass adodb connection to new php object

I'm trying to pass through an adodb connection to a class constructor but in doing so get this error:
mysql_error(): supplied argument is not a valid MySQL-Link resource
So to put it into context, I have instantiated a new adodb connection like this:
// establish database connection
$db = ADONewConnection($dsn);
if (!$db) die(mysql_error());
Then created my new user access object and passed in the adodb connection like this:
$user = new UserAccess($db);
This is the constructor from the user access class:
function UserAccess($oDbLink) {
// check we have a valid connection
}
Any ideas what I'm doing wrong?
Thanks,
Gaz
I can't see any obvious error in the part of code you supplied, so I'd suggest you:
leave aside the object for the time being
set your error_reporting() to E_ALL
double-check the parameters in $dsn - you may want to try to connect from the command line...
check your access privileges and run FLUSH PRIVILEGES
turn on ADODb debugging with $db->debug = TRUE;
test the thing from outside the object with a $db->Execute("SELECT * FROM tablename") or die($db->ErrorMsg());
When you get a message your connection resource is not a valid link - well, that's usually true. Don't forget to check the database is actually there and running.
The problem is most likely that you're attempting to use PHP's mysql_* functions with the $db object you get from ADONewConnection. It's not a mysql handle, so it won't work with those functions - you need to use adodb's own stuff.
Nothing wrong with your code, from what you've supplied. If you supply something more full then may be able to help.
Is there a real reason for passing a ADODB connection around? It'll just need to be passed everywhere and more work and without a real reason... I'd hesitate to do that. Even a standard global may be better (yes globals are evil) or perhaps a Singleton class?
Your code should be like this:
// establish database connection
$db = ADONewConnection($dsn);
if ( ! $db )
{
// just display error message
// you cannot use mysql_error, since you haven't connected to any database
die ("Cannot connect, check the parameter and make sure db is running!");
}
User reference, to avoid copying object
function UserAccess(&$oDbLink) {
// check we have a valid connection
}
Hope it help.
Thanks for your answers, I've managed to get this working by removing the $dsn variable and just passing in $_GLOBAL variables

how to enable database auto-reconnect in PHP? [closed]

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.

Categories