9

I have the following code and freshed this webpage in Firefox for 5 times, then the MySQL showed me 5 connections. According to the PDO Manual,

Persistent connections are not closed at the end of the script, but are cached and re-used when another script requests a connection using the same credentials. The persistent connection cache allows you to avoid the overhead of establishing a new connection every time a script needs to talk to a database, resulting in a faster web application.

I have used the same credentials, but the number of MYSQL connection keep increasing. Even trying to close connection with $db = null could not close the connections. What's wrong of my code?

<?php
try {
 $dbh = new PDO('mysql:host=127.0.0.1;dbname=lingtong', 'root', 'xxxxxx', array(PDO::ATTR_PERSISTENT => true));
 foreach ($dbh->query('SELECT * from agent') as $row) 
  print_r($row);
 $dbh = null;
} catch (PDOException $e) {
 print "Error! : " . $e->getMessage() . "<br/>";
 die();
}
Sebas
  • 21,192
  • 9
  • 55
  • 109
Jichao
  • 40,341
  • 47
  • 125
  • 198
  • 1
    What "did not work"? closing of the connection or removing the persistence? – bcosca Nov 13 '10 at 08:40
  • 1
    http://www.php.net/manual/en/pdo.connections.php Look at the last note. Is that can be the situation for you? – Halil Özgür Nov 13 '10 at 09:32
  • what is the method you had applied to get number of connection ? show processlist or ? – ajreal Nov 15 '10 at 15:43
  • Where actually are these connections **cached**??? That works even if you have no caching mechanism in place? – Felipe May 20 '11 at 23:19
  • it seems you need to close the cursor and assign null to the last statement object as well to close the connection – Sebas Dec 22 '16 at 16:27

3 Answers3

3

This question is very old but it will be okay if I contribute. I think you need to implement a singleton class for handling database connections I will write a sample class below ..

<?php
class DB{

//set the connection property to private to prevent direct access 
private static $conn;

//now since we dont want to reinstiate the class anytime we need it, lets also set the constructor to private 
private function __construct(){}

//now lets create our method for connecting to the database 
public static function connect(){

//now lets check if a connection exists already in our $conn property, then we should return it instead of recreating a new connection 
if(!empty(self::$conn)){
return self::$conn;
}//end if 

//upon reaching here means the $conn property is empty so lets create a new connection 

try {
 $dbh = new PDO('mysql:host=127.0.0.1;dbname=lingtong', 'root', 'xxxxxx', array(PDO::ATTR_PERSISTENT => true));

//lets now assign the database connection to our $conn property 
self::$conn = $dbh;

//return the connection 
return $dbh;

} catch (PDOException $e) {
 print "Error! : " . $e->getMessage() . "<br/>";
 die();
}

}//end method 

}//end class

?>

Our singleton class can make only one connection and reuse it,let see how we can use our class

<?php 
$dbh = DB::connect();

foreach ($dbh->query('SELECT * from agent') as $row){ 
  print_r($row);
}
?>
Big Zak
  • 1,040
  • 12
  • 17
  • 2
    So what did you contribute with? You just created a singleton without explaining why nor did you touch on the subject of persistent connection. What does your code help with? Do you know what persistent connections are, why they are used and how does singleton help with that? – Mjh Jul 20 '16 at 09:33
  • @Mjh I'm I mistaken or you downvoted the wrong answer? – Jonatan Cloutier Aug 10 '16 at 19:20
  • 1
    @Mjh I know what persistent connection is ,besides I added persistent support to the class, and more over , persistent connection and singleton class all aims at scalability , we are here to help each other with whats best and what might help others , again , the codes has been explained , thats i commented the codes, Thank you – Big Zak Aug 11 '16 at 09:43
  • @JonatanCloutier - I didn't downvote the wrong answer. I downvoted yours because you don't know what persistent connection is, you assumed OP is using Apache and you provided a wrong answer. No offense meant. – Mjh Aug 11 '16 at 09:45
  • @razzbee - you implemented a singleton for handling database connection in the app. You didn't explain **why** it solves the problem that OP has. You didn't mention what a persistent connection is and how your class helps with the problem. I didn't vote on your answer because it's incomplete. Dropping some code without explaining **why** it's useful isn't really helpful, is it? – Mjh Aug 11 '16 at 09:47
  • @Mjh , I get your point .. will do my best to explain my codes next time, besides I thought the comments would help – Big Zak Aug 11 '16 at 11:28
  • Just update the answer with explanation and that's it, it's not a bad answer in itself :) – Mjh Aug 11 '16 at 12:09
  • Regardless of whether this answered OPs answer I found this useful, thank you. – Eric Apr 21 '17 at 01:53
  • 2
    I've been scouring other Stack Overflow answers and this is the best PDO class that I've found. I disagree with others above that it is lacking in explanation. The comments in the code are clear. I found it very helpful. – Derrick Miller Oct 11 '17 at 19:31
  • Surely if it's using persistent connections, it won't need a singleton. You could call the DB connect as many times as you like, it should attempt to connect or fail just like a non-persistent but without the overhead – MrMesees Mar 24 '18 at 17:11
