I'm new to using functions, so - no judgements please ;).
Let's say I have a function add_to_x() in function.php which within performs a mysql_query(). This function is included, (include "function.php";), into script.php, and called mid-way through that script. At the top of function.php I establish a database connection, closing it at the end.
Would this be passed through by default to the function add_to_x() or would I need to establish and close a connection within add_to_x() itself?
For illustration and good measure:
Contents of script.php
include "function.php";
// Do something
add_to_x($arg1, $arg2);
// Do something else
Contents of function.php
include "db_conn.php";
$conn = mysql_connect($db_host, $db_user, $db_pass); mysql_select_db($db_name);
function add_to_x($arg1, $arg2) {
// Do something
$query = "SELECT * FROM table WHERE x = '$arg1'";
$result = mysql_query($query);
}
mysql_close($conn);
Would that work? Or would I need to do something like this:
function add_to_x($arg1, $arg2) {
include "db_conn.php";
$conn = mysql_connect($db_host, $db_user, $db_pass); mysql_select_db($db_name);
// Do something
$query = "SELECT * FROM table WHERE x = '$arg1'";
$result = mysql_query($query)
mysql_close($conn);
}
It might look like a rather stupid question, but I'm not sure of the scope of connections/functions. I feel that perhaps the second example would be better practice even if the first would work?
Any comments, advice, answers would be greatly appreciated! (I realize I've made this question a bit messy, but I hope the illustration code helps, and of course, if you need further clarification please do ask for it)!
You can open the database connection in the file that defines your functions, as you are doing. But closing it at the end of function.php is not what you want to do - by doing this you are closing the connection before it is ever used.
You would either call mysql_close() at the very end of your main script (after all calls to functions that require the connection), or not at all (the resource will be implicitly closed/freed when the script finishes).
Any code that's in the global scope of function.php (ie not inside a function), will be executed when you include the script. So in the code you posted, the $conn will no longer be open in your add_to_x().
Few things to explain:
1) If you have $conn defined in global scope, you can access it from any function using keyword global e.g.
function add_to_x(){
global $conn;
}
2) you can use mysql queries in your functions even if connection is made "outside", as mysql will use last opened connector, unless other specified
summing up, first of your example should work (did not check parsing etc).
Related
I am converting PHP code from mysql_ to mysqli_. My DB connection is in a separate file, named "conn.inc" in a parent folder of my regular code. The code in it is ::
function GetDBConn($host="localhost", $user="mydb", $pass="mypass", $db="mydb") {
return $dbconn = #mysqli_connect($host, $user, $pass, $db);
mysqli_close($dbconn);
}
In my code files, I have
include_once ("../conn.inc"); .
I have code like -
$AuditInsertQ = mysqli_query(GetDBConn(),"INSERT INTO audit (userid, notes) VALUES (\"".$userid."\", \"".$notes."\")") or die("Error inserting row to Audit: ".mysqli_error($dbconn));
When I run the code, I get a message that ::
PHP Notice: Undefined variable: dbconn in C:\...
All of the examples I have seen have the DB connection in the same file as the code it was referencing. How do I reference the DB connection when it is in a different file; I thought the "include_once" was the way...?
There is so much wrong in this code I don't even know where to start.
no need for mysqli_error() at all
no need for a function like GetDBConn()
mysqli_close() right after connect makes no sense. Thanks to return operator, it never gets called though
die() is harmful
# operator is harmful
the file extension for conn.inc is harmful
the way you are adding variables to your query is most harmful of them all
I know it's hard to find a good tutorial. Internet is full of crappy outdated information. I am writing good tutorials, but Google don't know they are good and don't show them to you. Well at least I can give it to you here in my answer.
Three things you must understand about modern mysqli
mysqli can report its errors automatically, no need for mysqli_error()
a connection must be made only once, it means there is no use for a function like this
no variable should be added to the query directly. You have to use prepared statements with placeholders for the purpose.
In order to fix your code,
please read this post. It doesn't explain why you should use prepared statements but take my word for it
then read my tutorial on how to connect with mysqi properly
rename your file to conn.php or anyone will be able to see your database credentals
Then rewrite your code to
include_once ("../conn.php");
$stmt = $mysqli->prepare("INSERT INTO audit (userid, notes) VALUES (?,?)");
$stmt->bind_param("ss", $userid,$notes);
$stmt->execute();
For the explanation on what is going on in this code please see my tutorial on how to run an INSERT query with mysqli
In you function GetDBConn it return a mysql resource, not define a $dbconn variable for you.
Use something like mysqli_query($dbconn = GetDBConn(),"INSERT INTO audit ....
Note
function GetDBConn($host="localhost", $user="mydb", $pass="mypass", $db="mydb") {
return $dbconn = #mysqli_connect($host, $user, $pass, $db);
mysqli_close($dbconn);
}
$dbconn is only avaliable in the function, it cannot be accessed outside the function, so define it here is useless.
mysqli_close($dbconn); will never reached.
I assume this will be a rather basic question for most of you PHP guys out there. Let's assume I have this file to work with a DB:
<?php
define("DB_HOST", "localhost");
define("DB_NAME", "dbname");
define("DB_USER", "admin");
define("DB_PASSWORD", "abcdefg");
$connection;
$result;
function connectDatabase() {
global $connection;
if(isset($connection)) return;
$connection = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if(mysqli_connect_errno()) {
die("Database connection failed: " . mysqli_connect_error() . " (" . mysqli_connect_errno() . ")");
}
}
function queryDatabase($query) {
global $connection, $result;
$result = mysqli_query($connection, $query);
if(!$result) {
die("Database query failed");
}
else {
return $result;
}
}
function releaseResult() {
global $result;
mysqli_free_result($result);
}
function closeConnection() {
global $connection;
mysqli_close($connection);
}
?>
And let's say it I call it like this:
<?php
require_once("db_connection.php");
function createNavigation() {
connectDatabase();
$query = "SELECT * ";
$query .= "FROM subjects ";
$query .= "ORDER BY position ASC";
$result = queryDatabase($query);
while($subject = mysqli_fetch_assoc($result)) {
//do something
}
releaseResult();
}
?>
The question is - do I actually have to release the local $result in the createNavigation function too or that is not necessary?
What is the mysqli_free_result good for anyway? Coming from other OOP languages I understand releasing/destroying/disabling/nulling objects, GC, memory management, etc. but I am kind of confused what it is good for in PHP considering the script runs only once, returns something and it is done. Thank you!
It's about helping php manage resources effectively. If you don't call it, then the resource will get cleaned up by php, but it's better to call it yourself and get rid of it straight away when you know it's no longer required.
Take an extreme example of a script which takes a second to run, where a database connection is opened at the beginning and only needed very briefly. Once the script finishes, resources (database connections etc) will be freed, but the connection could have been open for, say 0.8secs longer than needed. Now add multiple users hitting the page in parallel and you have ended up with lots of instances of this connection being open at any given time, whereas if yo had cleaned up the connection straight away, fewer instances would be needed.
In practice, it's not particularly necessary. Most PHP scripts are written to be accessed over HTTP, which means they run briefly, then they stop, and memory is freed up at that point. The only practical reason I could see this being important is if you're running a persistent script, such as one you've built as a daemon that you kick off and it continues to run until you stop it. Releasing your results at that point would prevent the memory footprint from bloating up.
For security, future compatibility, and because you said that you've come from an OOP background, you should probably be using PDO instead of the mysqli_* functions. To establish a MySQL connection, you create a new PDO object. To free up the resources, you simply unset of the object (or the result, as the case may be).
I have this index.php :
<?php
require_once ('required1.php');
require_once ('required2.php');
--- some mysqli_query here ---
?>
what's inside that required1.php is this :
<?php
$DbServer = 'localhost';
$DbUser = 'username';
$DbPassword = 'password';
$DbName = 'dbname';
$con = mysqli_connect($DbServer, $DbUser, $DbPassword, $DbName);
?>
and this is required2.php :
<?php
require_once 'required1.php';
--- some mysqli_query here ---
mysqli_close($con);
?>
the mysqli_close($con); on required2.php makes mysqli_query on index.php failed because the mysql connection already closed by required2.php.
how to make required2.php works independently? I mean, what ever happen on that file (required2.php) leave it there. don't bring anything into other file who calls it, specially the mysqli_close($con);
is it possible with require_once? or PHP have another function to make it like that? thanks!
Use a different connection in require2.php or don't close it. You can also include it at the bottom.
Using mysqli_close($con); in required2.php closes the connection, so after any include of required2.php, $con won't be available.
If you want required2.php to be independent, you have to use another database connection, not $con.
First of all, there is really no need to close the connection in your included file (there may be very specific exceptions...).
If you want to use your second include independently, you should refactor it to OOP. If it is a class that gets its database connection injected via its constructor (dependency injection), it would only show its name to the rest of your code so things that happen in the class or an object, would not affect the rest of your code.
Of course you still should not close your connection as that object will likely be passed around by reference but using objects / classes instead of procedural code will make it more independent an reusable.
if required2.php has nothing to do with your current script, but all you need to do is to run the script as you mentioned, i feel you can call the file required2.php using file(). this will run both the scripts separately and even if you close connection in required2.php it does not effect the current script.
I am trying my best to object orientate my login scripts and checks for my website. As such, I have created a function that is called named "attempt_login". This function uses a database connection via the "mysqli_connect" function provided by a outside php file that is included and returns the $link variable.
However, when in my "attempt_login" the "mysqli_stmt_prepare" function is reached. It always returns false, and as such, the if statement never runs.
mysql_connect.php
require_once '../conf.php';
$link = mysqli_connect($mysql_server,$mysql_user,$mysql_pass,$mysql_db);
if(mysqli_connect_error())
{
//Fail
echo mysqli_connect_error();
}else{
//Success
}
return $link;
And the code from the "attempt_login" that fails:
$link = require_once 'functions/mysql/mysql_connect.php';
print_r($link);
$stmt = mysqli_stmt_init($link);
echo mysqli_stmt_error($stmt);
echo mysqli_error();
//This if statement always fails.
if(mysqli_stmt_prepare($stmt,"SELECT member_salt FROM members WHERE username=?" ) )
{
mysqli_stmt_bind_param($stmt,'s',$login_details['username']);
mysqli_stmt_execute($stmt);
$member_salt = NULL;
mysqli_stmt_bind_result($stmt,$member_salt);
mysqli_stmt_close($stmt);
}
And calling the function is pretty simple.
attempt_login($login_details);
I have tried many ways to do this, but it seems to only work when it is not within a function. Which defeats the purpose of me trying to have it in a function. If I move the error output to after the if statment, it will print:
No Database Selected
Even though one clearly is set in the link. I also can do a print_r($link); and it does print proper data for the mysql server.
It also has the same issue with procedural and object orientated mysqli styles, and fails as well with "mysqli_prepare".
I do have mysql working on the site, but any attempts to run anything within a function fails.
I have searched for several hours on trying to find a answer, but was unable to locate anything. I look forward to hearing from you! Many thanks in advance.
~Travis
I'd say then you haven't selected a database.
Either $mysql_db isn't set in ../conf.php or there is a typo or $mysql_db isn't visible in mysql_connect.php.
You don't seem to be passing $stmt to your function, I would advise your read this on scopes.
I'm using a file called "lib.php" in which i have defined many functions.
One of these functions is the following :
function dbconn()
{
$servername="127.0.0.1";
$username="root";
$conn=mysql_connect($servername,$username)or die(mysql_error());
mysql_select_db("profit",$conn) or die(mysql_error());
}
In all the .php pages of my website, i've been using this dbconn() function, and it seemed to work fine for reading information from the database. However, when trying to write information, it seems to pose a problem. Specifically, the following code did not function :
<?php
require ("lib.php");
set_time_limit(60);
session_start();
dbconn();
$sql="update `city` set end_dt=now() where city_id='$_POST[killcity]'";
$result=mysql_query($sql,$conn) or die(mysql_error());
header("Location: manipulate.php");
?>
It says that conn is an undefined variable, whereas it should be defined by dbconn() in lib.php.
So, i've found a way around this, by instead creating a new php file called dbconn.php, which contains the exact same thing as dbconn(), and by inserting require ("dbconn.php"); instead of dbconn();.
But i'm still wondering : why did the original way not work ?
You could add a return statement for the function, through you could use global variable in a function, that's not good practice. If you want to, see how global variable works.
function dbconn() {
$servername="127.0.0.1";
$username="root";
$conn=mysql_connect($servername,$username)or die(mysql_error());
mysql_select_db("profit",$conn) or die(mysql_error());
return $conn;
}
$conn = dbconn();