Extract a mysql resource to php array? - php

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'];
...
}

Related

Warning: Invalid argument supplied for foreach() in - What can i solve this? [duplicate]

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() .

Stop SQL from inserting duplicates (php)

It seems to be impossible to do this just with SQL statements, so I wrote a php check, which is completely ignored by the script. $resourse array holds the right data.
public function handleUpdates($updates) {
$stmt = $this->database->connect()->prepare("SELECT ? FROM users"); //<-
$stmt->execute(["username"]); //<-
$resource = $stmt->fetch(PDO::FETCH_ASSOC); //<-
foreach ($updates["result"] as $update) {
$text = $update["message"]["text"];
$args = $update["message"]["chat"]["username"];
if ($text === "/start") {
if ($resource['username'] !== $args) //this here is ignored
$this->database->add($args);
}
}
}
From what I remember about PDO/SQL (I moved to MVC/Doctrine a while back), this part seems a little redundant
$stmt = $this->database->connect()->prepare("SELECT ? FROM users"); //<-
$stmt->execute(["username"]); //<-
and could be replaced with
$stmt = $this->database->connect()->prepare("SELECT username FROM users"); //<-
as you're only ever wanting to get the data found in the username column there's no need to bind it (which isn't fully possible in PDO anyway).
The reason your query fails is that you are using fetch over fetchAll which returns only the first row of results, while this will run it won't give the desired result (which I'm guessing is to check if the username already exists). Even then (as Ivan Vartanyan points out), you would need to foreach or in_array over $resource as it's results are sent as an array anyway.
Realistically you don't need to search and iterate over all the data in PHP, consider searching for your passed username data with SQL instead (code untested);
public function handleUpdates($updates) {
$stmt = $this->database->connect()->prepare("SELECT username FROM users WHERE username = ?");
$stmt->execute(array($update["message"]["chat"]["username"]));
$resource = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$resource) {
foreach ($updates["result"] as $update) {
$text = $update["message"]["text"];
$args = $update["message"]["chat"]["username"];
if ($text === "/start") {
$this->database->add($args);
}
}
}
}

php -$result->fetch_array does not work

