I am new to OOP having this code and am having a problem creating a database connection, what could be the problem? Strangely am not getting any errors yet i cannot make any MYSQL INSERTS or SELECTS from the database because the connections have not been made
//include the file that contains variables necessary for database connection
require_once 'configurations.php';
//This is the class that will be used for the MySQL Database transactions
class MySQLDatabase
{
private $database_connection;
//constructor class
function __construct()
{
$this->open_connection();
}
public function open_connection()
{
$this->database_connection = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD);
if (!$this->database_connection)
{
//if the connection fails, return the following message and indicate the error
die("Could not connect to the MYSQL Database due to: " . mysql_error());
}
else
{
//if the connection is made to MYSQL database, then select the database being used
$database_selection = mysql_select_db(DATABASE_NAME, $this->database_connection);
//if the database to be used cannot be selected, return this error
if (!$database_selection)
{
die ("Could not select the database due to: " . mysql_error());
}
}
}//end of function open database
}//end of class MySQLDatabase
$database_transactions = new MySQLDatabase();
There are a few things I would consider...
You write function __construct()
but all the other methods and
properties are either public or
private - use public function
__construct()
Why is the method open_connection()
public? Should it be called from
"outside"? Do you want someone
to execute this method directly
from an object? Think about making it private function open_connection() -> http://de.php.net/manual/en/language.oop5.visibility.php
Why use die() in OOP? Do you really
want to output the error message to
the user? It isn't secure to do that.
It's better to throw an Exception and work with try{} and catch{} to handle an error -> http://de.php.net/manual/en/language.exceptions.php
Are you really sure you're getting no error messages at all? Show use your query method... Your code should be fine so far (at least you should get an error on screen with die() if something is not correct).
Related
I have a weird issue in my mysql which is happening on a specific table !
I have a DB class as follows...
// Class: Database
class Database {
private $_connection;
private static $_instance; //The single instance
private $_error = '';
/*
SingleTon function to return DB Instance.
*/
public static function getInstance() {
if(!self::$_instance) { // If no instance then make one
self::$_instance = new self();
}
return self::$_instance;
}
// Constructor
private function __construct() {
global $db_host;
global $db_username;
global $db_password;
global $db_database;
$this->_connection = new mysqli($db_host, $db_username, $db_password, $db_database);
// Error handling
if(mysqli_connect_error()) {
$this->_error = "Failed to conencto to MySQL: " . mysql_connect_error();
}
}
// Get mysqli connection
public function getConnection() {
return $this->_connection;
}
}
?>
In my Other class where i need db action i do use following on constructor...
$db = Database::getInstance();
$this->mysql = $db->getConnection();
and following that i use $this->mysql->query("INSERT_QUERY") to insert the data. In the end i use $this->mysql->insert_id to see if the insertion has successfull returned id or not... In my execution of insertion i do get successfull auto incremented ID as output. But if i see DB through PHPMyAdmin tool the db is empty ! Even in select query also i do get nothing... but if i keep insert data i do get output of auto incremented value !
More over this happening in just one table. There are few other tables where i do the same insertion action and that does works normal !
All tables are on INNODB Engine.
Just to test i do delete that specific table but still i got same auto incremented value with out error message that table doesn't exist !!! but if i change the db name it throws me error which confirms that the connection points to the same DB.
This is really weird... does anyone faced similar problem ?
Check if you change the auto commit feature from your connection. maybe after closing your connection a rollback occurred.
$this->mysql->autocommit(true);
I have a PHP app that uses 2 different databases. The connection is realized by a singleton mysql class. What I would like to achieve is to use the same class but to connect to another database depending on a variable stated when calling the class.
So, the code used (but not yet functional):
/ start the single class
class Singleton {
// declare two private variables
private static $_instace;
private $conn;
var $dbc = 0;
// declare private constructor class
private function __construct() {
$this->conn = mysql_connect(HOST, USER, PASS);
//die('DB State: [' . $this->dbc . ']');
if ($this->dbc) {
mysql_select_db(DB_DATABASE_PS);
} else {
mysql_select_db(DBNAME);
}
}
// create a singleton method
public static function getconnect($dbc = false) {
if (!self::$_instace) {
self::$_instace = new Singleton();
$_instace->dbc = $dbc;
} else {
$_instace->dbc = $dbc;
}
return self::$_instace;
}
}
When calling a class that uses the first database (DBNAME), it all works perfect but when trying to use the second database, the code doesn't help me at all.
The code to load the second database inside a new class is made trough this code:
public function __construct() {
$this->connect = Singleton::getconnect(true);
}
Could someone help me figure it out?
Thank you!
The problem is, you're selecting the database during the construction of the object(in __construct() method) and it's completely based on the class member variable $dbc. So the next time you want to change the database, you have to call getconnect() method like this, Singleton::getconnect(true);, and then create another object to change the database, which would eventually defeat the purpose of singleton pattern. So basically, every time you change the database you have to call getconnect() method with true and false parameter alternatively, and create a new object to change the database.
Now comes down to your problem,
how should I use it (the singleton class) to change between the databases, keeping in mind that on a single page there could be data from both databases
Use the following code snippet to implement singleton pattern and change databases using a single object.
class Singleton {
// declare two private variables
private static $instance;
private $conn;
// Since it's constructor method is private
// it prevents objects from being created from
// outside of the class
private function __construct() {}
// It creates an object if not previously created,
// opens a connection to MySQL Server
// and returns the object
public static function getInstance() {
if(!isset(self::$instance)){
self::$instance = new Singleton();
self::$instance->conn = mysql_connect(HOST, USER, PASS);
}
return self::$instance;
}
// set your database here
public function setDatabase($db){
return mysql_select_db($db, $this->conn);
}
// Execute your query here
public function executeQuery($query){
return mysql_query($query, $this->conn);
}
// Close your connection here
public function closeConnection(){
mysql_close($this->conn);
}
}
// Get an instance of Singleton class
$obj = Singleton::getInstance();
// Set database "abc"
if($obj->setDatabase("abc")){
echo "database has changed <br />";
}else{
echo "database has not changed <br />";
}
// Display the selected database
$resultset = $obj->executeQuery("SELECT DATABASE() as db");
$row=mysql_fetch_assoc($resultset);
echo $row['db'] . "<br />";
// Set database "def"
if($obj->setDatabase("def")){
echo "database has changed <br />";
}else{
echo "database has not changed <br />";
}
// Display the selected database
$resultset = $obj->executeQuery("SELECT DATABASE() as db");
$row=mysql_fetch_assoc($resultset);
echo $row['db'] . "<br />";
// close connection
$obj->closeConnection();
Output:
database has changed
abc
database has changed
def
Sidenote: Please don't use mysql_ database extensions, they were deprecated in PHP 5.5.0 and were removed in PHP 7.0.0. Use mysqli or PDO extensions instead. And this is why you shouldn't use mysql_ functions.
i have a problem with PDO connection !
i read that i don't wanted to close PDO connection beacause will auto closed !
but if u want to close it manually i need to assign Null to connection variable .
but i use a data base class and the DB query run like this !
$addUser = users::getInstance()->userAdd($data);
and users class contain the following
class users extends DB {
private static $_instance = null;
public static function getInstance(){
if (!isset(self::$_instance)){
self::$_instance = new users();
}
return self::$_instance;
}
[...]
}
and Data base class
class DB {
private static $_instance = null;
private $_con;
[...]
public function __construct(){
try{
$this->_con = new PDO('mysql:host=localhost';dbname=db,user,pass);
}catch(PDOException $e){
die ($e->getMessage());
}
}
public function __destruct (){
$this->close();
}
public static function getInstance(){
if (!isset(self::$_instance)){
self::$_instance = new DB();
}
return self::$_instance;
}
public function close(){
$this->_con = null;
}
[...] }
the problem is that the script don't close the connections because when i limit max users connections in my localhost or use a free webhost service that already limit it i get this error message
SQLSTATE[HY000] [1203] User 'userName' already has more than 'max_user_connections' active connections
i need a solution to avoid this error message by closing connection while i using instance method in order to establish a connection !
Get rid of DB class.
Do not extend application class from DB class.
Do not play with static magic.
Create raw PDO object and pass it in application class
Forget about this connection stuff
So it goes:
$pdo = new PDO('mysql:host=localhost;dbname=db','user','pass');
$user = new users($pdo);
$user->select();
class users
{
protected $db;
function __construct($pdo){
$this->db = $pdo;
}
function select()
{
$this->db->query("select 1");
}
}
this way only one connection per script instance will be created and you will never face such an error again.
I am leaving this here as a reminder to me to think first before posting 'less than useful' answers. ;-/
Please use the answer provide by 'Your common sense' with the global, re-used connection.
do not read any further...
Stop throwing the unused connections away! Leave them active!
When you have finished with the 'connection' return it to a 'free list' array. do not destroy it
1) When you want a new database connection then check the 'free list'. Grab the top free one if available.
2) if no free ones available, create one and use it.
3) put it into the free list when you finish with it. Do not close it!
Implement the 'free list' as a 'stack'. I also kept a 'list of active connections'. when one completes just return it to the 'free list'.
This works a lot
You may run out of 'database handles' but you would need ten active overlapping active transactions.
I'm new. Below is the beginning of an attempt to interface with a database. Please let me know if the syntax is not correct, it seems to work on my localhost.
I think I could have typed class Database extends Mysqli, right? which would then have made the methods of Mysqli directly accessible to Database rather than through an instance created in the class itself. Would that have been preferable to what I have done?
class Database {
#The variable that stores the database handle
public $db;
#The Database objects's datbase parameters
public $host;
public $user;
public $password;
public $database;
#creates a Database object with the required databases details
public function __construct($host, $user, $password, $database) {
$this->host = $host;
$this->user = $user;
$this->password = $password;
$this->database = $database;
}
#Stores the database handle as a var $db of the Database instance
public function connect() {
if ($this->db = new Mysqli($this->host, $this->user, $this->password, $this->database)) {
if ($this->db->connect_errno) {
echo "No connection could be made <br/>";
} else {
echo "database succesfully connected <br/>";
}
}
}
}
If your class Database represents the database handle, then it should not have it public:
#The variable that stores the database handle
public $db;
Otherwise you would not encapsulate that detail and therefore you wouldn't need your class at all.
Next to that, when you start to write classes, echo does not belong in there:
if ($this->db = new Mysqli($this->host, $this->user, $this->password, $this->database)) {
if ($this->db->connect_errno) {
echo "No connection could be made <br/>";
} else {
echo "database succesfully connected <br/>";
}
}
Because classes consists of methods returning via their return value and not via standard output. Instead you want to throw an exception here. Which is also a feature of Mysqli already, therefore, you don't need to write that error handling code your own to get started:
Turning query errors to Exceptions in MySQLi
After getting these more or less obvious ones out of the way, you're asking yourself whether or not you should inherit mysqli instead of aggregating it.
I actually can not tell you. So far the code you've shared just shows standard functionality of a mysqli therefore I would suggest to drop that class completely as the code looks superfluous. So I would say: neither. I see no reason for your Database class as you just could use mysqli instead.
I'm trying to connect to 2 databases. One of them is a remote database. Once i connected to the remote database i had trouble with the one that existed, it gave me 'supplied argument is not valid ' on mysql_fetch_array() . So i changed my database class a bit and tried to make it work. But i still get errors :(. Its not grabbing $connection variable.
i get "undefined variable connection".
this is my connection class. Please help me out. Appreciate your help.
global $connection;
class Database{
function __construct()
{
$this->open_connection();
}
public function open_connection()
{
$connection = $this->connection= mysql_connect(SERVER,UNAME,PASSWORD);
if(!$this->connection)
{
return false;
}
if(!mysql_select_db(DB_NAME,$this->connection))
{
return false;
}
return true;
}
public function close_connection()
{
mysql_close($this->connection);
}
//open_connection();
}
$database = new Database();
and in another page:
$result=mysql_query($query,$connection);
while ($rec = mysql_fetch_array($result)) ... etc
p.s all constants and other variables are correct.
Using a global variable in a class is like death.
You could provide a class field for the connection link
$this->connection = mysql_connect(...);
And outside your class
$result = mysql_query($sql, $object->connection);
I'd also suggest you to use the existing mysqli class.
Hmm... Well, it looks like you are getting an undefined error thrown because you are calling global $connection at the top of the class file, and it hasn't been assigned a value.
It looks like you are establishing $connection inside of the open_connection() method... Are you establishing $connection in some included file that you haven't mentioned?
Try removing the first line of code, perhaps?
the "global $connection;" MUST be inside "open_connection" method or use #peipst9lker method