tags:

views:

54

answers:

3

I was just wondering how i would be able to code perform an SQL query and then place each row into a new array, for example, lets say a table looked like the following:

$people= mysql_query("SELECT * FROM friends")    

Output:

| ID | Name | Age |   
--1----tom----32   
--2----dan----22   
--3----pat----52   
--4----nik----32   
--5----dre----65

How could i create a multidimensional array that works in the following way, the first rows second column data could be accessed using $people[0][1] and fifth rows third column could be accessed using $people[4][2].

How would i go about constructing this type of array?

Sorry if this is a strange question, its just that i am new to PHP+SQL and would like to know how to directly access data. Performance and speed is not a issue as i am just writing small test scripts to get to grips with the language.

+7  A: 
$rows = array();
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
    $rows[] = $row; 
}
Artefacto
A: 
$array = array();
$sql = "SELECT * FROM friends";
$res = mysql_query($sql) or trigger_error(mysql_error().$sql);
while($row = mysql_fetch_assoc($res)) $array[]=$row;
Col. Shrapnel
You should initialize the array, otherwise if there are no rows, the variable is not defined.
Artefacto
good point thanks
Col. Shrapnel
+1  A: 

Are you open to using a DB module, like the PEAR::DB module? If so, check out this article by Paul Dubois on Writing Scripts with PHP's Pear DB Module. The Module has been superseded, but it will show you the basics of some more advanced (and more commonplace) DB practices.

As for your actual question, you could iterate over all the rows and populate an array...

$dsn = "mysqli://testuser:testpass@localhost/test";
$conn =& DB::connect ($dsn);
if (DB::isError ($conn)) { /* ... */ }

$result =& $conn->query ("SELECT * FROM friends");
if (DB::isError ($result)){ /* ... */ }

while ($row =& $result->fetchRow()) {
   $people[] = $row;
}
$result->free ();

Or you could write an object which implements the ArrayAccess interface, requesting a particular row when you refer to that index. (This code could be completely wrong but here's my try)

class FriendsTable implements ArrayAccess {
    function offsetGet($key) {  
        $result =& $conn->query ("SELECT * FROM friends LIMIT $key, 1",); // careful; this is vulnerable to injection...
        if (DB::isError ($result)){ die ("SELECT failed: " . $result->getMessage () . "\n"); }
        $people = null;
        if ($row =& $result->fetchRow ()) {
           $people = $row;
        }
        $result->free ();
        return $people;
    }  

    function offsetSet($key, $value) {  
        /*...*/ 
    }  

    function offsetUnset($key) {  
        /*...*/ 
    }  

    function offsetExists($offset) {  
        /*...*/ 
    }
}

$people = new FriendsTable();
$person = $people[2]; // will theoretically return row #2, as an array

... or something.

LeguRi
I find it interesting that in your implementation of offsetget you use references for no good reason and then do not return by reference as you're supposed to (at least if you want something like $a = new FriendsTable(); $a["foo"]["bar"] = 42; to work). But otherwise, +1.
Artefacto
Ya, I copy pasted a little hastily out of the article I linked to, and I think it's meant more for PHP4... you recommend I remove the references, or should I add the return by reference?
LeguRi
There's really no reason to assign by reference to $result and $people. As to return by reference, that's the usual behavior of offsetget, so that stuff like $a["foo"]["bar"] = 42, $a["foo"]->bar = 42 or unset($a["foo"]["bar"]) has any effect. To be fair, in this case, there's really not much of point, since you're returning new data every time. It would make sense if you stored the result in a class property and then returned the property value.
Artefacto