I am using MySQLi multi_query to work with several select statemets at a time.
What i would like to know is how to handle results, so i will be able to use them later in code.
Example:
<?php
//connection stuff
$query = "SELECT name, surname FROM database1;";
$query.= "SELECT car, year, type FROM database2 WHERE carID='1';";
$query.= "SELECT product, price FROM database3;";
if ($mysqli->multi_query($query)) {
if($result = $mysqli->store_result()) {
while($row = $result->fetch_row()) {
--> what to do here?
}
}
}
?>
<html>
<div id='persona'>
<?php
foreach() {
--> print name + surname
}
?>
</div>
<div id='cars'>
<?php
foreach() {
--> print car + year + type
}
?>
</div>
<div id='product'>
<?php
foreach() {
--> print product + price
}
?>
</div>
</html>
One more thing, prepared statements are not possible when using multiple_query, right?
There really is no benefit in putting unrelated queries together in one multi query call. In fact, the risk of getting hit by a SQL injection is way bigger! The regular query function does only allow one query per call, so it is impossible to inject something into a SELECT statement, ending it prematurely and then add a DELETE.
With multi_query, this is possible.
Additionally, you have to fetch and end each query, and then it's gone. You you cannot change between the query results at will, they have to be fetched in exactly the order they were issued.
The better way is to just execute independent simple queries. This would allow you to use prepared statements as well, and as long as you are not getting HUGE amounts of data back, it will probably use the same amount of memory and not annoy anyone.
Related
my xampp localhost was working well till i add this code to my php file
<?php while ($notification) {?>
<li>
<?php
echo $notification['notification'];
?>
</li>
<?php
} ?>
now the page is not loading or partially loading
here $notification is
$notification_sql= "SELECT id FROM notifications WHERE user_id='{$_SESSION['user']}'";
$notification_query = mysqli_query($conn, $notification_sql);
$notification = mysqli_fetch_assoc($notification_query);
Before I begin I want to recommend you something: Avoid the use of the while statetements. Unless they are really needed - like in the exact way they are used in the PHP docs (and even then you can find alternatives) - they should be avoided all the time. I present the motive down under.
That said,... it's not $notification['notification'], but $notification['id'].
After you change it, you still remain with the issue: an infinite loop. Because you are using a while loop without changing the state of the loop condition. E.g_ you are validating the $notification array for beeing existent. Because it exists all the time - it's state never beeing changed in the loop - then the iterations will be infinite in number. In order to avoid this dangerous (!!!) situation, you can use the following codes.
Method 1:
Notice the difference: $notification is valid only for the period of a loop step. After each iteration $notification is newly created. And, when mysqli_fetch_assoc() returns FALSE on the (last + 1)-iteration step, then the $notification receives that value and, therefore, the loop ends.
<?php
$notification_sql = "SELECT id FROM notifications WHERE user_id='{$_SESSION['user']}'";
$notification_query = mysqli_query($conn, $notification_sql);
if ($notification_query) {
while ($notification = mysqli_fetch_assoc($notification_query)) {
?>
<li>
<?php
echo $notification['id'];
?>
</li>
<?php
}
mysqli_free_result($notification_query);
}
?>
Method 2:
Or, if you want to fetch the results in an array and to output its items later, then you can do it like this:
<?php
$notification_sql = "SELECT id FROM notifications WHERE user_id='{$_SESSION['user']}'";
$notification_query = mysqli_query($conn, $notification_sql);
$notifications = array();
if ($notification_query) {
while ($row = mysqli_fetch_assoc($notification_query)) {
$notifications[] = $row['id'];
}
mysqli_free_result($notification_query);
}
// OTHER STUFF AFTER FETCHING...
?>
<?php
// LOOPING AT A LATER TIME.
foreach ($notifications as $notificationId) {
?>
<li>
<?php
echo $notificationId;
?>
</li>
<?php
}
?>
Other recommendations:
Use prepared statements in order to avoid MySQL injection.
Use exception handling in order to catch all errors and handle them correspondingly. Especially when you run database operations.
Use PDO instead of mysqli.
Here I have provided full code examples of prepared statements combined with exception handling (using mysqli library):
Can't insert info in a server, but i can as localhost (See EDIT 2)
Login using MySqli Prepared Statement (See solution 1 & 2)
Good luck.
I'm creating a page for my shop but I was using get_result, and after I finished everything I realised that HostGator couldn't allow me to have mysqlnd running. So I had to convert everything to bind_result instead but I'm in a dead end here probably from being frustrated that I have to change everything...
Anyway my problem is that I call some queries to read tables but the whole code stops after returning 1 result. In this code for example I call for a list of Appointments, although I have like 5 appointments set in the database it only returns the first one. It works as it is supposed to and reads from multiple tables but stops at 1 loop. It wouldn't let me to continue reading the 2nd table if I didn't do a $listappointments_stmt->free_result();
first before the next queries so I think that's my problem but I have no idea how to work arround it as it gives me a boolean error if I don't have it there. Any ideas welcome!
Thank you in advance,
Xenos K.
<?php
$query="SELECT * FROM appointments";
$listappointments_stmt=$mysqli->prepare($query);
$listappointments_stmt->execute();
$listappointments_stmt->bind_result($AppId, $AppDate, $AppTime, $AppType, $AppArtist, $AppTitle, $AppClient, $AppPrice, $AppNotes);
while ($listappointments_stmt->fetch())
{
$theDate=date("d-M-Y", strtotime($AppDate));
echo "<tr><td>".$theDate."</td>";
echo "<td>".$AppTime."</td>";
$listappointments_stmt->free_result();
$tempappointmentType=$AppType;
$query2="SELECT * FROM appointmenttypes WHERE ID=?";
$listappointmentsTypes_stmt=$mysqli->prepare($query2);
$listappointmentsTypes_stmt->bind_param("s", $tempappointmentType);
$listappointmentsTypes_stmt->execute();
$listappointmentsTypes_stmt->bind_result($AppTypeId, $AppTypeName, $AppTypeColor);
while ($listappointmentsTypes_stmt->fetch())
{
echo "<td><span class=\"label\" style=\"background-color:".$AppTypeColor."\">".$AppTypeName."</span></td>";
}
$listappointmentsTypes_stmt->free_result();
$listappointmentsTypes_stmt->close();
$tempappointmentArtist=$AppArtist;
$query3="SELECT * FROM staff WHERE ID=?";
$listappointmentsArtist_stmt=$mysqli->prepare($query3);
$listappointmentsArtist_stmt->bind_param("s", $tempappointmentArtist);
$listappointmentsArtist_stmt->execute();
$listappointmentsArtist_stmt->bind_result($ArtId, $ArtName, $ArtNickName, $ArtSurname, $ArtPhone, $ArtBirthDate, $ArtIdentificationNumber, $ArtStreetName, $ArtStreetNumber, $ArtPostalCode, $ArtCity, $ArtCountry, $ArtPosition, $ArtEmail, $ArtFacebook, $ArtInstagram);
while ($listappointmentsArtist_stmt->fetch())
{
echo "<td>".$ArtName." ".$ArtNickName." ".$ArtSurname."</td>";
}
$listappointmentsArtist_stmt->free_result();
$listappointmentsArtist_stmt->close();
echo "<td>".$AppTitle."</td>";
$tempappointmentClient=$AppClient;
$query4="SELECT * FROM clients WHERE ID=?";
$listappointmentsClient_stmt=$mysqli->prepare($query4);
$listappointmentsClient_stmt->bind_param("s", $tempappointmentClient);
$listappointmentsClient_stmt->execute();
$listappointmentsClient_stmt->bind_result($CliId, $CliName, $CliSurname, $CliPhone, $CliBirthDate, $CliIdentificationNumber, $CliStreetName, $CliStreetNumber, $CliPostalCode, $CliCity, $CliCountry, $CliFathersFullName, $CliMothersFullName, $CliEmail, $CliFacebook, $CliInstagram, $CliNotes);
while ($listappointmentsClient_stmt->fetch())
{
echo "<td>".$CliName." ".$CliSurname."</td>";
echo "<td>".$CliPhone."</td>";
}
$listappointmentsClient_stmt->free_result();
$listappointmentsClient_stmt->close();
echo "<td>".$AppPrice."</td>";
echo "<td><i class=\"text-green fa fa-eye\"></i></td>";
echo "<td><i class=\"text-blue fa fa-edit\"></i></td>";
echo "<td><i class=\"text-red fa fa-trash-o\"></i></td></tr>";
}
$listappointments_stmt->close();
?>
You'll be wise to learn to use JOIN statements in SQL. This will allow you to use just one SQL query to fetch all the results you need.
In the meantime, if you are nesting some SQL queries inside others, the outside query (in your case SELECT * FROM appointments) needs a separate database connection (in your case $mysqli) from the rest of the queries. Issuing a new query from the connection resets the rest of the queries.
Pro tip: Avoid using SELECT * in production software. Instead give a list of columns you need. Your software will be more robust and easier to understand if you do that.
I have this query which is one of a number of queries I have done, All the other queries works great but this does not display any results. My database has results that meets the request. Someone tell me what could be wrong?
<?php include_once "/phpmysqli/config.php" ?>
<?php
$Week_ID = $teams->WeekID->CurrentValue;
$GKB = $teams->Keeper2->CurrentValue;
$stmt16 = mysqli_stmt_init($conn);
if (mysqli_stmt_prepare($stmt16,"SELECT Total_pts FROM keeper_points WHERE PlayerID=? AND WeekNo=?"))
{
mysqli_stmt_bind_param($stmt16,"ss",$GKB,$Week_ID);
mysqli_stmt_execute($stmt16);
mysqli_stmt_bind_result($stmt16,$GKB_pts);
mysqli_stmt_fetch($stmt16);
echo $GKB_pts;
mysqli_stmt_close($stmt16);
}
?>
It sounds like PlayerID and WeekNo columns may be integers.
If they are, then try passing in the parameters as so:
mysqli_stmt_bind_param($stmt16,"ii",$GKB,$Week_ID);
The following code is meant to check if a certain query returns data. The query takes a piece of session data that is searched by the user on another page.
$whatwechecking = $_SESSION ['assignment_searched'];
$FindAsigns = $connection->query("SELECT `NAME`,`DATE`,`GRADE` FROM grades
WHERE `ASSIGNMENT` = '$whatwechecking' ORDER BY `ASSIGN_ID` DESC LIMIT 0,5");
if ($FindAsigns->fetchColumn() > 0) //this is the attempt at seeing if
//the query returned something
{
while($row = $FindAssigns->fetch()) //this loop outputs the data found in the
//query into a table
{
...find data
echo (...echo out data into table);
}
}
else
{
header('Location: NameNotFound.php'); //this is to redirect the user
to an error page that says data was not retreived in the query
}
ideally I'd like to do this in PDO as the query is in the same standard. The fetch rows method I imagine is not the most ideal in this case, so is there a better way to see if the query returns nothing?
A few things. The current query is not SQL-safe. It's possible that $_SESSION['assignment_searched'] may contain a malicious value, so I'd recomend either using the PDO Quote function or using prepared statements. In the example below I've used prepared statements.
Once you've prepared and executed the query you can easily check how many rows were returned and loop through them.
There's plenty of helpful examples of PDO in action on the internet. A quick search in Google will help. The PHP manual on PDO is also very good and the community have contributed many examples.
https://www.google.com/search?q=PHP+PDO+MySQL+Examples
http://www.php.net/manual/en/book.pdo.php
// Create PDO Prepared Statement (leave placeholder for our variable)
$stmt = $connection->prepare("
SELECT `NAME`, `DATE`, `GRADE` FROM grades
WHERE `ASSIGNMENT` = :whatwechecking
ORDER BY `ASSIGN_ID` DESC
LIMIT 0,5
");
// Bind Data to Placeholder in Statement and Execute (SQL-safe)
$stmt->execute(array('whatwechecking' => $_SESSION['assignment_searched']));
// Check if Anything was returned
if ($stmt->rowCount() > 0) {
// YES! Fetch Items and Loop Through
foreach ($stmt->fetchAll() as $item) {
var_dump($item);
}
}
I have made a "live search bar" with php and javascript. if you enter a word in the search bar it searches the database (mysql).
index.php:
<input type="text" onkeyup="getMovie(this.value)"/>
<div id="movie"></div>
javascript.js:
function getMovie(value) {
$.post("getmovie.php",{partialMovie:value},function(data) {
$("#movie").html(data);
});
}
getmovie.php:
include_once "connection.php";
if($_POST['partialMovie']){
$partialMovie = $_POST['partialMovie'];
$sql = "SELECT title FROM movie WHERE title LIKE '%$partialMovie%'";
$stm = $db->prepare($sql);
$result = $stm->execute(array());
while($row = $stm->fetch(PDO::FETCH_ASSOC)) {
echo "<li>".$row['title']."</li>";
}
}
This works, but it is way to slow. I have only 3 "movies" in my database, but it takes like a second or two to show the results.
the titles of the 3 movies are: een twee drie.
but if i type "een" fast, after a second you see een, twee, drie. a second later you see: een twee. and another second later you see: een.
So my question is: is there a way to speed the search up or is there a way to stop searching if you type another letter?
Either lower your expectation, because 1 second for a request's round trip is not very improvable, or get the data as json at page load time and search against locally available json data. But if there are many records this might not be an option.
As you use PDO, bind your parameters to avoid sql injection.
Then use full text search in MySQL (select match against), it will be a lot faster than the like %% approach.
Doc : http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
HTML:
<input type="text" id="movie-autocomplete"/>
<div id="movie"></div>
JS:
$(document).ready(function(){
$('#movie-autocomplete').keyup(function(){
setTimeout(function(){
$.post(
"getmovie.php",
{
partialMovie: $(this).val()
},
function(data) {
$("#movie").html(data);
}
);
}, 500);
});
});
This will create a small delay and post an atual value within the field.
PHP:
include_once "connection.php";
if(!empty($_POST['partialMovie'])){
$partialMovie = $_POST['partialMovie'];
$sql = "SELECT title FROM movie WHERE title LIKE :movie ORDER BY title LIMIT 0, 10";
$stm = $db->prepare($sql);
$result = $stm->execute(array(':movie' => "%{$partialMovie}%"));
while($row = $stm->fetch(PDO::FETCH_ASSOC)) {
echo "<li>".$row['title']."</li>";
}
}
We have to bind the parameter to secure the SQL query and prevent SQL injection. Also You should ensure You have set the PDO to use real prepared statements.
To further speed all the process You should return only JSON data from the PHP and fill in the <ul> within Your JS code...