PHP PDO fetch class returning FALSE - php

I have this PHP function that gets the data of the currently logged in user, or returns false if the visitor either isn't logged in, or has invalid user_id and password_hash cookies. For some reason, $q->fetch() always returns FALSE.
if( $_COOKIE['cuid']!='' && $_COOKIE['cuph']!='' )
{
try
{
$q = $db->prepare( 'SELECT * FROM users WHERE user_id = ? AND password = ?' );
$data = array( $_COOKIE['cuid'], $_COOKIE['cuph'] ); // id and password hash
$q->execute($data);
$num = count( $q->fetchAll() ); // in my case, $num is set to 1
if( $num == 1 )
{
$q->setFetchMode(PDO::FETCH_CLASS, 'User');
$user = $q->fetch(); // $user is set to FALSE for some reason
return $user;
} else {
return FALSE;
}
}
catch( Exception $e )
{
$db->rollBack();
echo 'Error: ' . $e->getMessage();
}
} else {
return FALSE;
}
Running that with exact data instead of placeholders in the query doesn't change anything, and running that query directly in my database returns 1 row, like it should. I checked, $num does indeed equal 1. I don't know why $q->fetch() returns FALSE, so any pointers would be very much appreciated.

You're already fetching all results using fetchAll(). The result set is thereby exhausted, you cannot fetch any more results from it. You simply want $q->rowCount() to count the rows or save the array returned by fetchAll() somewhere and use it later.

As said, you cannot use fetchAll then fetch after one query; but rowCount cannot be used for select. A solution can be:
You get results in an array with fetchAll:
$results=$q->fetchAll()
Then you can get and use or check the number, for example:
echo count( $results);
And get and work with results, for example:
foreach ($results as $result)
{
var_dump($result);
}

Related

SQL SELECT returns array but PHP considers that as null

I'm selecting something in mySQL via PHP and that command returns some array (which is right), but when I put that returning SELECT inside if condition and ask if it is returning null than PHP says it is returning null (which is not right, because it is returning array)
include '../db.php'; // my config
function select($command) {
global $db;
$sql = "".$command."";
$sqlDone = $db -> prepare($sql);
$sqlDone -> execute();
$data = $sqlDone -> fetchAll();
return $data;
}
$select = "SELECT likes.ID, likes.ID_user, likes.ID_post FROM likes WHERE likes.ID_user = '53' AND likes.ID_post = '2'"
if (select($select) == null) { // goes throw this
print_r(select($select)); // returns array
} else {
echo 'not null';
}
I tried to use !is_null and it doesn't work anyway.
I tried to put that select command with same values directly inside phpmyadmin and it returns array, so I'm confused. Can you help me out?
PDO's fetchAll() returns an array, if there are no results, it returns an empty array (not NULL).
Just use empty()
$return = select($select); //put this into a variable, because if you don't, you'll query the database twice and may get different results.
if (empty($return)) { // goes throw this
print_r($return); // returns array
} else {
echo 'not null';
}
Side note, your function doesn't really do anything special. You could achieve the same thing with this:
$return = $db->prepare($select)->execute()->fetchAll();
If you used a PDO wrapper, it could be even shorter. For example, using my own wrapper GrumpyPDO, you would use
$return = $db->all($select);
then if you had variables to pass to the query, you would do
$select = "SELECT likes.ID, likes.ID_user, likes.ID_post FROM likes WHERE likes.ID_user = ? AND likes.ID_post = ?"
$return = $db->all($select, [$userid, $postid]);

PHP return value if username exists

