2

I have a function that fetches some rows based on the sql query into an array. That array is returned from a function, How can I traverse all the elements of the returned array? I am a beginner in Php.

function get_user_wants($user_id)
{
$query=mysql_query("select product_id from user_wishlist where user_id= $user_id");
return mysql_fetch_assoc($query);
}

$out=get_user_wants($user_id);
print_r($out);

It only prints the first element, or the first record !

Faizan
  • 1,847
  • 8
  • 40
  • 63
  • Use PDO instead, you then can easily iterate over the result. Also you function is missing the database connection so it does not work with multiple connections. – hakre Dec 30 '12 at 17:50
  • The mysql* series of functions is deprecated. Use [PDO](http://php.net/manual/en/intro.pdo.php) instead. – nico Dec 30 '12 at 17:53
  • You should either use PDO or mysqli. The mysqli extension is almost the same as the old mysql extension. Please read [Choosing an API](http://www.php.net/manual/en/mysqlinfo.api.choosing.php) in the PHP docs. – Arnold Daniels Dec 30 '12 at 17:55
  • 1
    mysql_fetch_asssoc returns a single **ROW** of the result set. it doesn't return the entire set. – Marc B Dec 30 '12 at 18:06
  • So how mysql_fetch_assoc differs from mysql_fetch_array? – Faizan Dec 30 '12 at 20:31

4 Answers4

4

Try something like this:

$sql = "select product_id from user_wishlist where user_id= $user_id";
$res = mysql_query($sql) or die("FAIL: $sql BECAUSE: " . mysql_error());;
while ($row = mysql_fetch_assoc($res))
{
    print_r($row);
}

And in case you haven't already noticed it, someone will flame you about using MySQL instead of a different thing like MySQLI or PDO. Don't let them bother you. The point here is that your query returns potentially many rows, and you need some kind of iterator to retrieve all of the rows so your script can process them.

In the instant case, there will be one product_id element in each $row array. Once you see the output of the print_r() function, it will probably be obvious how you might change the code. This might turn out to be what you want (I think).

function get_user_wants($user_id)
{
    $sql = "select product_id from user_wishlist where user_id= $user_id";
    $res = mysql_query($sql) or die("FAIL: $sql BECAUSE: " . mysql_error());;
    while ($row = mysql_fetch_assoc($res))
    {
        $out[] = $row['product_id'];
    }
    return $out;
}
Salman A
  • 262,204
  • 82
  • 430
  • 521
Ray Paseur
  • 2,106
  • 2
  • 13
  • 18
  • Please feel free to correct my parse error -- unbalanced parentheses on the while() iterator. – Ray Paseur Dec 30 '12 at 17:59
  • Actually I got it working now, Basically I wanted to manipulate the received array outside the function. anyway its done now. – Faizan Dec 30 '12 at 18:06
  • @Ray: you should be able to edit your answers using the edit button below the answer. Also, avoid displaying MySQL errors on production environment (perfectly acceptable on development servers). – Salman A Dec 30 '12 at 21:19
  • @SalmanA: All good points. I have a roast in the oven and a football game on TV, so I'm not editing posts or worrying about hairsplitting details right now -- I'm building a fire and relaxing with my family and friends. Have a good New Year 2013. – Ray Paseur Dec 31 '12 at 00:09
2

You are returning the result of a single call to mysql_fetch_assoc() so you will only ever get the first row.

Loop over them to create a multidimensional array, then return:

function get_user_wants($user_id)
{
    $query=mysql_query("select product_id from user_wishlist where user_id= $user_id");
    $rows = array();
    while($row = mysql_fetch_assoc($query))
    {
         $rows[] = $row;
    }
    return $rows;
}

Now you can loop them with foreach:

$list = get_user_wants(99);
foreach($list as $product)
{
    print_r($product);
}

Side note: the mysql_* library is deprecated, it is recommended to upgrade to MySQLi or PDO.

MrCode
  • 63,975
  • 10
  • 90
  • 112
2

You can't. The function is only returning the first result. And no more information.

So you need to return something different, for example the result resource:

function get_user_wants($user_id)
{
    $query = mysql_query("select product_id from user_wishlist where user_id= $user_id");

    return $query;
}

You can then iterate over it:

$result = get_user_wants($user_id);

while ($out = mysql_fetch_assoc($result))
{
    print_r($out):
}

A better way then is to wrap the result in an Iterator:

function get_user_wants($user_id)
{
    $query = mysql_query("select product_id from user_wishlist where user_id= $user_id");

    return new MySqlResult($query);
}

$result = get_user_wants($user_id);

foreach ($result as $out)
{
    print_r($out):
}

Such an result iterator could look like:

/**
 * MySql Result Set - Array Based
 */
class MySqlResult implements Iterator, Countable
{
    private $result;
    private $index = 0;
    private $current;

    public function __construct($result)
    {
        $this->result = $result;
    }

    public function fetch($result_type = MYSQL_BOTH)
    {
        $this->current = mysql_fetch_array($this->result, $result_type);
        return $this->current;
    }

    /**
     * Return the current element
     * @link http://php.net/manual/en/iterator.current.php
     * @return array
     */
    public function current()
    {
        return $this->current;
    }

    public function next()
    {
        $this->current && $this->fetch();
    }

    /**
     * Return the key of the current element
     * @link http://php.net/manual/en/iterator.key.php
     * @return mixed scalar on success, or null on failure.
     */
    public function key()
    {
        return $this->current ? $this->index : null;
    }

    /**
     * Checks if current position is valid
     * @link http://php.net/manual/en/iterator.valid.php
     * @return boolean The return value will be casted to boolean and then evaluated.
     * Returns true on success or false on failure.
     */
    public function valid()
    {
        return (bool)$this->current;
    }

    /**
     * Rewind the Iterator to the first element
     * @link http://php.net/manual/en/iterator.rewind.php
     * @return void Any returned value is ignored.
     */
    public function rewind()
    {
        $this->fetch();
    }

    /**
     * Count of rows.
     *
     * @link http://php.net/manual/en/countable.count.php
     * @return int The count of rows as an integer.
     */
    public function count()
    {
        return mysql_num_rows($this->result);
    }
}
hakre
  • 193,403
  • 52
  • 435
  • 836
  • Thanks, I usually go for the simplest solution , I think this is what I wanted. – Faizan Dec 30 '12 at 18:02
  • @Faizan: For a really simple solution, continue reading here: http://stackoverflow.com/a/11580420/367456 - Also take a look for PDO. It will make your life easier. – hakre Dec 30 '12 at 18:06
1

Try

foreach ($out as $key=>$value) 
  echo "$key: $value<br>";

as a starting point.

Eugen Rieck
  • 64,175
  • 10
  • 70
  • 92
  • Your example will only loop the columns of the first row given by `mysql_fetch_assoc` because it returns an associative array that corresponds to the fetched row and moves the internal data pointer ahead, only one roe at a time. – The Alpha Dec 30 '12 at 17:57
  • Yes, it won't give anything print_r did't do already - but this is the point: I read the OQ as "how to look inside the `print_r()` blackbox" - in most cases, you will not just want to echo the contents. This interpretation might be wrong ... in which case an edit to the OQ would be fine – Eugen Rieck Dec 30 '12 at 18:04
  • what is the difference between var_dump and print_r ? – Faizan Dec 30 '12 at 18:07
  • 1
    The output of the former is valid PHP code, the output of the latter is text. – Eugen Rieck Dec 30 '12 at 18:11
  • +1 My sense of this question is that the OQ needs a little support from our community on some basic things, and this response provides that. It's a human instinct to be haughty, imperious and condescending; a little wiser and more helpful to be compassionate. – Ray Paseur Dec 31 '12 at 00:12