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
Related
Ok,
This is sort of an involved problem, but any help or advice would be incredibly appreciated.
So I'm working with a site that (using .htaccess) redirects all traffic to a load.php. For any sql functionality, I have an abstract class that has a lot of query statements as functions that pass parameters to define the specifics of each query.
e.g.
$table->update("constraints")
I'm trying to figure out how to set the connection to the database on load.php, and then set the connection as a variable ($mysqli) that can then be referenced in my abstract query class without having to pass the parameter to every single query function call.
Again, any help or advice would be appreciated.
Here's an example of a function:
function clearTable (){
$mysqli = dbConnect::connect();
$sql = "TRUNCATE TABLE $this->tablename";
$mysqli->query($sql);
}
If I connect to the database in a construct function and set $this->mysqli and replace $mysqli = dbConnect::connect(); with $mysqli = $this->mysqli, none of the queries work. Though they work with a fresh reconnect on each call.
You should use Dependency Injection for this.
Basically it means that the class that needs the database connection doesn't create the connection, it just receives the already instasiated instance.
Example
In some init file:
// Create the db connection
$db = new Mysqli(......);
// Pass it to the query class that needs it
$queryClass = new QueryClass($db);
Then in your class file:
class QueryClass
{
protected $db;
public function __construct($db)
{
// $this->db will now be the same Mysql instance
$this->db = $db;
}
public function doSomeQuery()
{
$this->db->query(....);
}
}
A bonus for this is that you don't need to touch the QueryClass, if you ever want to start making some unit tests. You only need to pass a DB connection to a test database instead.
After looking through this a bit more, I can also create my db::connect() function to look like this:
class dbConnect {
private static $db;
private $mysqli;
private function __construct() {
$this->mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
}
function __destruct() {
$this->mysqli->close();
}
public static function connect() {
if (self::$db == null) {
self::$db = new dbConnect();
}
return self::$db->mysqli;
}
}
and pass that as $this->mysqli in the query functions file
Please look at my databaseClass I Used a public property Called "connection" but I'm unable to access that property other .php files. I'm learning OOP PHP. Please help me.
Here is the other File link http://pastebin.com/0Nh1uc8D
<?php
require_once('config.php');//calling config.php
class Database{
public $connection;//property
//__construct();
public function __construct(){
$this->openDbConnection();
}
//method
public function openDbConnection(){
$this->connection = mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
if (mysqli_connect_errno()) {
# code...
die("Database Connection Failed Badly" . mysqli_error());
}else{
echo "DB Connected Successfully.";
}
}
}
//instance of the class
$database = new Database();
?>
Here is my confi.php file code
http://pastebin.com/wQ9BFGf4
Thanks in Advance.
For global access of classes and properties you can use it as static properties and methods:
class Database
{
public static $connection;//property
//method
public static function openDbConnection()
{
self::$connection = mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
if (mysqli_connect_errno()) {
# code...
die("Database Connection Failed Badly" . mysqli_error());
}else{
echo "DB Connected Successfully.";
}
}
}
// once "create" connection
Database::openDbConnection();
// and for all other files
var_dump(Database::$connection);
The problem is that $database isn't definied at all by line 16 adminContent.php, if that is indeed all the code for that file in Pastebin.
You're getting distracted by the public property scope, that's working fine as-is. Public properties are definitely accessible from other files not included in other function or class scopes, but only if you've actually required the file that instantiates the $database object in the first place.
Without showing us more code on how adminContent.php is being included from, we can't debug why $database isn't instantiated by line 16.
Use a debugger to trace the code execution flow, or just add echo's or error_log's to both the database instantiation file and to adminContent.php code and run it. I think you'll find that $database isn't instantiated at all, or at least before you're accessing it in adminContent.php
I have a PHP class with a few functions defined, this class is responsible for database access:
class database {
function open($params) {
// code here to open the db
}
function close() {
// code here to close the db
}
function count_users() {
// code here counts the number of user records
// Return -1 for testing
return -1;
}
function insert_user($user) {
// code here inserts a user record
}
function select_user($user_id) {
// code here selects a user record
}
}
I have accessor classes defined as follows:
require_once("database.php");
class user {
public $user_id;
public $email_address;
// etc, etc
}
class db_user {
static function select_user($user_id) {
$db = new database();
$db->open();
$user = NULL;
$result = $db->select_user($user_id);
// Test the result and decode user record into $user, etc
$db->close();
return $user;
}
static function count_users() {
$db = new database();
$db->open();
$count = $db->count_users();
$db->close();
return $count;
}
}
My issue occurs when I attempt to count the number of users through db_user::count_users(); which always fails with a Fatal Error: call to undefined method database::count_users
If I dump the database class methods using get_class_methods, I can see that the count_users function isn't present in the list but I have no idea why.
I'm very much a PHP n00b so there maybe something really obvious I'm not doing. My db_user and user classes have many other functions which pull data back through the database class and all of these succeed - just this one function.
Please help!
UPDATE
Ok, so, having removed a couple of functions from the database class and re-uploaded the file to the live server, it appears that it is somehow being "cached" as when I dump the methods belonging to the database object, the removed methods are still displayed in the list.
The count_users function is also not present in the method list yet when I inspect the file uploaded to the server, it is there in code.
Is there any way of removing this caching???
Try as follows:
class user extends database {
//code user class goes here
}
or
class user extends db_user {
//code user class goes here
}
simple problem solved.
You can store you instance of Database to the variable.
class db_user {
public static $db;
static function openDatabase(){
self::$db = new database();
self::$db->open();
}
static function select_user($user_id) {
$user = NULL;
$result = self::$db->select_user($user_id);
// Test the result and decode user record into $user, etc
self::$db->close();
return $user;
}
static function count_users() {
$count = $db->count_users();
self::$db->close();
return $count;
}
}
The issue, it would appear, is related to another version of the "database.php" file hiding in a sub-folder which must have been copied there by mistake.
Having removed this troublesome file, all now works as expected.
Thanks for your help.
Tried running your code in on-line phptester tool - first complained about missing $params in $db->open(), removing the argument (or passing the $params) it works fine on php 5.2,5.3,5.4. No complaints about count_users().
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).
I am trying to convert code from mysql to mysqli.
The code uses a single mysql_connect in a file which is included by every other file.
mysql_connect returns a MySQL link identifier that is a superglobal so you can rely on having a database connection available in any of your own functions.
It looks like with mysqli_connect this is not the case, the object returned isn't global.
Does this mean I have to add : global $mysqli; at the top of every function, or is there an way of making it a superglobal?
Relying on the fact that PHP will use the last opened connection resource if you don't specify one, is probably not a very good idea.
What happens if your application changes and you need two connections, or the connection is not there?
So it seems you need to do some refactoring anyway.
Here's a solution similar to Karsten's that always returns the same mysqli object.
class DB {
private static $mysqli;
private function __construct(){} //no instantiation
static function cxn() {
if( !self::$mysqli ) {
self::$mysqli = new mysqli(...);
}
return self::$mysqli;
}
}
//use
DB::cxn()->prepare(....
I usually make a function:
$mysqli = new mysqli(...);
function prepare($query) {
global $mysqli;
$stmt = $msqyli->prepare($query);
if ($mysqli->error()) {
// do something
}
return $stmt;
}
function doStuff() {
$stmt = prepare("SELECT id, name, description FROM blah");
// and so on
}
and then call that. That being said, I've since abandoned mysqli as being too bug-ridden to be considered usable. Shame really.
A very simple way to do this would be with a fixed database class, just to hold the mysqli connection object:
class Database {
public static $connection;
}
Database::$connection = new mysqli(HOST, USERNAME, PASSWORD, DATABASE);
Then you can access it in the normal ways:
$sql = 'SELECT * FROM table';
$result = Database::$connection->query($sql);
$result = mysqli_query(Database::$connection, $sql);
echo 'Server info ' . mysqli_get_server_info(Database::$connection);
To introduce some oop to you and solve your problem, you could use a class like this:
class MyDatabase
{
private static $_connection;
public static function connect()
{
$mysqli = new mysqli(...);
self::$_connection = $mysqli;
}
public static function getConnection()
{
return self::$_connection;
}
}
In your database-connection file you would load this class and execute MyDatabase::connect(); once.
To get the $mysqli-connection anywhere in your script, just call MyDatabase::getConnection();.