How to use store_result() to get the data? - php

I'm having trouble trying to use $stmt->store_result() after executing a prepared statement. The manual says "Transfers a result set from a prepared statement", but to where?
I would ideally like to use it, all nice and buffered in memory, like $mysqli->query() returns.
The PHP documentation examples make it seem like the only good reason to use store_result() is to get the number of rows.
Ideally, I need something that can get the entire result set from a prepared statement and do something like fetch_rows on it. I DID hack the mysqli_stmt class by extending it and adding a fetch_assoc function using some backwards methods, but I would really like to remove that hack if I can get all my data buffered into memory.
So I guess my short question is, I know what store_result() does, but how do you USE it?
(And honestly, I wouldn't even be using $mysqli->prepare() to get a stmt, if it wasn't so damn useful in preventing SQL injection attacks, sterilizing variables, and making my SQL look so nice and pretty with all those question marks.)

The only thing that store_result() does is it moves the result from MySQL into PHP memory. It's not very useful since you still need to fetch the results into PHP variables.
What you are looking for is get_result(). This function will fetch results from MySQL and store them in PHP memory, additionally returning a familiar mysqli_result object.
$stmt = $mysqli->prepare('SELECT ? as col');
$stmt->bind_param('s', $variable);
$stmt->execute();
// returns mysqli_result object
$result = $stmt->get_result();
// loop to get associative rows
foreach ($result as $row) {
echo $row['col'];
}

Related

PDO storing FetchAll result in variable vs using directly in foreach

