Reusing MYSQL queries on the same page - php

I have a header.php and a footer.php file being included on the same page, they both return some of the same information. Specifically I use this query in each file.
<?php
$q3 = "SELECT page_id, show_id, link_title FROM pages as p WHERE show_id = 1";
$r3 = #mysqli_query ($dbc, $q3); // Run the Query.
while ($nav = mysqli_fetch_array($r3, MYSQLI_ASSOC)) {
echo"<li>{$nav['link_title']}</li>"
}
?>
This is to show the pages in both the header and footer.
However SOMETIMES the second query in the footer returns a "Couldn't fetch mysqli", sometimes it works, sometimes it doesn't. I was wondering should I be using something like mysqli_free_result() would that be better practice?
Even more, is it good practice to free the result after every query? Is there a better way to use the same result from different pages and <?php // ?> tags?
Also, I get the error "too many mysql connections error" every now and then? Is this because I am not closing connections after queries are ran?

You could begin with removing the # from your code. Error suppression is slow and harmful practice.
If you inlcude's are in same scope, you can just save the value of first in some variable, and check in second , if variable has been set.
content of header.php
$storage = '';
$query = "SELECT page_id, show_id, link_title FROM pages as p WHERE show_id = 1";
if ( $result = mysqli_query ($dbc, $query))
{
while ($nav = mysqli_fetch_array($result, MYSQLI_ASSOC))
{
$item = "<li>{$nav['link_title']}</li>";
$storage .= $item;
echo $item;
}
}
else
{
echo 'Query has failed !';
}
content of footer.php
if ( isset( $storage ) && count( $storage ))
{
echo $storage;
}
else
{
echo 'Query has failed !';
}
Read about include() in the fine manual.
And please , stop writing that this procedural perversion. Learn how to do OOP and read about PDO.

Run the query only once, prior to including the header and footer and store the results in a variable - you can use them as many times as you want after that.
mysqli_free_result() should be used only if you have a really large result set, as PHP would take care of free-ing it after it's no longer needed and manually doing this every time just creates extra overhead.
You are getting the "too many connections" error because you're probably opening multiple connections as you do with repeating the same query - create just one before including any other script and just reuse it. You should use the standard mysql extension with mysql_pconnect() for an even better solution to this one ... otherwise - yes, close the connection after you no longer need it.

Related

PHP While Loop with MySQL Has Inconsistent Execution Time, How Can I Fix This?

My problem is simple. On my website I'm loading several results from MySQL tables inside a while loop in PHP and for some reason the execution time varies from reasonably short (0.13s) or to confusingly long (11s) and I have no idea why. Here is a short version of the code:
<?php
$sql =
"SELECT * FROM test_users, image_uploads
WHERE test_users.APPROVAL = 'granted'
AND test_users.NAME = image_uploads.OWNER
".$checkmember."
".$checkselected."
ORDER BY " . $sortingstring . " LIMIT 0, 27
";
$result = mysqli_query($mysqli, $sql);
$data = "";
$c = 0;
$start = microtime(true);
while($value = mysqli_fetch_array($result)) {
$files_key = $value["KEY"];
$file_hidden = "no";
$inner_query = "SELECT * FROM my_table WHERE KEY = '".$files_key."' AND HIDDEN = '".$file_hidden."'";
$inner_result = mysqli_query($mysqli, $inner_query);
while ($row = mysqli_fetch_array($inner_result)) {
// getting all variables with row[n]
}
$sql = "SELECT * FROM some_other_table WHERE THM=? AND MEMBER=?";
$fstmt = $mysqli->prepare($sql);
$fstmt->bind_param("ss", $value['THM'], 'username');
$fstmt->execute();
$fstmt->store_result();
if($fstmt->num_rows > 0) {
$part0 = 'some elaborate string';
} else {
$part0 = 'some different string';
}
$fstmt->close();
// generate a document using the gathered data
include "../data.php"; // produces $partsMerged
// save to data string
$data .= $partsMerged;
$c++;
}
$time_elapsed_secs = substr(microtime(true) - $start, 0, 5);
// takes sometimes only 0.13 seconds
// and other times up to 11 seconds and more
?>
I was wondering where the problem could be.
Does it have to do with my db connection or is my code flawed? I haven't had this problem at the beginning when I first implemented it but since a few months it's behaving strangely. Sometimes it loads very fast other times as I said it takes 11 seconds or even more.
How can I fix this?
There's a few ways to debug this.
Firstly, any dynamic variables that form part of your query (e.g. $checkmember) - we have no way of knowing here whether these are the same or different each time you're executing the query. If they're different then each time you are executing a different query! So it goes without saying it may take longer depending on what query is being run.
Regardless of the answer, try running the SQL through the MySQL command line and see how long that query takes.
If it's similar (i.e. not an 11 second range) then the answer is it's nothing to do with the actual query itself.
You need to say whether the environment you're running this in is a web server, e.g. accessing the PHP script via a browser, or executing the script via a command line.
There isn't enough information to answer your question. But you need to at least establish some of these things first.
The rule of thumb is that if your raw SQL executes on a MySQL command line in a similar amount of time on subsequent attempts, the problem area is elsewhere (e.g. connection to a web server via a browser). This can be monitored in the Network tab of your browser.

