PHP: When to release the result from DB? - php

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).

Related

Improve code that periodically query SQLite database

I have an sqlite database that I query from PHP periodically. The query is always the same and it returns me a string. Once the string changes in the database the loop ends.
The following code is working, but I am pretty sure this is not the optimal way to do this...
class MyDB extends SQLite3
{
function __construct()
{
$this->open('db.sqlite');
}
}
$loop = True;
while ($loop == True) {
sleep(10);
$db = new MyDB();
if (!$db) {
echo $db->lastErrorMsg();
} else {
echo "Opened database successfully\n";
}
$sql = 'SELECT status from t_jobs WHERE name=' . $file_name;
$ret = $db->query($sql);
$state = $ret->fetchArray(SQLITE3_ASSOC);
$output = (string)$state['status'];
if (strcmp($output, 'FINISHED') == 0) {
$loop = False;
}
echo $output;
$db->close();
}
If you want to get an output immediately and a kind of interface, I think The best solution for your problem might be to use HTTP long polling. This way, it will not hold the connection for hours if the job is not done:
you will need to code a javascript snippet (in another html or php page) that runs an ajax call to your current php code.
Your web server (and so, your php code) will keep the connection opened for a while until the job is done or a time limit is reached (say 20-30 seconds)
if the job is not done, the javascript will make another ajax call and everything will start again, keeping the connection, etc... until you get the expected output status...
BEWARE : this solution will not work on any hosting provider
You will need to set the max_execution_time to a higher value than the default one see php doc for this.
I think you can find many things on http long polling with php/javascript on google / stack overflow...

PHP: could not find database

i am having difficulty with connecting my database to mysql, i have tried many different ways of trying to get it to connect to my database, but none these methods seem to work. I am only new to php and i could be missing something, but i dont know what it is.
This is for a search engine, i have the form created.
I would think that my problem is coming from this line of code, mysql_connect("localhost", "root", "") or die("could not connect");?!
I was wondering if i could be told what is the problem and how to fix it, thank you so much.
here is my code below.
<?php
//connect
mysql_connect("localhost", "root", "") or die("could not connect");
mysql_select_db("search") or die("could not find database");
$output = '';
if (isset($_POST['search'])) {
$searchq = $_POST['search'];
$searchq = preg_replace("#[^0-9a-z]#i","", $searchq);
$query = mysql_query("SELECT * FROM gp management system WHERE Title LIKE '%$searchq%' OR Description LIKE '%$searchq%' OR Keyword LIKE '%$searchq%'") or die("could not search");
$count = mysql_num_rows($query);
if($count == 0) {
$output = 'There was no search results!';
}
else{
while($row = mysql_fetch_array($query)) {
$Title = $row['Title'];
$Description = $row['Description'];
$Keyword = $row['Keyword'];
$output .= '<div> ' .$Keyword. ' </div> ';
}
}
}
?>
SQL errors:
SELECT * FROM gp management system WHERE Title...
^^-- table name
^^^^^^^^^^ aliasing 'gp' as 'management'
^^^^^^-- extra unknown garbage
Table names shouldn't have spaces to begin with, but if you insist on having them, then you need proper quoting:
SELECT * FROM `gp management system` etc...
^--------------------^
Never output a fixed/useless "could not search" error. Have the DB tell you what went wrong:
$result = mysql_query($sql) or die(mysql_error());
^^^^^^^^^^^^^^^^^^^^^^^
As your only new, you really should stop using mysql_ and change to mysqli_ or (my preference) PDO(). Your message in your title seems to be coming from your selectdb line, so you're actually connecting to the database fine, it's just not able to locate the schema that you are trying to use (i.e. "search" does not exist as a schema name in your DB environment). Unless that's not the error that you are getting, in which case it's a flaw in your actual SQL query. Without an accurate statement of what you are getting back on the screen when you try to run the script then not much can be done to help.
I would rather do somehow like I did ages ago, see below:
function db_connect($host, $username, $passwd, $db_name) {
$db = mysql_connect($host, $username, $passwd);
if (!$db) {
echo "Login to database failed: ";
echo mysql_error();
return false;
}
$result=mysql_select_db($db_name); //Select the database
if (!$result) {
echo "Cannot find the database: ".$db_name;
echo mysql_error();
return false;
}
return $db; //Database descriptor
}
However you shouldnt rely on the old MYSQL extension, but use MYSQLi.
EDIT: as #tadman pointed out there were a # sign infront the mysql_connect call, however there is an if statement for checking and a call to error output.
As others have said, your code is something of a mess - you seem to be new to programming, not just in PHP. But everyone has to start somewhere, so....
You might want to start by learning a bit about how to ask questions - specifically you have included a lot of code which is not relevant to the problem you are asking about - which is about connecting to MySQL. OTOH you have omitted lots of important information like the operating system this is running on and what diagnostics you have attempted. See here for a better (though far from exemplary example).
Do read your question carefully - the title implies an issue with mysql_select_db() while in the body of the content you say you think the problerm is with mysql_connect(). If you had provided the actual output of the script we would have been able to tell for ourselves.
You should be checking that MySQL is actually running - how you do that depends on your OS. You should try connecting using a different client (the mysql command line client, sqldeveloper, Tora, PHPMyAdmin....there are lots to choose from).
You should also check (again this is operating system specific) that your MySQL instance is running on the same port as is configured in your php.ini (or overridden in your mysql_connect() call).
MySQL treats 'localhost' as something different from 127.0.0.1 on Unix/Linux systems. If this applies to you try 127.0.0.1 in place of localhost.
or die("could not connect");
Does not help in diagnosing the problem. If instead you...
or die(mysql_error());
You will get a more meaningful response.
BTW: while writing code using the mysql extension rather than mysqli or PDO is forgivable, I am somewhat alarmed to see what appears to be medical information managed with no real security.