So curiosity got to me. I always try to avoid creating variables that will only be used once, instead I try to use it directly (unless it's a lot of text, for example MySQL queries).
What I usually do is something like this:
$getSomethingSql = 'LONG SQL';
$getSomething = $dbConnection->prepare($getSomethingSql); // or query if no parameters are needed
// Some binds etc if needed
$getSomething->execute(); // if prepared statements are used
$something = $getSomething->fetchAll(PDO::FETCH_ASSOC);
foreach ($something as $s) {}
Now, the $getSomethingSql is only used once but is stored as a variable since it can be a long string and thus this looks better. However, I was curious if there is any advantage of using above versus the code below:
$getSomethingSql = 'LONG SQL';
$getSomething = $dbConnection->prepare($getSomethingSql); // or query if no parameters are needed
// Some binds etc if needed
$getSomething->execute(); // if prepared statements are used
foreach ($getSomething->fetchAll(PDO::FETCH_ASSOC) as $s) {}
Does these 2 codes do the same? And is there a (huge) performance difference, or is one of them cleaner?
Internally they'll do the same thing. The only difference is that in one case it will use your explicitly created variable to hold the results of fetchAll() and in the second case it will make use of a temporary variable.

How do I use prepared statements to store_result and then get_result? [duplicate]

When I use statements in PHP with mysqli library, before I fetch and bind_results I call the store_result.
After I've seen the mysqli_result class with methods like fetchArray/object etc.
So if I want use it, I call from mysqli_stmt object the method get_results... but if I call before the method store_result it give me an error of "non object" (get_result return false).
Es:
$s = $stmt->get_result(); //this work
but if I do
$stmt->store_result();
$s = $stmt->get_result(); //this not work, return false
So I'm trying to understand when I need to user store_result or get_result (and what is the right way) but in Mysql and php doc I didn't find nothing of useful.
PS: Can you explain why I should use the first or the second?
Use get_result whenever possible and store_result elsewhere.

Store_result and get_result for statement

When I use statements in PHP with mysqli library, before I fetch and bind_results I call the store_result.
After I've seen the mysqli_result class with methods like fetchArray/object etc.
So if I want use it, I call from mysqli_stmt object the method get_results... but if I call before the method store_result it give me an error of "non object" (get_result return false).
Es:
$s = $stmt->get_result(); //this work
but if I do
$stmt->store_result();
$s = $stmt->get_result(); //this not work, return false
So I'm trying to understand when I need to user store_result or get_result (and what is the right way) but in Mysql and php doc I didn't find nothing of useful.
PS: Can you explain why I should use the first or the second?
Use get_result whenever possible and store_result elsewhere.

Problems with converting mysql over to mysqli errors with mysqli_query & mysqli_fetch_row

Here is the edited script without errors. And the 2 fixes applied to it. To those who helped in part, thank you. To mentions that the code is unclear or messy is inconsequential. Given that most of the following is common structure in mysql queries. Even the example documentation for mysql followed this similar flow. Members who reply should negate from pointless internet banter. Its more worth your time, and my own to do so. Those who stayed on topic and assisted, I thank you.
For example:
$row = mysqli_fetch_row(mysqli_query($con, "SELECT test_table.points FROM test_table WHERE test_table.key = '" . $key . "'"));
if ($row[0] > 0){ // exists
Where $row will return a non-zero result if true. Otherwise 0 on false. There is little need to check mysqli_fetch_row and/or mysqli_query. Since checking $row in simplicity works fine. It is unneeded to check mysqli_fetch_row and/or mysqli_query individually in a general exists condition. It does accurately provide exist / does not exist results. There is no $result $row $query just $row.
The noted deviation to that normal flow was my desire to use call_user_func. And to poll in func and params through $_GET. Will be looking more at PDO. However, the clean code before exec should do alright job for now. Which is to clean before exec.
All in all, the code works just as it should. And have since written more to manage a mysql database. From write, write chunk, read, read chunk, delete, delete chunk.
Also to collect numbered records on request. For example say you have 6 records for the same John Smith. You can now collate and scan for differences in those records. Either for what you want, dont want, etc. Or if say you just want to blindly call the first 3 of those records for John Smith.
mysqli_fetch_row & mysqli_fetch_row fix :
FROM Calling $con outside function then into as per mysql. Which in mysqli does not work as expected. There was no error with the functions, over how $con was being handled.
TO Calling $con inside function with just the added global $con. May end up using $GLOBALS even for this.
Result : Calling $con outside function then in works fine in mysql. In mysqli it requires global be set within the function. ie global $con. Or it fails.
call_user_func non-critical error fix :
FROM call_user_func($func($_GET['user'],$_GET['key'],$_GET['points'],$_GET['type']));
TO call_user_func($func,$_GET['user'],$_GET['key'],$_GET['points'],$_GET['type']);
Result : Both lines execute correctly. From executed with a non-critical error. TO does the same thing, but with no following non-critical error.
Sample Output for both : user=MY_Name;key=34342$ee56i1;points=1234;type=
-- code removed as fixes solved the issues --
You are using call_user_func wrong read the manutal
call_user_func first parameter is the callback - in your case it's a function inside your class so it should be something like this:
If you have a non-static function in an object:
class Test{
public function doit($a){
echo($a);
}
}
$t = new Test();
call_user_func(array($t,'doit'),'asfaasfs');
and in static functions inside object:
class Test{
public static function doit($a){
echo($a);
}
}
call_user_func('Test::doit','asfaasfs');
You have a few problems.
$con is declared outside the class, and is thus not available inside the class. You need to pass it into the class (the better option), or specify it as a global (the quick+dirty option).
mysqli_fetch_row(mysqli_query($con,'...'))
This code is obviously converted directly from your old mysql_xx() code, but it's not great.
You're ignoring any possible error condition that is returned by mysqli_query(). This means that if it fails, it'll pass false into the mysqli_fetch_row() function, which will then fail with a meaningless error expects parameter 1 to be mysqli_result, rather than actually telling you what the error was in the query.
The thing is, because of my first point above, with $con not being set, mysqli_query() is failing, and this is why you're getting the error in mysqli_fetch_row().
Ideally, you should split this code out into multiple lines. Call mysqli_query() on its own, then do some error checking, then call mysqli_fetch_row() only once you know that the query actually worked.
Hope that helps explain what the problems are here. Solve those two points, and you should be well on the way to sorting the whole thing out.
Once you've got rid of those fatal errors, you should also take time to work on the problem that your code is vulnerable to SQL injection attacks. You're currently passing your $_GET variables directly into the query strings without any sanitisation. This will make your system very fragile and easy to hack. You should consider using Parameterised Queries, which is a feature of the mysqli library designed to make it easier to deal with variables in SQL queries in a safe and secure way.
Your class is pointless at the moment, perhaps stick to writing imperative style code as it will at least be cleaner.
At the moment, you should pass $con to your MYsql class to use itself as a resource, not try to access it as a global variable.
Your are not filtering your user's input either, this is dangerous and could lead to SQL injection attacks on your site.
I'd encourage you to read through these two articles, and once you grok them, I'd also encourage you to simply switch to using PDO with prepared statements. This will stop SQL injection attacks that your code currently allows.
http://net.tutsplus.com/tutorials/php/pdo-vs-mysqli-which-should-you-use/
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/

PHP, Using PDO with nested queries, results corrupted

I'm using PDO against MSSQL, and need to run nested queries. They are all prepared statements. If I try to use the fetch() method, it inner queries fail immediately, so I used fetchAll(). So, I get something like this, with Programs, Products and Budgets:
$pgm_stmt->execute();
$pgm_res = $pgm_stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($pgm_res as $pgmrow) {
$prod_stmt->execute(array($pgmrow['ID']));
$prod_res = $prod_stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($prod_res as $prodrow) {
$bdgt_stmt->execute(array($pgmrow['ID'], $prodrow['ID']));
$bdgt_res = $bdgt_stmt->fetchAll(PDO::FETCH_NUM);
foreach ($bdgt_res as $bdgtrow) {
... work here
}
}
}
OK, everything works the first time through, but when it loops back for the 2nd program, the product result set gets corrupted somehow. When I dump the $prod_res variable right after the fetchAll(), the values are randomly assigned from other parts of memory, bits of other arrays, etc. Of course it fails because the $prodrow['ID'] value is undefined, because that whole result set is mangled.
Can someone help me troubleshoot this? I'm stumped.
Thanks.
Not a bug, but a feature, see: https://bugs.php.net/bug.php?id=65945
This is the behavior of MSSQL (TDS), DBLIB and FreeTDS. One statement per connection rule. If you initiate another statement, the previous statement is cancelled.
The previous versions buffered the entire result set in memory leading to OOM errors on large results sets.
The previous behavior can be replicated using fetchAll() and a loop if desired. Another workaround is to open 2 connection objects, one per statement.

Categories