Php postgresql error, prepared statement already exists

Am getting an error of prepared statement "my_query7" already exists, i call this function each time a user tries to update table leader_info in the database, i have gone through the documentation for pg_prepare and i don't understand what is meant by it should only be run once. code snippets will be of help. Thanks.
function add_leader_country($user_id,$l_country)
{
global $connection;
$query = pg_prepare($connection,"my_query7","update leader_info set l_country = $1 where user_id = $2 and status < 9");
$result = pg_execute($connection,"my_query7",array($l_country,$user_id));
if(!$result)
{
echo pg_last_error($connection);
}
else
{
echo "Records created successfully\n";
}
$row = pg_affected_rows($result);
return $row;
}
Prepare execute does not permit duplicate naming, so that is your error.
A query should only be prepared once, for example, in a cycle for the preparation state must be set out of the for and its execution in the for.
$result=$pg_prepare($connection,"my_query7",$query);
for($id=1;$id<3;$id++){
$result=pg_execute($connection,"my_query7",array($l_country,$user_id));
...
}
In your case using a functio that use the prepare and execute multiple times it's a problem.
What are you trying to accomplish with this function dispatches more code like where you are calling the function. This way I might be able to help you.
If you want to use functions I would use this method
Exemple from https://secure.php.net
<?php
function requestToDB($connection,$request){
if(!$result=pg_query($connection,$request)){
return False;
}
$combined=array();
while ($row = pg_fetch_assoc($result)) {
$combined[]=$row;
}
return $combined;
}
?>
<?php
$conn = pg_pconnect("dbname=mydatabase");
$results=requestToDB($connect,"select * from mytable");
//You can now access a "cell" of your table like this:
$rownumber=0;
$columname="mycolumn";
$mycell=$results[$rownumber][$columname];
var_dump($mycell);
If you whant to use preaper and execute functions try to create a function that creates the preparations only once in a session. Do not forget to give different names so that the same error does not occur. I tried to find something of the genre and did not find. If you find a form presented here for others to learn. If in the meantime I find a way I present it.

MySQL Select Query & use it globally(Multiple PHP pages)