where's the best place to close the DB connection?

In this code I think maybe it would be best to close after both the if and else but it seems off to close it twice.
<?php
$member_id = "";
require("connect.php");
if (isset($_POST['member_id']))$member_id = fix_string($_POST['member_id']);
$sql=("DELETE FROM members WHERE member_id = '$member_id'");
$res = mysqli_query($con, $sql);
if (mysqli_affected_rows($con) == 1) {
echo "member with ID of ".$member_id." has been removed from members table";
} else {
echo "member was not deleted";
}
function fix_string($string) {
if (get_magic_quotes_gpc()) $string = stripslashes($string);
return htmlentities ($string);
}
?>
It is very common practice to open the db connection at the beginning, and close your connection once at the end. You don't need to do it in the middle of your code.
Closing database connections isn't absolutely required, as seen in the PHP manual page for mysql_close(), but it is considered good practice by many to do so.
There is a rare exception to this. If your program is going to be doing some heavy processing for several minutes, you might want to close the db connection before this. If you need it again after the processing, open the db connection again. The reason for this is that the MySQL connection will eventually time out, and then it may lead to more problems in your program.
Using mysql_close() isn't usually necessary, as non-persistent open links are automatically closed at the end of the script's execution.
Straigh out from the php manual.

PDO let database stay open, or open and close when needed?

I have just discovered PDO and I'm very excited about it, but I have read a few tutorials on how to implement it, and they show me different ways of doing it.
So now I'm confused which way is the best.
example 1: open database once.
include("host.php"); //including the database connection
//random PDO mysql stuff here
Example 2: open close the database when needed:
try {
$dbh = new PDO(mysql stuff);
$sql = "mysql stuff";
foreach ($dbh->query($sql) as $row)
{
echo $row['something'];
}
/*** close the database connection ***/
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
Which is best? I would think example 2 is best, but there much more code than example 1.
Usually, there is significant time spent/lost when connecting, and you want to do it only once. Do not go closing a connection you need later on, it will only slow things down. You may consider closing a connection sooner if you are reaching the maximum connections limit, but that's more a hint you should scale up then a permanent solution IMHO.

Database connections and functions?

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).

Categories