This is a function to return the username of logged users. However, I can't seem to troubleshoot what's going on and why I'm getting Notice: Array to string conversion in.. on the first if() statement.
function getuserfield($field, $link) {
$query = $link->prepare("SELECT `$field` FROM `users` WHERE `id`= :session_id");
if ($query->execute(array(':session_id' => $_SESSION['user_id']))) {
if ($query_result = $query->fetchAll(PDO::FETCH_ASSOC)) {
return $query_result;
}
}
}
As well as that, the whole page becomes unreadable (in terms of encoding). Naturally, I'd use it like so:
echo "<p>Greetings, you are logged in as:" . getuserfield('username', $link) . "</p>";
The Notice: Array to string conversion indicates that $_SESSION['user_id] is an array which I'm trying to access as a string.
$query->execute(array(':session_id' => $_SESSION['user_id']['id']))
Fixes this. Then calling the function with two foreach() statements.
Related
This question already has answers here:
Invalid argument supplied for foreach()
(20 answers)
Closed 1 year ago.
I have had problema with "foreach"...
<?php
/*** user ***/
$sql = "SELECT * FROM user WHERE user_login = '$login' ";
$users = selecionar($sql);
foreach($users as $user) {
$userId = $user['user_id'];
}
?>
<?php
$sqll = "SELECT * FROM cadastro WHERE user_id = '$userId' ";
$cadastro = selecionar($sqll);
foreach($cadastro as $cad) { ?> /* Line 41 */
..... HTML
<?php } ?>
If I register something in PhpMyAdmin this code shows the register. But if there's not register in DB the page shows
Warning: Invalid argument supplied for foreach() in C:\wamp64\www\banheiromovel\02-listagem\listagem_perfil.php on line 41
It looks like selecionar() returns something that isn't iterable if there are no results, like maybe null or false. (Remember that if your function doesn't reach a return statement it's going to return null.)
I think your two best options are either
Wrap the foreach in a conditional to make sure it's not empty before you try to iterate it
if ($users) {
foreach($users as $user) {
$userId = $user['user_id'];
}
}
Modify selecionar() so that it always returns an array, but just returns an empty array if the query returns no results.
I prefer the second one, personally. You can do this by initializing whatever variable you're fetching your query results into in the function to an empty array, then returning that variable after you (possibly) fill it with data.
Like this:
function selecionar(string $sql): array
{
$result = [];
// code that executes a query and fetches results,
// adding the rows to $result if there are any
return $result;
}
Also, you should be executing those queries using prepared statements. Inserting input into the SQL string like that is not safe.
Try the following
/*** user ***/
$sql = "SELECT * FROM user WHERE user_login = '$login' ";
$users = selecionar($sql);
if ($users) {
foreach(array($users) as $user) {
$userId = $user['user_id'];
}
}
?>
I had the same problem and i resolved by adding an array() .
I am just testing out a data set I am looking to return from the DB.
I am running this in command line mode. When I var_dump() the data, I can see data being returned, but when I try to traverse the array, which has duplicate data in it, I get the warning message below and can not print the array item.
I am sure to some that is obvious to some, but I do not know why this is happening. I am sure I am doing something wrong here...but what?
Consider:
$link = mysqli_connect("localhost","username","password","mydatabase") or die("Error " . mysqli_error($link));
$query = "SELECT * FROM citizen_application";
$execute = $query or die("Error in the consult.." . mysqli_error($link));
//execute the query.
$result = $link->query($execute);
$data = mysqli_fetch_array($result); // also tried mysqli_fetch_assoc() and the issue persists
//display information:
//var_dump($data); //This show duplicates in the array returned???
foreach($data as $data_unit){
print_r($data_unit["dob"]."\r");
}
The warning in the logs:
Illegal string offset 'dob'
There seems to be no way to do this with a foreach() when running the script in command line mode. But I found a solution below that gives me what I was looking for:
while($data = mysqli_fetch_assoc($result)) {
print_r($data["dob"]."\n");
}
I noticed all the examples in the documentation where doing this way. I thought it was just a preference. It does not seem so. I hope this helps someone else, because this was quite irritating. You used to be able to do this easily with the previous mysql functions.
mysqli_fetch_array returns an array, you're traversing the array with the foreach, $data_unit will most likely be a single element and not an array... try just
foreach($data as $data_unit){
echo $data_unit."\r";
}
or use mysqli_fetch_assoc() and try
foreach($data as $fieldname => $data_unit){
echo "$fieldname = $data_unit\r";
}
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'];
}
I'm trying to check if a row exist in my db like this:
$uid = $_GET['queryString'];
if(isset($_GET['queryString'])) {
echo "New: ".$uid."<BR>";
$query = "SELECT * FROM stuff WHERE $uid";
// Escape Query
$queryE = $db->real_escape_string($query);
$results = $db->query($queryE);
if(($results->num_rows) > 0) {
echo "NO!";
}
else
{
echo "Make new row";
}
}
else
{
echo 'Error!';
}
But I keep getting the error: Trying to get property of non-object in ....
So if it exist I do one thing, if it doesn't I do the other, i've been searching for about an hour to find the cause, maybe I'm mixing up old PHP4 with my PHP5 stuff?
I've tried a lot, tried some examples but tend to get the error: mysql_fetch_array() expects parameter 1 to be resource, string given
Or should I check it in the query itself?
What line is the error on?!
If it is on the real_escape_string line, you haven't instantiated $db properly.
If it is on the $results->num_rows line, try changing
$results = $db->query($queryE); to:
if(!($results = $db->query($queryE))) {
echo 'Make new row';
} else {
// user likely exists, check $results
}
Also, you need to clean up the way you check the query string -- just process the query variable you want, rather than the whole string. Suggest also to use a different name for the query variable and the table column.
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'];
...
}