1

It seems you need to close the cursor and release (assign null) to the last pdo statement object as well to close the connection.

Also, what's important to understand about persistent connections is that they persist, but you are not guaranteed that you will neither:

  • Be given back your last connection handler in further script executions
  • Nor be reusing a previous connection, if it's still "busy". Busy may mean in a script, timing out etc... Connections instanciation may go on and on... See Fully Understanding PDO ATTR_PERSISTENT
Community
  • 1
  • 1
Sebas
  • 21,192
  • 9
  • 55
  • 109
-1

From what I know from persistent connection you probably doesn't need it:

  1. you are on localhost so the connection is very fast and you wont save a lot from caching of your connection
  2. because of the underlying principal of Apache you have many thread that answer the client request and because of these multi-threading the connection is persistent in a single thread, not shared on all of them so you will see your number of connection go up in mysql until it's reach the ThreadLimit of apache
  3. there is a few risk that persistent connection cause problem to your app in the kind of dbLock or tableLock

Now you might wanna do a bit more research about persistent connections if you still think that you really need it

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Jonatan Cloutier
  • 899
  • 9
  • 26
  • 2
    Reasons for downvote: it's not relevant if someone is on localhost or not. Non-persistent connections spend file descriptors. Non-persistent connections initiate the connection handshake on every http request. 2) Apache or nginx persist the connection per thread and they perform the handshake once - that means every subsequent request **won't** have to go through this overhead. That's what you **want**. The reason why connections go up is because Apache is a really badly written piece of software that can't clean up properly. 3) WTF?! You just dropped random statement with 0 facts. – Mjh Aug 11 '16 at 09:50
  • @Mjh thanks, at least I can understand why it's downvoted, while I couldn't without comment – Jonatan Cloutier Aug 11 '16 at 15:10
  • 1
    The answer can be improved and edited, in which case you will have my upvote, and I suggest you add a few extra bits of information to it. The problem is that nothing is black and white, persistent connections have their use, non-persistent ones do as well. Persistent connections are best used with `php-fpm`, while non-persistent should be used with Apache and `mod_php` because Apache tends to screw up otherwise. FastCGI applications such as `php-fpm` are fast(er) because of persistent connections, not only towards MySQL. – Mjh Aug 11 '16 at 15:11
  • I just have to refresh my mind, I haven't work at this level for a few years. In the mean time for people searching this subject, this express the main part of my answer http://stackoverflow.com/questions/50303/persistent-db-connections-yea-or-nay – Jonatan Cloutier Aug 11 '16 at 15:15
  • 2
    Well that answer is 8 years old now, and it's not even correct. People usually read what they want to be true and upvote, without taking facts into account. Nowadays, applications are built much better and with more forward-thinking in mind. If you are going for a fast application, you'll use a persistent connection because it's always quicker to connect once instead of connect/disconnect upon every request (that actually really rapes the db and kills performance). – Mjh Aug 11 '16 at 15:19
  • well this one was 4 years old – Jonatan Cloutier Aug 11 '16 at 21:43