I know this might be a very basic question, but I am new to php and databases, I'm trying to figure out a while condition that will keep while loop running until all (would be also nice to know how to do it for fixed amount) of data is taken form database.
$stmt = $db->prepare("SELECT * FROM icecreams");
$stmt -> execute();
$row = $stmt -> fetchAll(PDO::FETCH_ASSOC);
So now I need to figure out what while condition I need, the logic is
while (there is data to fetch) {
echo "<h1>$row['flavour']</h1>";
echo "...";
}
fetchAll() returns an array containing all of the result set rows, whereas fetch() returns a single row from the result-set.
fetchAll() Usage:
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($array as $row) {
# code...
}
fetch() Usage:
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
# code...
}
If you're going to use this for printing HTML, the second option seems nicer. For small recordsets, the performance difference shouldn't really matter, but if you're working with a lot of records, then fetchAll() might be a little slower, as it tries to map the entire data into a single array at once.
$stmt = $db->prepare("SELECT * FROM properties");
$stmt -> execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
//$row['column_name']
}
fetchAll does fetch everything as an associative array (as flag FETCH_ASSOC tells). It does it automatically for, you don't have to worry about it.
If you do this then you will see that you have all of your data in an array already:
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo '<pre>'.print_r($row, true).'</pre>';
So now you can simply loop the items an access the data:
foreach($row as $k=>$v)
{
echo $k.'<br>'; // this will show you what row # you are on, sometimes useful :)
echo $v['title'].'<br>';
// etc....
}
Related
I have different id's, i am getting the values of these id from users
$id=array();
$id[0]=$_GET["id0"];
$id[1]=$_GET["id1"];
$id[2]=$_GET["id2"];
now to fetch data from database i am using following query:
for($j=0;$j<count($id);$j++)
{
$res=mysql_query("SELECT * FROM mutable WHERE id='$id[$j]'")
while($row=mysql_fetch_array($res))
{
$row[]=array("email"=>$row[2],"name"=>$row[3],"address"=>$row[5]);
echo JSON_encode($row);
}
}
now i am getting proper result from this query using for loop but the result is not in proper JSON format, is there any way to do it more efficentyly and getting proper result in JSON array and JSON object format
Place json_encode() outside of your loops.
Let's modernize and refine things...
*Unfortunately prepared statements that use an IN clause suffer from convolution. pdo does not suffer in the same fashion.
Code: (untested)
if(isset($_GET['id0'],$_GET['id1'],$_GET['id2'])){
$params=[$_GET['id0'],$_GET['id1'],$_GET['id2']]; // array of ids (validation/filtering can be done here)
$count=count($params); // number of ids
$csph=implode(',',array_fill(0,$count,'?')); // comma-separated placeholders
$query="SELECT * FROM mutable WHERE id IN ($csph)";
$stmt=$mysqli->prepare($query); // for security reasons
array_unshift($params,str_repeat('s',$count)); // prepend the type values string
$ref=[]; // add references
foreach($params as $i=>$v){
$ref[$i]=&$params[$i]; // pass by reference as required/advised by the manual
}
call_user_func_array([$stmt,'bind_param'],$ref);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_array(MYSQLI_NUM))
$rows=["email"=>$row[2],"name"=>$row[3],"address"=>$row[5]];
}
$stmt->close();
echo json_encode($rows);
}
Three things:
Always, always, always used prepared statements and bound parameters when dealing with untrusted (i.e., $_GET) input. Just do it.
As regards your problem with JSON, you only need to run json_encode once:
$results = [];
for($j=0;$j<count($id);$j++) {
...
while($row=mysql_fetch_array($res)) {
results[] = ...
}
}
json_encode( $results );
Use a single SQL statement, since you have a known number of IDs to collect:
$dbh = new PDO($dsn, $user, $password);
$sql = "SELECT * FROM mutable WHERE id IN (?, ?, ?)";
$sth = $dbh->prepare( $sql );
foreach ( $sth->execute( [$_GET['id0'], $_GET['id1'], $_GET['id2']] ) as $row ) {
...
This is more efficient then multiple round trips to the database. For this contrived case it probably doesn't matter, but getting into good habits now will serve you in the long run.
you have used $row wrongly, declare array variable outside of loop like
$json_response = array();
for($j=0;$j<count($id);$j++) {
$res=mysql_query("SELECT * FROM mutable WHERE id='$id[$j]'")
while($row=mysql_fetch_array($res)) {
$json_response[]=array("email"=>$row[2],"name"=>$row[3],"address"=>$row[5]);
echo json_encode($json_response); // not good to echo here
}
}
// echo json_encode($json_response); // ideally echo should be here
I am using PDO to access my data base and am looping using two while loops with fetch at the same time, seen below:
$DBH = new PDO('mysql:host=localhost;dbname=database;charset=utf8',$dblogin,$dbpass);
$sql = 'SELECT * FROM table';
$STH = $DBH->prepare($sql);
$STH->execute();
while ($bm_table = $STH->fetch(PDO::FETCH_ASSOC))
{
// SQL Query
$sql1 = 'QUERY HERE';
$STH1 = $DBH->prepare($sql1);
$STH1->execute();
// Loops through using different handle, but what if I used STH again?
while ($row = $STH1->fetch(PDO::FETCH_ASSOC))
{
SomeFunction($bm_table,$row);
}
}
As you can see above I am using a different statement handle ($STH, $STH1 etc.) Is this necessary? Or can I use just one statement handle for everything. The reason I have used multiple handles is as the $bm_table value that uses $STH, will still be in use while I am fetching $row wouldn't that change the value of $bm_table or stop the fetch from working? How does the handles with PDO work? Especially when in this case I have two simultaneous fetch loops running at the same time using the same PDO connection.
So the main thing I am looking for here is if I have two statements that are running simultaneously is it important that I use different handles when I continue to use the same connection?
$STH and STH1 are not statement handles, they're just PHP variables. You can reassign a variable if you no longer need its old value. But in the case of this code, you still need the old value.
If you assign $STH inside the outer loop to the handle returned by the second prepare() call, then when it gets back to the top of the loop and re-executes the $STH->fetch() test, it will try to fetch from the second query, not the first one. This will immediately end the outer loop because all those rows have been read.
You can reuse a statement handle for repetitions of the same query. This is very useful when the query has parameters:
$stmt = $DBH->prepare("SELECT * FROM tablename WHERE id = :id");
$stmt->bindParam(':id', $id);
foreach ($id_array as $id) {
$stmt->execute();
$row = $stmt->fetch();
// do stuff with $row
}
If I understand you correctly what you want is dynamic query?... just put a parameter on your method then...
something like this. call it as much as you want with difference parameters though.
Class SampleClass{
public function GetAll($tablename)
{
$sth = $this->prepare("SELECT * FROM $tablename");
$sth->execute();
return $sth->fetchAll();
}
}
This is a bit of a clueless-beginner type of question, so I apologise. But I've not managed to find a website or video that helps me understand working with MySQL prepared statements, so I'm hoping for some direct advice.
For the last couple of weeks of my learning, I've been using procedural MySQLi calls to make database queries, and working through them with while loops. Things like
$query = mysqli_query("SELECT * FROM `Shoes` WHERE `Color` = 'Red'");
while ($row = mysqli_fetch_assoc($query)) {
echo $row['size'];
}
Things like that. It makes sense to me that I would be execute a query, get returned a special results resource, and then use a 'fetch_something' function to turn it into an array I can pick from and loop over, regardless of its size.
Now I'm trying to learn about prepared statements. What's tripping me up is the 'bind_result' function that seems to get used all the time, at least in every book and tutorial I've consulted so far. It tells me to provide one variable per column, to which the result for that column will be bound. Like
$db = new mysqli(server,user,pass,database);
$stmt = $db->prepare("select `Temperature` from `BuildingDetails` where `HouseNumber` = ?");
$stmt->bind_param("i",$_GET['num']);
$stmt->execute();
$stmt->bind_result($x);
$stmt->fetch();
echo "The temperature in this house is {$x}.";
Simple enough when I'm retrieving a single value, or a single row. But what if I want to loop over a table with 20 columns and 5,000 rows? Is there a way I can just return a regular old MySQL result resource and use fetch_assoc or something on it?
Is there a way I can just return a regular old MySQL result resource and use fetch_assoc or something on it?
You can use mysqli_stmt_get_result
Procedural
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($result))
{
print_r($row);
}
OOP
$result = $stmt->get_result();
while ($row = $result->fetch_assoc())
{
print_r($row);
}
This way you do not have to bind all the variables to get results.
Here is my somewhat broken strategy
If it is a query with no input ( always the same ), just use query();
$results = $this->database_top->query( $query );
If a single row is returned and there is input, do the prep (not shown here) and use
$results = $pdoStatement->fetch(PDO::FETCH_ASSOC);
If multiple rows are returned and there is input,do the prep (not shown here) and use:
$results = $pdoStatement->fetchAll();
Problem I'm facing is that I need the first method to return an array or array of arrays like the second and third.
Prep looks like this FYI
$this->database_top->quote($query); // quote it
$pdoStatement = $this->database_top->prepare($query); // prepare it
$results = $pdoStatement->execute($parameterArray); // execute it
How can I modify my code so that all 3 methods return arrays or array of arrays?
Iterating over query()
$result_array = $this->DatabaseObject->_pdoQuery( 'multiple', 'tweet_model' );
foreach( $result_array as $array_1d )
{
$array_2d[]=$array_1d;
}
query does not return results, so I'm not sure what you meant on the first example. query returns a PDOStatement. It's basically the same as:
$qry = $db->query("...");
//equiv:
$qry = $db->prepare("...");
$qry->execute();
As vicTROLLA noted, the simplest solution is to just use:
$results = $stmt->fetch(PDO::FETCH_ASSOC);
However, if you need to process the results as you go for some reason, you could always loop over them manually.
$stmt = ...;
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
//use or return $results
$results will thus always be an array with 0 or more arrays inside of it.
I find it useful to build arrays where the array key is the primary key of the record:
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[$row['id']] = $row;
}
Also, I suspect that you've misunderstood the purpose and functionality of quote. It is used for escaping strings that you are going to interpolate into a query, not for magically escaping all values in a query (hence $db->quote($query) makes no sense).
Even worse is that drivers are not required to support quote. (Though it does at least return false if there's no support.)
prepare is massively preferred over quote.
In all of those cases, you can do
$arrayOfAssocArrays = $pdoStatement->fetchAll(PDO::FETCH_ASSOC);
To get the result from the database, you can do this:
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll();
foreach($result as $r) {
echo "<pre>";
print_r($r);
echo "</pre>";
}
but it seem to work without using fetchAll, example:
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$result = $sth->execute();
foreach($result as $r) {
echo "<pre>";
print_r($r);
echo "</pre>";
}
so what is the difference?
fetchAll will read in all rows from the database resultset and make an array out of them, keeping it all in memory. Iterating over the resultset will fetch one row at a time from the server which will save resources on the PHP side (but may use more resources on the database server, depending on the database implementation).
Firstly I assume that you are using php PDO
With fetchAll you can specify Fetch mode as an argument and fetchall provides more flexibility over the returned rows and fetchall will read all rows from database and translate into an array.
fetchall is lot more efficient in resource management compared to simple executes i guess. also the resource returned by execute is bool