PDO - Notice: Trying to get property of non-object - php

What is the problem in this function?
function journeygetLeadertalks($link, $journeyid)
{
$thingResult = $link->prepare("SELECT `leadertalks` FROM `journey` WHERE journeyid=:journeyid");
$thingResult->execute([
"journeyid" => $journeyid
]);
if($thingResult->fetchObject()->leadertalks == "NULL")
return "imgs/noimg.png";
else
return $thingResult->fetchObject()->leadertalks;
}
Database picture:
This function works every time exepct when im using it for leadertalks and leadertalksImage, what can I do?

The problem is that you're calling fetchObject() twice. You're calling it once in the if, and then if the value doesn't match, you're calling it again in the else. But your query only returns one row, so the second fetchObject() returns false, and that's not an object. You need to save the result in a variable.
Also, if the query doesn't match anything at all, the initial fetchObject() will return false, so you should check for that as well.
$row = $thingResult->fetchObject();
if ($row && $row->leadertalks == "NULL") {
return "imgs/noimg.png";
} else {
return $row->leadertalks;
}

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/PDO : No result if a column = 0?

I have a very simple function to check in the DB if we know an Artist (based on a unique ID) and if it's the case, I want to collect his infos :
function isArtistKnown($id_artist){
global $pdo;
$isKnownQuery = $pdo->query("SELECT * FROM artistes WHERE IDArtiste = '$id_artist'");
if($isKnownQuery->rowCount() > 0){
$KnownArtiste = $isKnownQuery->fetch(PDO::FETCH_OBJ);
return $KnownArtiste;
}else{
return $isKnownQuery->errorInfo();
}
}
The problem is following :
If the IDArtiste is known and another colmun called "last_tweet' (INT50) equals 0 then the PDO finds 1 result and $KnownArtiste is filled.
Now, If the IDArtiste is known but the colum "last_tweet" != 0 then the PDO doens't find any result (and errorInfo() equals 0000, which means : no error).
Do you have an idea where the problem comes from ?
The documentation states :
PDO::query() executes an SQL statement in a single function call,
returning the result set (if any) returned by the statement as a
PDOStatement object.
Which means, if there's no match, it returns no rows!
Quoting directly from the PHP PDOStatement::rowCount page:
PDOStatement::rowCount() returns the number of rows affected by the
last DELETE, INSERT, or UPDATE statement executed by the corresponding
PDOStatement object.
If the last SQL statement executed by the associated PDOStatement was
a SELECT statement, some databases may return the number of rows
returned by that statement. However, this behaviour is not guaranteed
for all databases and should not be relied on for portable
applications.
You can't use rowCount with SELECTs. Use this instead:
function isArtistKnown($id_artist){
global $pdo;
//If you don't use prepared statements, a kitten and a puppy die somewhere
$isKnownQuery = $pdo->prepare("SELECT * FROM artistes WHERE IDArtiste = :ida");
$isKnownQuery->bindValue(':ida', $id_artist);
$isKnownQuery->execute();
$KnownArtiste = $isKnownQuery->fetch(PDO::FETCH_OBJ);
if(isset($KnownArtiste->IDArtiste)){
return $KnownArtiste;
}else{
//Actually, in this case there's no error, just no artist
//so i'd use
return null;
//instead of
//return $isKnownQuery->errorInfo();
}
}
If you're going to return errorInfo() it'll always contain data whether there is an error or not. You should be returning a friendly user message to state that there are no rows found (the artist is not known to you)
function isArtistKnown($id_artist){
global $pdo;
$isKnownQuery = $pdo->query("SELECT * FROM artistes WHERE IDArtiste = '$id_artist'");
if ($isKnownQuery->rowCount() === 0){
return false;
}
$KnownArtiste = $isKnownQuery->fetch(PDO::FETCH_OBJ);
return $KnownArtiste
}
and validate:
$Validate = isArtistKnown(0);
if ($Validate === false){
echo "Artist is Not Known";
}else{
//Work with your data
}

How to use array from one function, inside another function