I'm currently pulling the data from MySQL Database with the current code Example 1
function User_Details($uid){
$uid = mysql_real_escape_string($uid);
$query = mysql_query("SELECT uid,password,email,nickname,username,profile_pic,friend_count FROM users WHERE uid='$uid' AND status='1'");
$data = mysql_fetch_array($query);
return $data;
}
I'd like to use this query across multiple PHP pages without having to write a foreach loop for every PHP file.
Currently I have it inside a class called class Wall_Updates { }, and I try to print it with the following code: Example1 : < ?php echo $data['username']; ? >.
The class Wall_Updates is being called on the header which should also include the User_Details, so the only issue is how do I print with just the following PHP example I gave above without the need of a loop.
The class words with single fielded queries such as Example 2 $face = $Wall->Profile_Pic($msg_uid); and if I echo $face it'll show my current Profile_Pic which is a single query.
Example 3 of how I don't want to do as it's very messy.
<?php
if ($uid) {
$updatesarray = $Wall->Updates($uid);
}
if ($updatesarray) {
foreach ($updatesarray as $data) {
$username = $data['username'];
?>
#HTML CODE GOES HERE
<?php } ?>
So I'd like my query to pull multiple fields from users and use it across any page without a foreach.
PS: I'm sorry if it's not making sense, I've been complained a lot for not showing what I've tried and I hope to not get complained about it this time, I appreciate for looking at my question.
you need to issue the "or die" sql command EVERYWHERE otherwise you have no idea why it failed.
http://pastie.org/7897405
you have a column name wrong (look at the last line of the pastie
also, get off of the mysql_ stuff and get into pdo. you should know better chump !

Strange error "sqlsrv_fetch_array(): 16 is not a valid ss_sqlsrv_stmt resource" since ReturnDatesAsStrings

I am using the sqlsrv driver for IIS so I can connect to a MS SQL server in PHP.
I've managed to convert a lot of my original mysql_ code and all going well, until I tried to SELECT some DateTime fields from the database. They were coming back as Date objects in PHP rather than strings, I found the fix which is adding this to the connection array:
'ReturnDatesAsStrings'=>1
Since doing that though my code is broken when trying to populate my recordset:
function row_read($recordset) {
if (!$recordset) {
die('<br><br>Invalid query :<br><br><bold>' . $this->sql . '</bold><br><br>' . sqlsrv_error());
}
$rs = sqlsrv_fetch_array($recordset);
return $rs;
}
The error is: sqlsrv_fetch_array(): 16 is not a valid ss_sqlsrv_stmt resource
There is such little amount of help on that error in Google so this is my only shot! I just don't get it.
row_read is called from within a While: while ($row = $db->row_read($rs)) {
Any ideas?
Just to add more code and logic - I do a simple SELECT of all my orders, then as it loops through them, I do another 2 SELECT's on the orders table then the customer table. It's falling down when I try these extra 2 'gets':
$this->db->sql = "SELECT * FROM TicketOrders";
$rs = $this->db->query($this->db->sql);
$this->htmlList->path("skin/search.bookings");
if ($this->db->row_count != 0) {
while ($row = $this->db->row_read($rs)) {
// Load the order row
$this->TicketOrders->get($this->db, $row['Id']);
// Load the customer row
$this->Customers->get($this->db, $row['CustomerId']);
Did you pass this resource variable by another function? If yes, you can try by executing the sqlsrv_query and executing sqlsrv_fetch_array in one function; don’t pass the ss_sqlsrv_stmt resource by another function. Hope that it will help.
Does your program involves a nested query function?
If so, the next question is: are you opening the same database in the inner query function?
Try these changes:
comment out the lines that open the database, including the { and } that enclose the function,
change the name of connection and array variables between the outer loop and the inner loop.
In other words, the outer loop may have:
$tring = sqlsrv_query($myConn, $dbx_str1);
while( $rs_row1 = sqlsrv_fetch_array($tring, SQLSRV_FETCH_ASSOC))
and the inner loop would have:
$tring2 = sqlsrv_query($myConn, $dbx_str2);
while( $rs_row2 = sqlsrv_fetch_array($tring2, SQLSRV_FETCH_ASSOC))
sqlsrv_fetch_array need a ss_sqlsrv_stmt resource. There must be something wrong with your SQL.

Is mysql_num_rows efficient and/or standard practice?

A while ago I was poking around with SQLite, trying to port some of my sites to use it instead of MySQL. I got hung up on the lack of a function to count results, like PHP's mysql_num_rows(). After searching a little I discovered this mail list, which says (as I understand it) that SQLite doesn't have that functionality because it's inefficient. It states that it is bad form to write code that needs to know how many rows are returned.
I generally use mysql_num_rows to check for empty return results. For example:
$query = "SELECT * FROM table WHERE thing = 'whatever'";
$results = mysql_query($query);
if (mysql_num_rows($results)) {
while ($row = mysql_fetch_array($results)) {
echo "<p>$row[whatever]</p>";
}
} else {
echo "<p>No results found</p>";
}
The vehement distaste for the concept of mysql_num_rows() in the SQLite community makes me wonder if it's that terribly efficient for regular MySQL in PHP.
Is there a better, more accepted way for checking the size of a MySQL result set in PHP besides mysql_num_rows()?
EDIT:
I'm not just using mysql_num_rows to get the count--I would use a COUNT query for that. I'm using it to check if there are any results before outputting everything. This is useful for something like displaying search results - it's not always guaranteed that there will be results. In SQLite world, I have to send one COUNT query, check if there is something, and then send a SELECT query to get everything.
You already have something that is telling you if you've got results in mysql_fetch_array(). It returns false if there are no more rows to fetch (from php.net).
$query = "SELECT * FROM table WHERE thing = 'whatever'";
$results = mysql_query($query);
if($results) {
$row = mysql_fetch_array($results);
if($row) {
do {
echo "<p>{$row[whatever]}</p>";
} while($row = mysql_fetch_array($results));
} else {
echo "<p>No results found</p>";
}
} else {
echo "<p>There was an error executing this query.</p>";
}
Regardless of whether or not you actually use what you SELECTed, all of the rows are still returned. This is terribly inefficient because you're just throwing away the results, but you're still making your database do all of the work for you. If all you're doing is counting, you're doing all that processing for nothing. Your solution is to simply use COUNT(*). Just swap COUNT(*) in where you would have your SELECT statement and you're good to go.
However, this mostly applies to people using it as a complete substitute for COUNT. In your case, the usage isn't really bad at all. You will just have to manually count them in your loop (this is the preferred solution for SQLite users).
The reason being is in the underlying SQLite API. It doesn't return the whole result set at once, so it has no way of knowing how many results there are.
As explained on the mailing list you found. It is inefficient to return the count of rows because you need to allocate a lot of memory to hold the entire (remaining) result set. What you could do, is to simply use a boolean to test if you have output anything.
$query = "SELECT * FROM table WHERE thing = 'whatever'";
$results = mysql_query($query);
$empty_result = true;
while ($row = mysql_fetch_array($results)) {
echo "<p>$row[whatever]</p>";
$empty_result = false;
}
if ($empty_result) {
echo "<p>No results found</p>";
}

Categories