This question already has answers here:
Synchronized functions in PHP
(6 answers)
Closed 9 years ago.
I've got a php application that requires to make a connection to a server which authenticates with a token, this token stays valid until connection is lost.
When another connection is made while the first is still open my application crashes because the token is different from the currently connected one...
public function connect()
{
$Socket = fsockopen("192.168.1.1", 1234);
if ($Socket !== false) {
stream_set_timeout($Socket, static::TIMEOUT_SEC, static::TIMEOUT_USEC);
$this->socket = $Socket;
$this->sendeverything;
}
}
How am I able to run a function like:
function gogogo() {
connect();
}
multiple times without having them running simultaneously
Sorry for my bad english
Most easy solution would be to have a is_connected function:
function connect() {
if(is_already_connected()) {
return;
}
// ... your connect logic
}
In the is_already_connected() you'll have to write some intelligent code to determine if there is an open connection.
You can also create a kind of singleton connection (although this suggestion would probably instantiate a lot of debate about the use of singletons ;))
Try something like this...
<?php
class Connection {
public $Socket = null;
public function connect(){
// Checking if Socket already has a pointer :P
if((bool)$this->Socket){
return true;
}
$this->Socket = fsockopen("192.168.1.1", 1234);
if ($this->Socket !== false) {
stream_set_timeout($this->Socket, static::TIMEOUT_SEC, static::TIMEOUT_USEC);
$this->sendeverything();
}
}
}
$myconnect = new Connection();
$myconnect->connect();
$myconnect->connect();
?>
As mentioned in this question you can use sem_aquire for this. Something like:
function connect(){
$key = "192.168.1.1:1234" ;
try{
$sem = sem_get( $SEMKey);
sem_acquire($sem);
//Do connecty stuff here
sem_release($sem);
}catch(Exception $ex){
//Exception handling
}finally{
//Finally only available in PHP 5.5 place this in catch and try if < 5.5
sem_release($sem);
}
}
Note that this is entirely untested and wont work on windows. If you are on windows you can use flock - again as mentioned in the above question.
Related
I am using PHP 7.2 on a website hosted on Amazon. I have a code similar to this one that writes a record in the MongoDB:
Database connection class:
class Database {
private static $instance;
private $managerMongoDB;
private function __construct() {
#Singleton private constructor
}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new Database();
}
return self::$instance;
}
function writeMongo($collection, $record) {
if (empty($this->managerMongoDB)) {
$this->managerMongoDB = new MongoDB\Driver\Manager(DB_MONGO_HOST ? DB_MONGO_HOST : null);
}
$writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000);
$bulk = new MongoDB\Driver\BulkWrite();
$bulk->insert($record);
try {
$result = $this->managerMongoDB->executeBulkWrite(
DB_MONGO_NAME . '.' . $collection, $bulk, $writeConcern
);
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
// Not important
} catch (MongoDB\Driver\Exception\Exception $e) {
// Not important
}
return $result->getInsertedCount() > 0;
}
}
Execution:
Database::getInstance()->writeMongo($tableName, $dataForMongo);
The script is working as intended and the records are added in MongoDB.
The problem is that connections are not being closed at all and once there are 500 inserts (500 is the limit of connections in MongoDB on our server) it stops working. If we restart php-fpm the connections are also reset and we can insert 500 more records.
The connection is reused during the request, but we have requests coming from 100s of actual customers.
As far as I can see there is no way to manually close the connections. Is there something I'm doing wrong? Is there some configuration that needs to be done on the driver? I tried setting socketTimeoutMS=1000&wTimeoutMS=1000&connectTimeoutMS=1000 in the connection string but the connections keep staying alive.
You are creating a client instance every time the function is invoked, and never closing it, which would produce the behavior you are seeing.
If you want to create the client instance in the function, close it in the same function.
Alternatively create the client instance once for the entire script and use the same instance in all of the operations done by that script.
This question already has answers here:
MYSQLi error: User already has more than 'max_user_connections' active connections [duplicate]
(6 answers)
Closed 3 years ago.
public function getActiveUsers(){
$result = $this->con->query("SELECT * FROM `USERS` where `IsActive`=1");
$users = array();
while ($item = $result->fetch_assoc()) {
$users[] = $item;
}
return $users;
}//End Function
This is my PHP Function I am using to get active users from my DB (of my dashboard). Most of the other functions are written like this. They are written in a single PHP file (db-function.php). But first I defined the connection in a file called DB-Connet.php.
public function connect()
{
require_once 'source/config/config.php';
$this->con = new mysqli(DB_HOST,DB_USER,DB_PASSWORD,DB_DATABASE);
return $this->con;
}
And then created the connection in the construct of DbConnet class in db-function.php.
function __construct()
{
require_once 'DB-Connet.php';
$db = new DbConnect();
$this->con = $db->connect();
}
But when I try to visit the dashboard url It Displays a msg like this,
User adimn_user already has more than 'max_user_connections' active connections in ..../db-function.php on line 16.
What am I doing wrong? (My English is Bad. I am sorry. Edits are Wellcome. Thank you all.)
P.S : Is it okay if I close the connection in _destruct function of db-connect.php like this?
function __destruct() {
$this->con->close();
}
Always close the mysql connection if you do not need it. It saves memory and free up connection for next possible requests that might hit the Database.
This question already has answers here:
How do I parse object data from MySQL database using PHP PDO?
(1 answer)
PHP/PDO - use variable assignment as fetch-statement
(4 answers)
Closed 5 years ago.
After 10 years away from PHP coding, am getting back in the swing of things going through tutorials. I discovered things have changed, and PDO is the new standard to connect to MySQL.
I set up small projects. I am trying to build my own Class database, and things get all sideways, and I don't figure out why.
So here is my database class:
<?PHP
$Db = new database;
class database
{
/////////////
//Attributs//
/////////////
private $db_host;
private $db_user;
private $db_pass;
private $db_name;
private $bdd;
/////////////////////
// internal process//
/////////////////////
private function activateDB()
{
$this->checkList();
$this->dbInitilisation();
$this->dbConnection();
}
////////////////////////
//Check Websiteconfig//
////////////////////////
private function checkList()
{
if(!file_exists('website-config.ini')){
die('missing configuration file.');
}
}
///////////
//Db init//
///////////
private function dbInitilisation()
{
// Load config file for database connection info
$config = parse_ini_file("website-config.ini");
$this->db_host=$config['db_host'];
$this->db_user=$config['db_login'];
$this->db_pass=$config['db_password'];
$this->db_name=$config['db_name'];
}
/////////////////
//Db connection//
/////////////////
private function dbConnection()
{
try
{
$this->bdd = new PDO('mysql:host='.$this->db_host.';dbname='.$this->db_name.';charset=utf8', 'root', '');
$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (Exception $e)
{
die('error '.$e);
}
}
public function dbQuery($user_query, $parameters)
{
$this->activateDB();
$query = $this->bdd->prepare($user_query);
$query->execute($parameters);
$query->fetch();
return $query;
}
}
?>
and, here is how I am calling it:
$values[':user_id']='1';
$result=($Db->dbQuery('SELECT user_username FROM user WHERE user_id = :user_id',$values));
print_r($result);
When I was not using pdo, and writing my function like normal, I had what I wanted. Now, not any more.
Does anyone has a clue on what I am doing wrong? Do you have any kind of comment on how to improve my overall stuff?
PS: I did read around before coming here (like here: http://php.net/manual/fr/pdostatement.fetch.php (I thought my issue were maybe with the type of fetch, but again, when not in OOP, my code runs ok as it is.) Or here PHP: Database Connection Class Constructor Method but the solution give here is to go on someone else code library, and not allowing to understand what I am actually doing wrong.
I've got a class that is pulling and aggregating data from a Mongo DB. This is all working fine...I have multiple queries being run for a connection under the same connection (in the same class). However, every time I refresh the page, a new connection is opened...I can see this in my mongod output:
[initandlisten] connection accepted from 127.0.0.1:46770 #12 (6 connections now open)
I see this count up and up with every page refresh. This should be fine, I think; however, the connections never seem to close.
After a while, the connections / locks take up too much memory in Mongo, and I can no longer run the queries.
This dev environment is on a 32-bit version of Mongo, so I don't know if this is only happening because of that. (Our prod env is 64-bit, and I cannot change the dev env right now.)
My question is: Should I be closing the connection after all the queries have been made for a particular user? How should I be handling the connection pool?
The service class:
class MongoService{
protected $mongoServer;
public function setSpokenlayerMongoServer($mongoServer)
{ $this->mongoServer = $mongoServer; }
protected $mongoUser;
public function setSpokenlayerMongoUser($mongoUser)
{ $this->mongoUser = $mongoUser; }
protected $mongoPassword;
public function setSpokenlayerMongoPassword($mongoPassword)
{ $this->mongoPassword = $mongoPassword; }
protected $conn;
public function setServiceConnection($conn)
{ $this->conn = $conn; }
public function connect(){
try {
$this->conn = $this->getMongoClient();
} catch(Exception $e) {
/* Can't connect to MongoDB! */
// logException($e);
die("Can't do anything :(");
}
}
public function getDatabase($name){
if(!isset($this->conn)){
$this->connect();
}
return $this->conn->$name;
}
protected function getMongoClient($retry = 3) {
$connectString= "mongodb://".$this->mongoUser.":".$this->mongoPassword."#". $this->mongoServer."";
try {
return new MongoClient($connectString);
} catch(Exception $e) {
/* Log the exception so we can look into why mongod failed later */
// logException($e);
}
if ($retry > 0) {
return $this->getMongoClient(--$retry);
}
throw new Exception("I've tried several times getting MongoClient.. Is mongod really running?");
}
}
And in the service class where the queries are:
protected function collection(){
if(!isset($this->collection)){
$this->collection = $this->db()->selectCollection($this->collectionName);
}
return $this->collection;
}
And then a query is done like so:
$results = $this->collection()->aggregate($ops);
Is this correct behavior?
Known issue if you're using Azure IaaS, possible issue on other platforms.
One option would be to change the Mongo configuration:
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(5);
This would kill all idle connections after 5 minutes.
This question already has an answer here:
PHP: mysql_connect not returning FALSE
(1 answer)
Closed 8 years ago.
I'm very new to OOP and am trying to learn it. So please excuse my noobness. I'm trying to connect to mysql and to test whether the connection is successful or not, I'm using if-else conditions.
Surprisingly, the mysql_connect is always returning true even on passing wrong login credentials. Now I'm trying to figure out why it does and after spending about 20 minutes, I gave up. Hence, I came here to seek the help of the community. Here is my code:
class test
{
private $host = 'localhost';
private $username = 'root2'; // using wrong username on purpose
private $password = '';
private $db = 'dummy';
private $myConn;
public function __construct()
{
$conn = mysql_connect($this->host, $this->username, $this->password);
if(!$conn)
{
die('Connection failed'); // this doesn't execute
}
else
{
$this->myConn = $conn;
$dbhandle = mysql_select_db($this->db, $this->myConn);
if(! $dbhandle)
{
die('Connection successful, but database not found'); // but this gets printed instead
}
}
}
}
$test = new test();
Please don't use the mysql_* functions, there are many, many reasons why - which are well documented online. They are also deprecated and due to be removed.
You'd be much better off using PDO!
Also I'd strongly advise abstracting this database code into a dedicated database class, which can be injected where necessary.
On-topic:
That code snippet seems to work for me, have you tried var_dumping $conn? Does that user have correct rights?
I also hope that you don't have a production server which allows root login without a password!
Ignoring the fact that you're using mysql_* functions rather than mysqli or pdo functions, you should utilise exceptions in OOP code rather than die(). Other than that, I can't replicate your problem - it may be that your mysql server is set up to accept passwordless logins.
class test
{
private $host = 'localhost';
private $username = 'root2'; // using wrong username on purpose
private $password = '';
private $db = 'dummy';
private $myConn;
public function __construct()
{
// returns false on failure
$conn = mysql_connect($this->host, $this->username, $this->password);
if(!$conn)
{
throw new RuntimeException('Connection failed'); // this doesn't execute
}
else
{
$this->myConn = $conn;
$dbhandle = mysql_select_db($this->db, $this->myConn);
if (!$dbhandle)
{
throw new RuntimeException('Connection successful, but database not found'); // but this gets printed instead
}
}
}
}
try {
$test = new test();
} catch (RuntimeException $ex) {
die($ex->getMessage());
}