I'm new to the world of OOP and PDO and just need a bit of a hand when returning data in one function and wanting to use that inside another function.
Below is my function to get all gecko data from my database, at the moment i have it printing out the array so i know it's working.
function getGecko:
public function getGecko($geckoName){
$dbh = $this->dbh;
try {
if (!$geckoName) {
throw new Exception("No gecko name set!");
}
$stmt = $dbh->query("SELECT * FROM geckos WHERE gecko_name = '$geckoName'");
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$row_count = $stmt->rowCount();
$row = $stmt->fetch();
if($row_count > 0){
print_r($row);
return true;
} else {
echo 'No information found for '.$geckoName.'!';
return false;
}
}
catch (Exception $e) {
echo $e->getMessage();
}
}
which outputs as - Array ( [gecko_id] => 1 [gecko_name] => Zilly [gecko_aquisition_date] => 0000-00-00 [gecko_type] => Normal [gecko_gender] => Male [gecko_traits] => [gecko_bio] => Hench bastard [gecko_health_check] => All good! [gecko_bred] => 0 [gecko_hatchling] => 0 [gecko_clutch] => [gecko_photo] => ) - no problem.
But i want to use that data inside a function called getMorph to utilise [gecko_type] => Normal. I have tried things like:
public function getMorph($geckoName){
$this->getGecko($geckoName);
echo $row['gecko_type'];
}
But it returns nothing at all. I am quite used to php in the procedural sense, i'm just trying to better myself and my code and wanted to get stuck into OOP. I do apologise if this is considered a 'noob' question but as i say, i am trying to learn.
Thank you for your time :)
The problem with your first function is that you're returning a boolean value. No actual data is returned. Also, in the getMorph() function, you're trying to use the $row variable. This won't work as the $row variable only exists inside the local scope of the function getGecko(). This would actually cause PHP to print an error message. Had you enabled error reporting, you'd have found this out.
To fix the issue, you can modify your first function to return the array:
if($row_count > 0){
// print_r($row);
return $row;
} else {
echo 'No information found for '.$geckoName.'!';
return false;
}
Then, in your second function, you can access the array like so:
public function getMorph($geckoName){
// $morph now contains the entire array
// returned by the other function
$row = $this->getGecko($geckoName);
// output the array contents
echo '<pre>' . print_r($row, TRUE), '</pre>';
// return the specific gecko_type value
return $row['gecko_type'];
}
I suggest you read up on variable scope. It's going to be very useful. Also, completely unrelated the issue above, you're directly inserting the user input in your SQL query. Don't do that! Use parameterized queries instead - that way, you'll be able to avoid SQL injection attacks.
The following questions has more details on the subject:
How can I prevent SQL injection in PHP?
How does PHP PDO's prepared statements prevent sql injection?
Your function getGecko returns only a Boolean and $row is only a local variable in that method. So you can either change the return value to return the actual data or you can create a private variable in your PHP Class.
For changing the return type, you could in getGecko change that return to something like this:
if($row_count > 0){
// ...
return $row;
}
And then in your getMorph function do something like:
public function getMorph($geckoName){
$row = $this->getGecko($geckoName);
echo $row['gecko_type'];
}

php if sql query returns valid result

I'm sure this is a simple fix, I want to run a code block if an sql query comes back with a positive result. something like:
if($query = mysqli_query($cxn,"[query]"))
{
Code to be executed if the query returns a positive result
}
I have tried this format but doesn't work. I'm sure I have done this before but I'm running in to a wall here.
Hope you can help.
As stated in php.net/manual/mysqli.query.php, mysqli_query will:
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.
You should for you next question specify what you mean by positive result. But this code will see if there was an error, if the query returned an empty set, and so on... (I have not tried to run the code)
$result = mysqli_query($cxn,"[query]");
if ($result === FALSE) {
echo "There was an error";
}
else if ($result === TRUE) {
echo "The query was successful (a query that didn't return anything)";
}
else if (mysqli_num_rows($result) == 0) {
echo "The result is empty"
}
else {
echo '$result contains data';
}
So you mean if the query doesn't fail? then:
$query = mysqli_query($cxn, "[query]");
if($query !== false) {
// Code to be executed if the query returns a positive result
}

how to transform a function from mysql into mysqli

hello i would like to transform a mysql-function into a mysqli version. this function is for checking if an user exists or not. so i'm new to functions and even to mysqli. thats why i'm having problems while transforming it.
the mysql-version is:
function a($uname){
return (mysql_result(mysql_query("SELECT COUNT (`a`) FROM `table_1` WHERE `a`='$uname'"), 0) == 1) ? true : false;
}
the mysqli-version i thought would be:
function a($uname){
return (mysqli_num_rows(mysqli->query("SELECT COUNT (`a`) FROM `table_1` WHERE `a`='$uname'"), 0) == 1) ? true : false;
}
i know that there is no mysql_result anymore. i decided to use mysqli_num_rows. but this function does not work and i have no clue why. error_reporting is enabled but when calling the page, i will get a blank page with no error messages?!
so if there is someone who could help me out i really would appreciate.
thanks alot.
You need a helper function to put all dirty mysqli internals behind the scenes.
Like safemysql. It can mimic mysql_result as well:
function a($uname){
global $db; // with mysqi you have to connect once and then use this connection
return (bool)$db->getOne("SELECT COUNT (1) FROM table_1 WHERE a=?s"), $uname);
}
and can solve dozens of similar issues.
Freely from the documentation:
mysqli->query returns either a mysqli_result object for queries, which actually return some results, 'false' for failed queries and 'true' for all other queries (if successful).
You will not know anything about the result of your query, unless you check the result more thoroughly.
Try something like this: (This assumes that the connection has been successfully established, and that $uname has been properly escaped.)
function a($uname) {
$found = false;
$result = mysqli->query("SELECT `a` FROM `table_1` WHERE `a`='$uname'");
if($result) {
//We used a 'SELECT' query and the query was successful. That means, we now have a mysqli_result object.
$found = ($result->num_rows == 1); //Determines, if something was actually found or not.
$result->close(); //Frees some ressources. Not necessary, but doesn't hurt either.
} else { //The query failed, as such we have nothing to evaluate.
die("Queryerror: ".mysqli->error);
}
return $found;
}
I changed the query parameter from 'COUNT' to 'a', because otherwise 'num_rows' will ALWAYS return 1, even if the actual count is '0'. This way, it returns the number of matched rows, essentially return '0' for 'no match' or '1' for 'match'.

Categories