I've been searching stack to get my answer, but nothing fixed my problem. So here's my shot:
$conn = mysqli_connect('localhost', 'username', 'pass', 'db');
function GetArticle() {
global $conn;
$sql = "sql query";
$getresult = mysqli_query($conn, $sql);
..
}
This doesn't seem to work. If I put $conn inside the function, it works fine.
Any ideas?
I don't know your exact situation, but in general I do not see the benefit to using $conn as global. Your function depends on a mysqli connection in order to work, so just make the connection a function parameter.
function GetArticle($conn) {
$sql = "sql query";
$getresult = mysqli_query($conn, $sql);
..
}
Then after you have established your connection, you can call the function with your connection object as its argument.
$conn = mysqli_connect('localhost', 'username', 'pass', 'db');
$article = GetArticle($conn);
I think this is a more manageable approach than trying to keep track of whether $conn is available in global scope before calling the function.
Related
Make other functions access the $conn variable inside my database connection function
So here I am absolutely desperate trying to make something work. I know what im trying to do is not OOP neither 100% best practice. It is not for a live website, I am just learning some basic PHP concepts on XAMPP.
What I am trying to do is to make the $conn variable inside my database connection function accessible to all other functions that need it. I am thinking of passing it as a parameter, but how can this be done? I prefer not using PHP's "global" or $GLOBALS. My method of working right now is with mysqli using procedural methods.
For example I have something like this:
function db () {
$conn = mysqli_connect ("localhost", "root", "", "database");
}
function someFunction () {
$result = mysqli_query ($conn, "SELECT * FROM examples)
}
I never found the answer to my issue...most solutions which I recently got familiar with are OOP based or use somewhat questionable methods.
------------------------------------------------------------------------------------------------------------------------------------
SOLUTION A - I would rather avoid not having my connection in a wrapper and using global variables:
global $conn = mysqli_connect ("localhost", "root", "", "database");
global $conn;
function someFunction () {
global $conn;
$result = mysqli_query ($conn, "SELECT * FROM examples)
}
SOLUTION B - I am not ready for OOP yet but I know this works. The point is I want to learn something different:
class Database
{
private static $conn;
public static function getObject()
{
if (!self::$conn)
self::$conn = new mysqli("localhost", "root", "", "database");
return self::$conn;
}
}
function someFunction () {
$result = mysqli_query (Database::$conn, "SELECT * FROM examples)
}
SOLUTION C - Not using functions at all...just keeping it unwrapped which I dont find very practical in the long term:
$conn = mysqli_connect ("localhost", "root", "", "database");
$result = mysqli_query ($conn, "SELECT * FROM examples)
------------------------------------------------------------------------------------------------------------------------------------
THE SOLUTION I AM TRYING TO ACHIEVE:
function db () {
$conn = mysqli_connect ("localhost", "root", "", "database");
return $conn;
}
function someFunction () {
$conn = db ();
$result = mysqli_query ($conn, "SELECT * FROM examples)
}
OR Something like this where I just pass in the connection as a parameter or something (pseudo code at the moment)
function db () {
$conn = mysqli_connect ("localhost", "root", "", "database");
}
function someFunction ($conn) {
$result = mysqli_query ($conn, "SELECT * FROM examples)
}
------------------------------------------------------------------------------------------------------------------------------------
So how do I achieve something like the last two but which actually works. Is this concept possible?
Your Desired Solution: This should work, and you'll only make one connection.
function db () {
static $conn;
if ($conn===NULL){
$conn = mysqli_connect ("localhost", "root", "", "database");
}
return $conn;
}
function someFunction () {
$conn = db();
$result = mysqli_query ($conn, "SELECT * FROM examples);
}
If you used the function someFunction($conn), that would make your code much messier, since you wouldn't actually have universal access to $conn from anywhere.
You should go with Solution B IMO. That way, you can have simple access to it Database::$conn which will be consistent throughout your script. You could should have an initialize function (you could use a different name if you want) that will initialize Database::$conn, and you can then use that to initialize other things on the Database class later, if desired.
Solution A is terrible. I did that for a long time (globalizing things), and it was a horrible idea. I should have never done that. But I did. And I learned. It just made code get progressively sloppier and sloppier.
Solution B: Database::$conn should be public if you want to be able to access it by Database::$conn from anywhere. If it's private, then you would always need to call Database::getObject();
Solution C: You're right. That would be very impractical.
Solution B rewrite:
class Database
{
/** TRUE if static variables have been initialized. FALSE otherwise
*/
private static $init = FALSE;
/** The mysqli connection object
*/
public static $conn;
/** initializes the static class variables. Only runs initialization once.
* does not return anything.
*/
public static function initialize()
{
if (self::$init===TRUE)return;
self::$init = TRUE;
self::$conn = new mysqli("localhost", "root", "", "database");
}
}
Then... call Database::initialize() at least once before it gets used.
<?php
Database::initialize();
$result = mysqli_query (Database::$conn, "SELECT * FROM examples);
?>
EDIT
You can also call Database::initialize() immediately after the declaration of the class, in that PHP file. Then initializing is handled.
I'm now far more fond of something like Database::getDb() than accessing the $conn property directly. Then initialize can be called from the getDb() function. Basically like the Desired Solution but inside a class. The class really isn't necessary, but it can be nice if you like classes, like I do.
All of the answers in this section are overkill as they are doing overhead just by creating a wrapper around a database object.
For separation of concern(Maintainability) use a separate PHP file for database connection and use require_once.
//Inside Database_Connect.php
$db = mysqi_connect(localhost, database, password);
Now use $GLOBALS['db'] inside your mysqli_ functions wherever needed.
OR, initialize your script / object as
$dbConn = $GLOBALS['db'];
and use $dbConn inside your mysqli_ functions wherever needed.
simple answer just pass your $conn variable into another calling function(instead of making new connection)
like
yourpage.php
$conn = new mysqli($servername, $username, $password, $dbname);
someFunction ($conn)//you can add other parameters if you like
function someFunction ($conn) {
$result = mysqli_query ($conn, "SELECT * FROM examples);
}
Note:This is not good practice to always make new connection for database access.so always make connection once and use it every where.(but if your requirement different and require multiples connections then you can make multiples connections)
Pass an argument to your function like and return the connection
function db($conn){
$conn = mysqli_connect ("localhost", "root", "", "database");
return $conn;
}
If you have multiple php files which require db access, then the option you can have is create a file connection.php with connection code
<?php
$conn = mysqli_connect ("localhost", "root", "", "database");
?>
And use include_once 'connection.php'; in all other files you require a connection.
I'm in the process of upgrading from mysql to mysqli.
All my mysql code was procedural, and I'd now like to convert to OOP, as most mysqli examples online are in OOP.
The problem I'm having is that, with mysql, once I had set up a connection, I never had to inject that connection into any functions as arguments for mysql to be accessible in the function.
Here is my old connection code:
$location = "localhost";
$user = "rogerRamjet";
$pass = "bestPassInTheWorld";
$dbName = "myDBName";
$link = mysql_connect($location, $user, $pass);
if (!$link) {
die("Could not connect to the database.");
}
mysql_select_db("$dbName") or die ("no database");
And an example function that has access to the mysql connection, without $link needing to be injected into the function:
function getUser($data)
{
$data=mysql_real_escape_string($data);
$error = array('status'=>false,'userID'=>-1);
$query = "SELECT `user_id`, `user_email` FROM `myTable` WHERE `data`='$data'";
if ($result = mysql_query($query))
{
$row = mysql_fetch_array($result, MYSQL_ASSOC);
if ($row['user_id']!="")
{
return array( 'status'=>true, 'userID'=>$row['user_id'], 'email'=>$row['user_email'] );
}
else return $error;
}
else return $error;
}
And here's my new mysqli connection:
$mysqli=new MySQLi($location, $user, $pass, $dbName);
So, to upgrade the first line in the above function, I'd need:
$data = $mysqli->real_escape_string($data);
But that throws the error:
Undefined variable: mysqli
Does this mean that for any function needing access to $mysqli, I need to inject $mysqli as an argument into it, or is there a way for it to be accessible the way mysql is without injection?
I know I need to move to prepared statements, but this is just so I can get my head around mysqli basics.
Making the variable global is bad practice. The singleton pattern solves the issue of needing to share one instance of an object throughout an application lifecycle. Consider using a Singleton.
The crude solution would be global $mysqli; as first line of your function. But as hsan wrote, read about PHP variable scope
Guys this is a code i have written. I have two files.
File one.
$regname=$_POST['name']; -----> here the variable passed is john suppose..
$sponserid=$_POST['sname'];
$regemail=$_POST['email'];
$regmobile=$_POST['mobile'];
include 'dbcon.php';
$obj = new dbcon;
$obj->createUser($regname,$sponserid,$regemail,$regmobile);
echo $obj;
in the above code i am getting variables from a form a and storing them. Then I instantiate an object and pass all those to a method.
My class code id like this.
class dbcon
{
public function __construct() //This is the connection construct.
{
$server = "localhost";
$user = "eplu";
$pass = "123456"; //Change on hosting server
$db = "epl";
mysql_connect($server, $user, $pass) or die("Error connecting to sql server: ".mysql_error());
mysql_select_db($db);
}
public function createUser($regname,$sponserid,$regemail,$regmobile){
$sql = "INSERT INTO onlinereg (names,sid,emails,mobiles) VALUES (`$regname`,`$sponserid`,`$regemail`,`$regmobile`)";
mysql_query($sql) or die(mysql_error());
return "Registration Success";
}
}
I get an error like Unknown column 'john' in 'field list'. New to OOPS pls help...Thnx in advance.....
Try now. This is not an OOPS related error, just the database thing.
class dbcon
{
public function __construct() //This is the connection construct.
{
$server = "localhost";
$user = "eplu";
$pass = "123456"; //Change on hosting server
$db = "epl";
mysql_connect($server, $user, $pass) or die("Error connecting to sql server: ".mysql_error());
mysql_select_db($db);
}
public function createUser($regname,$sponserid,$regemail,$regmobile){
$sql = "INSERT INTO onlinereg (names,sid,emails,mobiles) VALUES ('$regname','$sponserid','$regemail','$regmobile')";
mysql_query($sql) or die(mysql_error());
return "Registration Success";
}
}
Its because you are using backticks in your SQL query values. You need to use apostrophes instead of backticks, else the query will think you are referencing another column, in this case, 'john'
Change:
INSERT INTO onlinereg (names,sid,emails,mobiles) VALUES (`$regname`,`$sponserid`,`$regemail`,`$regmobile`)
to:
INSERT INTO onlinereg (names,sid,emails,mobiles) VALUES ('$regname','$sponserid','$regemail','$regmobile')
Simple change
`name`
to 'name'
You are using wrong quotes. This question is not really related to OOP
I am trying to pass an mysqli database connection to a php class. The code I have so far (cut down for simplicity) is as follows:
db.php
$db_host = 'localhost';
$db_name = 'dbname';
$db_user = 'username';
$db_password = 'password';
$db = array('db_host'=>$db_host,
'db_name'=>$db_name,
'db_user'=>$db_user,
'db_password'=>$db_password);
$dbCon = new mysqli( $db['db_host'],
$db['db_user'],
$db['db_password'],
$db['db_name']);
if (mysqli_connect_errno())
{
die(mysqli_connect_error()); //There was an error. Print it out and die
}
index.php
<?php
require_once($_SERVER["DOCUMENT_ROOT"] . "/db.php");
$sql = "SELECT id FROM usr_clients";
$stmt = $dbCon->prepare( $sql );
if ($stmt)
{
$stmt->execute();
$stmt->bind_result($id);
while($stmt->fetch())
{
$cl = new Client($id, $dbCon);
$cl->doIt();
}
$stmt->close();
}
?>
client.php
<?php
Class Client
{
private $con;
public static $clientCount = 0;
public function __construct( $id, $con )
{
$this->con = $con;
$sql = "SELECT id FROM usr_clients WHERE id = $id";
$stmt = $this->con->prepare( $sql );
if ($stmt)
{
echo "it worked!";
}
else
{
echo "it failed";
}
}
}
?>
Now the index.php page successfully recognises the database connection declared in db.php, and returns a list of all clients. It then loops through each client, and creates a "client" object, passing it the database connection.
It is here that the problem seems to start. In the client class, the database connection is not recognised. I get multiple errors on the page saying "it failed". In the logs, there is a line about calling prepare() on a non object.
Can anyone explain why the connection works in index.php, but not in the client class?
Thanks
Your main problem is assumptions.
You are assuming that there is no connection passed, judging by indirect consequence.
But a programmer should be always logically correct in their reasoning.
Talking of connection? Verify the very connection. var_dump($con) in the constructor. var_dump($this->con) in the method. If it fails - only now you can blame connection and start for the solution.
If not - there is no reason in looking for another connection passing method. Yet it's time to find the real problem.
If your query fails, you have to ask mysql, what's going on, using $this->con->error, as this function will provide you with a lot more useful information than simple "it fails". The right usage I've explained here: https://stackoverflow.com/a/15447204/285587
How do I allow a function to access a database connection without using GLOBAL?
config.php
DEFINE ('DB_HOSTNAME', 'hostname');
DEFINE ('DB_DATABASE', 'database');
DEFINE ('DB_USERNAME', 'username');
DEFINE ('DB_PASSWORD', 'password');
$dbc = mysqli_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
if(!$dbc) die("Unable to connect to MySQL: " . mysqli_error($dbc));
functions.php
function something()
{
$info = mysqli_query($dbc, "SELECT info FROM text") or die("Error: ".mysqli_error($dbc));
}
The above gives me the following error:
mysqli_query() expects parameter 1 to be mysqli, null given in
Use function parameters
function something ($dbc) {
// your db code here
}
function arguments
Either pass the database handle to your function, as #KingCrunch and others have said, or call a function that returns the handle:
In config.php:
function get_dbc() {
$dbc = mysqli_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
if(!$dbc) die("Unable to connect to MySQL: " . mysqli_error($dbc));
return $dbc;
}
In functions.php:
require_once('config.php');
function something()
{
$dbc = get_dbc();
$info = mysqli_query($dbc, "SELECT info FROM text") or die("Error: ".mysqli_error($dbc));
}
You may wish to look at The mysqli Extension and Persistent Connections for details on how you can prevent the connection from being re-established on each call to get_dbc(). There are alternative approaches to this, such as creating a singleton class for your database connection.
There are two ways one is by passing arguments and the other by using function closure like #Ondrej said. But I wonder both of these require you to modify the code if that is the case, then I would suggest you to use global keyword.
You can use global keyword to get the scope of variable $dbc
Try this..
function something()
{
global $dbc;
$info = mysqli_query($dbc, "SELECT info FROM text") or die("Error: ".mysqli_error($dbc));
}
(OR)
Try this...
function something()
{
$dbc = func_get_arg(0);
$info = mysqli_query($dbc, "SELECT info FROM text") or die("Error: ".mysqli_error($dbc));
}
& do this ....
$query = something($dbc);
There are more ways. You could use classic procedural style:
function something($dbc)
or anonymous function (if you use PHP5.3):
$fn = function() using ($dbc)
its so simple just pass your $conn variable into another calling function(instead of making new connection) like
yourpage.php
$conn = new mysqli($servername, $username, $password, $dbname);
someFunction ($conn)//you can add other parameters if you like
function someFunction ($conn) {
$result = mysqli_query ($conn, "SELECT * FROM examples);
}
Note:This is not good practice to always make new connection for database access.so always make connection once and use it every where.(but if your requirement different and require multiples connections then you can make multiples connections)