I have been using singleton design for PDO on my websites for years with PHP5. I am now migrating to PHP7 and I am seeing errors in my apache log file:
PHP Notice: Accessing static property Db::$PDOInstances as non static in /var/www/class/class_db_test.php on line 12
PHP Notice: Accessing static property Db::$PDOInstances as non static in /var/www/class/class_db_test.php on line 13
PHP Notice: Accessing static property Db::$PDOInstances as non static in /var/www/class/class_db_test.php on line 32
Here is my Singleton class for DB access:
<?php
require_once(dirname(__FILE__) . "/../setting.php");
class Db {
private static $debug = 1;
private static $debugPath = "/tmp/sql_debug.log";
private static $PDOInstances = array("db1"=>"","db2"=>"");
private function __construct($db_type){
switch($db_type) {
case "db1":
$this->PDOInstances[$db_type] = new PDO('mysql:dbname='.DB_NAME.';host='.DB_HOST,DB_USER ,DB_PWD,array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$this->PDOInstances[$db_type]->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
break;
case "db2":
$this->PDOInstances[$db_type] = new PDO('mysql:dbname='.DB2_NAME.';host='.DB2_HOST,DB2_USER ,DB2_PWD,array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$this->PDOInstances[$db_type]->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
break;
}
}
public static function getInstance($db_type) {
if(self::$debug == 1){self::sqlDebug("connection","");}
if(self::$PDOInstances[$db_type] == null){
self::$PDOInstances[$db_type] = new self($db_type);
}
return self::$PDOInstances[$db_type];
}
public function query($db_type,$query){
if(self::$debug == 1){self::sqlDebug("read request",$query);}
return $this->PDOInstances[$db_type]->query($query);
}
public function exec($db_type,$query){
if(self::$debug == 1){self::sqlDebug("request",$query);}
return $this->PDOInstances[$db_type]->exec($query);
}
public function lastInsertId($db_type){
return $this->PDOInstances[$db_type]->lastInsertId();
}
public function quote($db_type,$string){
if(self::$debug == 1){self::sqlDebug("quote",$string);}
return $this->PDOInstances[$db_type]->quote($string);
}
public static function sqlDebug($_mode,$_query){
$today = date("m.d.y-H:m:s");
if($_mode == "connection"){
$line = $today." Connection: '".$_query."'\r\n";
}
else if($_mode == "quote"){
$line = $today." Quote : '".$_query."'\r\n";
}
else if($_mode == "request"){
$line = $today." Request : '".$_query."'\r\n";
}
else if($_mode == "read request"){
$line = $today." Read request : '".$_query."'\r\n";
}
$file_debug = fopen(self::$debugPath, "a+");
fwrite($file_debug, $line);
fflush($file_debug);
fclose($file_debug);
}
}
?>
And my test code:
<?php
error_reporting(E_ALL);
require_once(dirname(__FILE__) . "/setting.php");
require_once(dirname(__FILE__) . "/class/class_db_test.php");
$con = Db::getInstance("db1");
$res = $con->query("db1","SELECT userId from user WHERE userName='test'");
if($res->rowCount() == 1){
$line = $res->fetchAll();
$res->closeCursor();
echo $line[0]['userId'];
}
else{
echo "0";
}
?>
When I change $this to self:: on line 12, 13 and 32, I get theses errors:
PHP Warning: Missing argument 2 for Db::query(), called in /var/www/class/class_db_test.php on line 32 and defined in /var/www/class/class_db_test.php on line 30
PHP Notice: Undefined variable: query in /var/www/class/class_db_test.php on line 31
PHP Notice: Undefined index: SELECT userId from user WHERE userName='test' in /var/www/class/class_db_test.php on line 32
PHP Fatal error: Uncaught Error: Call to a member function query() on null in /var/www/class/class_db_test.php:32\nStack trace:\n#0 /var/www/class/class_db_test.php(32): Db->query('SELECT userId f...')\n#1 /var/www/test.php(8): Db->query('db1', 'SELECT userId f...')\n#2 {main}\n thrown in /var/www/class/class_db_test.php on line 32
Do you have ideas on how to adapt my code in order make it work on PHP7 ?
Thank you