The problem I am having is that it always returns true no matter if the username passed in is valid or not.
$data = array($_POST["username"]);
$db = new PDO('mysql:host=localhost;dbname=Example;charset=utf8', 'Example', 'Example');
$stmt = $db->prepare("SELECT * FROM Table WHERE username=?");
$num_rows = $stmt->execute($data);
if($num_rows>0){
echo "true";
}
else{
echo "false";
}
$stmt->execute($data) returns TRUE on success.
If you want to get the number of rows returned, you need to use fetchAll after the execute
USE SQL FUNCTIONS
SELECT COUNT(*) as uCount FROM Table WHERE username=? // you can change * to id, for example.
then check if($data['uCount'] > 0)
You can change your SQL statement a little bit and capture either true or false in return as query result.
SELECT count(username) > 0 as user_exists FROM Table WHERE username=?
Read the query result to find if it is true or false.
PDOStatement::execute() returns a boolean to indicate success; if you're using exception error handling it will always return true or throw an exception (recommended by yours truly).
You can fetch the results (assuming there's only one) like this:
if (($data = current($stmt->fetchAll(PDO::FETCH_ASSOC)) !== false) {
echo "yay";
// do stuff with $data
} else {
echo "sorry dude";
}
The use of current() returns the first element of the returned result set or false if there was none.
Update
If you only need to return true or false, it's better to do just this:
$stmt = $db->prepare("SELECT COUNT(*) FROM Table WHERE username=?");
if ($stmt->execute($data) && current($stmt->fetchAll(PDO::FETCH_COLUMN))) {
echo 'true';
} else {
echo 'false';
}
try this
$num_rows = $stmt->fetch(PDO::FETCH_NUM);

Count rows of a table using PDO

I was wondering, what is the best way to count the rows of a table with PHP using PDO?
Here is what I have, but not getting anything for $count.
$count = $con -> query("SELECT COUNT(*) FROM item_descr")->fetch(PDO::FETCH_NUM);
echo $count[0];
if (count($count)>0)
{
$subStatus = "The email introduced is already in our database.";
}
There's no reason to use the PHP count() function on the array returned by fetch(). The count has already been calculated in SQL, so you want the value stored in the result, not the count of results.
Here's how I would write it:
$countStmt = $con->query("SELECT COUNT(*) FROM item_descr");
if ($countStmt === false) {
// do something to report the error
}
$count = 0;
while ($row = $countStmt->fetch(PDO::FETCH_NUM)) {
$count = $row[0];
}
if ($count > 0)
{
$subStatus = "The email introduced is already in our database.";
}
Always check that the return value from query() is a valid PDOStatement. Any error causes it to return false, and the scalar value false is not an object with a fetch() method.
In other words, you can't make the call in a fluent interface manner ($con->query()->fetch()), because query() is not guaranteed to return an object.
$count = $con->query("SELECT COUNT(*) as `num` FROM `item_descr`")
->fetch(PDO::FETCH_ASSOC);
echo $count['num'];
if ( $count['num'] > 0 )
{
$subStatus = "The email introduced is already in our database.";
}
would work.
If you do a COUNT in your query, you will ALWAYS have just ONE result, namely the number of rows. So count( $result) will always give you 1. In my example I use the COUNT from the query.

Why PDO does not show any result?

I've used PDO in my PHP application. But I have problem with fetch() function. Whenever I count the result of fetch(), it tells me there is something in resultset. But when I want to show them, it has nothing to show.
try
{
$sql = "SELECT id,salt FROM tbl_admin WHERE username = ? AND password = ? LIMIT 1";
$q = $db->prepare($sql);
$q->execute(array($username,$password));
$rows = $q->columnCount();
if ($rows > 0)
{
$r = $q->fetch(PDO::FETCH_BOTH);
echo(count($r).'<br />'); // Prints 1
print_r($r); // Nothing to print ...
die();
}
else
{
die('error');
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
May you help me please?
You're counting the number of columns, not the number of rows.
$rows = $q->columnCount();
This should be
$rows = $q->rowCount();
That said, rowCount is for UPDATE, INSERT, or DELETE queries. So that isn't the problem here.
Firstly should also be checking if $q->execute returns true or false.
Secondly you should be checking if $q->fetch returns true or false.
Given your code
$r = $q->fetch(PDO::FETCH_BOTH);
echo(count($r).'<br />'); // Prints 1
Try the following.
echo(count(false));
You'll notice that this also outputs 1.
So the solution is, that you need to check the return value of $q->fetch before assuming it returned a valid row.

Extract a mysql resource to php array?

My goal is to display the profile of a user. I have this function:
function get_profile($un) {
if($registerquery = $this->conn->query("SELECT * FROM table WHERE usr = '".$un."' ")){
return $profile = mysql_fetch_array($registerquery);
}
}
Then the display snippet:
<?php $profile = $mysql->get_profile($un);
foreach($profile as $key => $value){
echo "<span>".$key.': '.$value."</span><br />";
}
?>
But I get: "Warning: Invalid argument supplied for foreach() in..."
Help pls???
You need to see if the result was a success or not
if (gettype($result) == "boolean") {
$output = array('success' => ($result ? 1 : 0));
}
And you need to cycle through it if it's a resource type...
if (gettype($result) == "resource") {
if (mysql_num_rows($result) != 0 ) {
while ($row = mysql_fetch_assoc($result)) {
$output[] =$row;
}
}
}
I chopped up some real code that does basically everything pretty awful for you because I can't release it, sorry.
Check the result of get_profile, as it will return null if the query failed. You can't loop over null.
Be very very careful here. You are passing a raw string into the query function without escaping it and without using a parameterized query. Use mysql_escape_string around $un in your query. Your code flaw is called a sql injection attack.
Someone could pass their username as this
myusername'; update users set password = '';
And blank all passwords, thereby allowing themselves to access any account. Other similar shady attacks are equally likely.. you can basically do anything to a database with sql injection attacks.
I Agree with Anthony Forloney. The following code is just returning TRUE or FALSE depending on wether loading the $profile variable worked:
return $profile = mysql_fetch_array($registerquery);
You don't need $profile. You can eliminate it as such:
return mysql_fetch_array($registerquery);
The function will return the array and then when you call the function later you can load it's return value into $profile as you do with the following:
$profile = $mysql->get_profile($un);
Try this:
function get_profile($un) {
if($result = $this->conn->query("SELECT * FROM table WHERE usr = '".$un."' ")){
return $result->fetchArray(MYSQLI_ASSOC);
}
return array();
}
You're mixing MySQLi and MySQL functions and you can't do that. And, the last line of this code will return an empty array if the query does not work, rather than return null.
It is probably empty ($profile). Print the value of "count($profile)"
I have found that the easiest way to loop through mysql results is to use a while loop:
$select = "SELECT * FROM MyTable";
$result = mysql_query($select);
while ($profile = mysql_fetch_array($result)) {
$name = $profile['name'];
...
}

Categories