check if PDO query returns results - php

Assume I have this piece of code:
foreach($creds as $cred){
$prev_fut = $pdo->query("SELECT importo FROM incassi_prev WHERE
data_prev='$data_fut' AND incasso=0 AND
id_cre='{$cred['id_cre']}'")->fetch();
if(count($prev_fut)>0){
//I have found a result
}else{
//I have found nothing
}
}
NOTE: It is an internal query for my application with no data posted by user so I don't worry about SQL injections.
I use to check if count($prev_fut)>0 to see if the query is returning data (if I find any row in the db with these criterias).
My question is:
is this check enough to verify that the query has at least a result? Is it better to perform any other check?
The question is mostly coming from my thoughts about this being in a for loop and is related to the option of emptying/unset the $prev_fut array before starting a new iteration of for loop.

fetchColumn returns a single value of the next row in the result set. count counts the length of an array. Since fetchColumn can't return an array (for most database implementations), using count on it is wrong. You want to test whether $prev_fut is false or not. false would indicate that no result could be fetched, while anything else means a result was fetched:
if ($prev_fut !== false) ..
Having said that, you should really use a COUNT() in the database and check that value:
$result = $pdo->query('SELECT COUNT(*) FROM ...')->fetchColumn();
if ($result > 0) ..
It's much more efficient to have the database count and summarise the result than fetching an entire result set into PHP just for this simple check.

Related

can a result of $conn->query(...) be not null with 0 records

I came across the following in some old PHP code that I have to work on. My question is, are both those Ifs required? In other words, if a result is returned it must have returned greater than zero records, right? And the converse - meaning if $result is False, can I assume that no records have been found?
$sql = "SELECT * FROM houses WHERE ownerphone=$pn";
$result = $conn->query($sql);
if ($result) {
$count = $result->num_rows;
if ($count > 0){
....Stuff happens here...
} else {
...What happens here?...
}
} else {
...Other Stuff happens here
}
Yes, both are required.
if a result is returned it must have returned greater than zero records, right?
Wrong.
If you don't get a result then you got an error and you won't have an object to read the number of results back from.
You can get zero rows back from a successful request.
if $result is False, can I assume that no records have been found?
Well, yes. Sort of. That's why the if statement stops you checking to see if there are a number of rows if the result is False.
… but not getting rows back because there was an error is different to not getting rows back because there were none to find.
No, you can't assume this. $conn->query() returns false if there's an error trying to perform a query. A SELECT query that doesn't match any rows is not an error.
Errors include incorrect syntax in the query or problems communicating with the database server.
From the docs;
Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or
EXPLAIN queries mysqli_query() will return a mysqli_result object. For
other successful queries mysqli_query() will return TRUE.
This means that it will bascically never return null. The first check (if ( $result ) is just to make sure all went well, and you got some kind of a response from the database. The second one is to count your rows; getting a result doesn't imply your query actually returns data, because maybe you're searching for stuff that is just not there.

MySql PDO Prepared Select Statement - Counting Results within Classes via PHP count()

I have quite an issue I can not seem to solve. I am trying to get a row count from a select statement.
I should start by saying I have tried most all methods resulting from google searches on this issue.
I am using the result set so I would prefer not to make a second query.
The query uses a prepared select statement which seems to be a main issue if I understand it correctly.
I decided to try a simple approach using PHP's native count() function. Which lead me here because I finally reached the end of the rope on this.
On to the details...within a class of mine, I make the query like this.
// Create database connection
$database = DatabaseFactory::getFactory()->getConnection();
// Set and execute database query
$sql = "SELECT * FROM `service_orders` WHERE `agency_id` = :agency_id $filter ORDER BY $sort $order $per_page";
$query = $database->prepare($sql);
$query->execute($query_array);
// If results
if ($query->rowCount() > 0) {
$results = $query->fetchAll();
self::$order_count = "Count: " . count($results);
return $results;
}
// Default, return false
return false;
Findings
If I perform count($results) like I did above, I get the total rows in the database (Let's say 50).
If I print_r($results), it shows the array with the proper number of entries (Let's say 10) that of course differs from the total rows in the database.
How can these two differ? It's as if the count($results) is misreading the result array.
More Findings
Within my actual php page, I call the class to retrieve the data like this.
$results = OrderModel::getServiceOrders();
echo count($results);
Strangely enough, if I then perform count($results) it gives me the correct reading of the result array (which in my example here would be 10).
I am perplexed by this as the count function is being performed on the exact same array. The only difference is one is called on the array within the class, and the other is called on the array returned from the class.
Does anyone have any ideas on how to solve this or why there is the discrepancy when using count() in this instance?
Thank you all in advance!
James
Additional Info
This is another mind numbing scenario. If I return the count along with the actual results, I can access it on the page with the correct value (10 rows). Yet, if I set it into a session variable, and access it that way, the count is the whole data set (50 rows). How is it even possible these two values are not the same?!
$results = $query->fetchAll();
Session::set("order_count", $total[0]); // Yields 50 (incorrect)
return [
"results"=> $results,
"count"=> $total[0], // Yields 10 (correct)
];

simplest explanation of $query->row() and $query->result()

I'm quite annoyed with CI's behavior lately, may be because i'm little ignorant towards small stuff, now to the question :D. i'm making an application where i'm trying to get one single row using active records, now as a good programmer(i think) i try this
when i select such as login
if($query->num_rows() == 1)
{
// do something
}
// now when i make an update, that also a single row i tend to use this command
if($query->affected_rows() == 1)
{
// perform some action
}
// now i use this code when i've to get all entries of one single user
if($query->num_rows() > 0)
{
// show them
}
now many time i get error like "Call to member function num_rows() on non object"
can anyone please explain what to use, when to use and how to use, so that code igniter never gets made a me
1.num_rows()
num_rows() are result helper functions, they are used against a query resultobject, note that we don't use it like $this->db->num_rows(), instead we use it like:
$query = $this-query('query');
OR
$query = $this->db->get('tableName');
if($query->num_rows()>0){ ....}
Now lets see affected_rowS().
2. affected_rows()
affected_rows is a query helper function, they are used like $this->db->affected_rows(). Note that $this->db->affected_rows() yields valid result only after a valid db write operation. i.e insert, update and delete. The database class has a small hack that allows it to return the correct number of affected rows after a delete operation because MySQL "DELETE FROM TABLE" returns 0 affected rows.
3.$query->result()
This function returns the query result as an array of objects, or an empty array on failure.
i.e if you have more than one result you have to loop the result object like :
foreach ($query->result() as $row){....}
4.$query->row()
This function returns a single result row as an object. If your query has more than one row, it returns only the first row.
I hope my explanation is readable enough.. Although you could find all of these in CI docs with relevant examples.

How to get the type of a query statement in PDO?

In the MySQL Reference Manual, there's distinction between data definition statements and data manipulation statements.
Now I want to know if a query inserts a database record, updates one, deletes one or modifies the table structure and so on, or, more precisely, the exact number of affected rows, but only if it is applicable.
For example, the statement
SELECT *
FROM SomeTable
WHERE id=1 OR id=2
returns a number of affected rows (in this case 2), but with the SELECT statement, there's nothing modified in the database, so that number would be 0.
How to get the type of query?
I was looking for the same answer and stumbled across this article. It was last updated in August. In it, there is a section: "Determining the Type of a Statement" You basically can make the following assumptions: (copied from the article)
If columnCount() is zero, the statement did not produce a result set. Instead, it modified rows and you can invoke rowCount() to determine the number of affected rows.
If columnCount() is greater than zero, the statement produced a result set and you can fetch the rows. To determine how many rows there are, count them as you fetch them.
I'll save you the trouble and just paste the code sample here
$sth = $dbh->prepare ($stmt);
$sth->execute ();
if ($sth->columnCount () == 0)
{
# there is no result set, so the statement modifies rows
printf ("Number of rows affected: %d\n", $sth->rowCount ());
}
else
{
# there is a result set
printf ("Number of columns in result set: %d\n", $sth->columnCount ());
$count = 0;
while ($row = $sth->fetch (PDO::FETCH_NUM))
{
# display column values separated by commas
print (join (", ", $row) . "\n");
$count++;
}
}
I have been thinking of the same issue, and come to conclusion that I don't need no automation in this matter.
The only use for such an auto-detect is some magic function which will return number of affected rows. But such a magic, although adding a little sugar to the syntax, always makes code support a nightmare:
When you're calling a function, and it can return values of different types depends on the context, you cannot tell which one is returned at every particular moment. So, it makes debugging harder.
So, for sake of readability, just call appropriate function to get the result you need at the moment - affectedRows or numRows. It won't make your code bloated, but make it a lot readable.
I'm using this:
substr($statement->queryString, 0, strpos($statement->queryString, ' '));
where $statement is a PDOStatement object, a few things to note here are that you should verify before using this that $statement is a PDOStatement object, also we should probably take the strpos out of the substr statement in case strpos returns false, which would probably cause an error, finally, this only works with one word statement types, like SELECT, INSERT, etc and not multi-word statement types like ALTER TABLE

How to determine whether a particular resource has data

I am trying to figure out the proper way to get file location data (for display/editing) from MySQL with PHP. So far I've got these three parts. $resfile is a resource getting the actual array. Would I then test with an if statement, or would I have to use a while loop to iterate over the array (which, as far as I know, should only have ONE value)
First part:
$resfile = mysql_query('SELECT file_loc WHERE org_id = '.$org);
Do I use this?
if (!$resfile) {
}
Or this?
while ($filerow = mysql_fetch_array($resfile)) {
}
Or both?
The mySQL library has a function for counting the rows of a result set:
if (mysql_num_rows($resfile) > 0) .......
You need to use both. If the query returns false, then there was an error executing your query. If there is no data returned in the query, (it will still return true) then you need to use fetch_array to get the data.

Categories