I am trying to select a table within my database with a GET Method.
Now when I hardcode the value of the variable in there (the table name) it works as expected and it returns the values in an array.
But when I try to determine the table name through a variable, I get the following error:
Fatal error: Call to a member function fetch_array() on a non-object in
Now I have tried the var_dump($result); but that returns bool(false).
Now the variable does carry a value, because when I echo it back to the screen it gives the value I would expect.
So why does not return the value when making the query for my table search???
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); //This where a change needs to happen
var_dump($result);
$posts = array();
while($row = $result->fetch_array())
{
$ID=$row['ID'];
$sermonTitle=$row['sermonTitle'];
$sermonSpeaker=$row['sermonSpeaker'];
$sermonSeries=$row['sermonSeries'];
$sermonDate=$row['sermonDate'];
$linkToImage=$row['linkToImage'];
$linkToAudioFile=$row['linkToAudioFile'];
$posts []= array (
'ID'=> $ID,
'sermonTitle'=> $sermonTitle,
'sermonSpeaker'=> $sermonSpeaker,
'sermonSeries'=> $sermonSeries,
'sermonDate'=> $sermonDate,
'linkToImage'=> $linkToImage,
'linkToAudioFile'=> $linkToAudioFile
);
}
$response['posts'] = $posts;
var_dump($posts);
PS I have read about the depreciation in mysql style and that I know have to use mysqli writing. I am running PHP Version 5.2.6-1+lenny16
If the $series is a string you need to put quotes around the variable..
Try...
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = '". $series ."'");
Hope it helps.
Now I have tried the var_dump($result); but that returns bool(false).
Because your query failed.
Try:
if( ! $result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); ) {
echo "An error has occurred: \n" . var_export($mysqli->error_list, TRUE);
} else {
//do stuff
}
The central question seems to me: Where does $series come from? Where does that variable ever get initialized?
If you're passing this in from the web form, two things: either use $_GET or $_POST (whatever action you use in your form). And then you have to sanitize what comes from there, in order to not be vulnerable to SQL injection attacks. Prepared statements are your friend in this case; they help harden your script against this kind of attacks.
try this
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = '$series' ");
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); //This where a change needs to happen
You should be using Prepared Statements if the variable: $series is user defined.
$result->prepare("SELECT * FROM PodcastSermons WHERE `sermonSeries`=?");
$result->bind_param('s', $series);
$result->execute();
Also, Print_r($result); to check if your initial $result to see if it has been populated; Furthermore, in your SQL Query is sermonSeries properly matched to your SQL Table?
Update:
while($row = $result->fetch_array())
{
Try Modifying this to:
while($row = $result->fetch_array(MYSQLI_ASSOC))
{
http://uk1.php.net/manual/en/mysqli-result.fetch-array.php
your query simply fails. check var_dump($series); before executing.
i assume it might be a string and you just don't quote it?
just a tip: first build a string with your commandtext before
calling $mysqli->query. and use that string (like $mysqli->query($cmd);
dump that string :) might open your eyes ;)
that way you can extract it and execute it directly against the database (f.e. phpmyadmin).

Jquery Autocomplete remote datasource

Im trying to use Jquery UI's autocomplete feature to query usernames on my database. So the user enters a username similar to one on my db and the autocomplete is suppossed to guess what they are looking for in a drop down. Unfortunately, I can't get the backend script to return suggestions.
<?php
sleep( 3 );
// no term passed - just exit early with no response
if (empty($_GET['term'])) exit ;
$q = strtolower($_GET["term"]);
// remove slashes if they were magically added
if (get_magic_quotes_gpc()) $q = stripslashes($q);
$sql = "SELECT * FROM users";
$r = mysql_query($sql);
$items = array();
if ( $r !== false && mysql_num_rows($r) > 0 ) {
while ( $a = mysql_fetch_assoc($r) ) {
$username = $a['username'];
array_push($items, $username);
}
}
$result = array();
foreach ($items as $key=>$value) {
if (strpos(strtolower($key), $q) !== false) {
array_push($result, array("id"=>$k, "label"=>$key, "value" => strip_tags($key)));
}
if (count($result) > 11)
break;
}
// json_encode is available in PHP 5.2 and above, or you can install a PECL module in earlier versions
echo json_encode($result);
/* echo $items; */
?>
The script simply returns an empty array, even when it should return a result. I have no idea what is wrong here..
First let me say, querying the database and returning the entire table to sift through for your results is a poor method. The SQL queries will execute faster if they are filtering the data from the database. You have to call up the data anyways, why not filter it and return only the relevant results?
You need to send the query a Like parameter as in the following:
$sql = "SELECT * FROM users where username like :term";
(I'm using parameterized queries in this case which you should use to protect against SQL Injection attacks.)
You can also use the more precarious method as follows:
$sql = "SELECT * FROM users WHERE username = ". $term;
Reference for Parameterized Queries:
How can I prevent SQL injection in PHP?

PHP login return values

function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
//$values = array();
while($row = mysql_fetch_array($result))
{
return 'gg';
return(array($row['member_id']));
}
}
Not able to get the userlevel field.... nor anything....
Not sure exactly what your question is, but one problem is that you're returning from within this while loop:
while($row = mysql_fetch_array($result))
{
return 'gg';
return(array($row['member_id']));
}
In fact, you're returning twice from within the loop... so the procLogin() function will always return a value of "gg", unless something goes wrong with your SQL query.
In general, you should avoid return statements within any loop, as it creates confusion and can lead to unexpected results.
return(array($row['member_id']));
Looks wrong - it should be:
return($row['member_id']);
You shouldn't need to define the array in the return like that.
You also use mysql_fetch_array () which returns as a numerical index - the function you probably want is mysql_fetch_assoc which is much nicer to work with as it returns the values with the keys as the column name rather than a numerical index.
Here's it again with a few tidy ups:
function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
if ($row['member_id'] > 0)
{
return ($row['member_id']);
}
else
{
return false;
}
}
I'm thinking, based on your comments about the userlevel, that you want to return the entire array rather than just the member_id ? Here's a slight edit to Meep3D's answer above:
function procLogin($username,$password){
$query = "SELECT *
FROM members
WHERE login = '".mysql_escape_string($username)."'
AND passwd = '".mysql_escape_string($password)."'";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
if (mysql_num_rows($result) > 0)
{
$row = mysql_fetch_assoc($result);
return $row;
}
else
{
return false;
}
}
This should return an array of all your table columns, if you are looking for the userlevel, presumably you should be able to access it something like:
$loginInfo = procLogin("theband","password1");
//if ($loginInfo) or something similar here
$level = $loginInfo['userlevel'];
So are you getting anything returned? That is to say, is it actually going into the while loop?
I'd use a mysql_error() function call straight after the mysql_query call to see if anything went wrong there.
Maybe there was no connection made, for example.
Are you still having issues? If so try something like:
echo $query;
after you define the query, then copy+paste that into phpmyadmin to check if there are any valid returns from the database.
After that try placing:
if (mysql_error())
{
trigger_error ("MySQL Error: ". mysql_error(), E_USER_ERROR);
}
Just after you call mysql_query. This should trigger an error if there is one giving you details of what went wrong.

Categories