I'm using PDO to get an array of relations from my DB.
$dbRelaties = $dbh->query("SELECT pkRelatieId,naam,email FROM relaties");
in another function i need to acces one specific row in this array. I've managed to do it like this:
$klant = array();
foreach($dbRelaties as $dbRelatie)
{
if($dbRelatie["pkRelatieId"] == $relatie){ $klant = $dbRelatie; break; }
}
sendMail("Subject",$klant);
The above code works. But i'me looking for a neater solution and a quicker one, the above code is called in a function and that function is called inside a loop. So everytime it executes is has to loop through $dbRelaties to get the correct relation.
Can anyone set me in the right direction?
assuming the pk means primary key, then
while($row = mysql_fetch_assoc($result)) {
$dbRelatie[$row['pkRelatieID']] = $row;
}
would produce an array keyed with your primary key field, so
$dbRelatie[$pk]['naam']
will give you that particular pk's naam value.
To show a PDO specific version of Marc B's answer.
Assuming a query was executed through PDO like so:
$sql = "SELECT pkRelatieId,naam,email FROM relaties";
$resultSet = $pdo->query($sql);
The results can be read into a PHP array using PDO's fetch method.
$dbRelaties = array();
while ($row = $resultSet->fetch(PDO::FETCH_ASSOC)) {
$dbRelaties[$row['pkRelatieID']] = $row;
}
This can then be used to access values based on the PK of the row.
sendMail("Subject", $dbRelaties[$relatie]['naam']);
Furthermore. PDO lets you assign a default fetch mode to each PDO instance, and the PDOStatement class is Traversable, so that you don't actually have to call the fetch() method in a while loop to go through a result set.
If you were to do this to a PDO object before a query: (Ideally only once right after creating the object.)
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
Then you can use a foreach loop on the result set to get row arrays with field names, instead of using a while loop.
$dbRelaties = array();
foreach ($stmt as $row) {
$dbRelaties[$row['pkRelatieID']] = $row;
}
Related
This is how I get one record with MySQLi:
$result = $db->query("...");
$image = $result->fetch_object();
Now I need to get the comments and pass it to the view. I'm using the following snippet right now, but it doesn't seem right:
$result = $db->query("...");
while ($row = $result->fetch_object())
$comments[] = $row;
I'm wondering if there's a way to remove the loop?
Is there something like:
$image = $result->fetch_object(((s)))
So then my code would look like:
$result = $db->query("...");
$comments = $result->fetch_objects();
The mysqli_result class provides a fetch_all method to collect the full result set. However, that method will only return associative or numeric arrays (or a hybrid), not objects.
It's not possible to get an array of objects using mysqli_fetch_all(). The available options are: indexed array, associative array, or both.
Consider using the PHP Data Objects (PDO) interface, which has many more fetch modes and is thus superior to MySQLi in that regard.
Without seeing your SQL, it's tough to say. There may be a better query you could use. Post your SQL and I'll take another look.
In terms of your SQL query, if your query returns multiple rows, then you have already fetched them with one db call.
I don't see a way to collect into an array all of the comments, but you can clean up your code with a custom function.
function get_all_rows_as_array(&$result)
{
foreach($result as mysql_fetch_assoc($result))
{
$array[] = $row;
}
return $array;
}
$result = $db->query("...");
$comments = get_all_rows_as_array($result);
I have been doing MYSQL just fine for a while now but am trying to learn how to do all that i know with PDO; what I am struggling with now is a simple SQL select, and then I loop through all the rows and dump the corresponding column values into a variable; and then I can do something with the variables for that row while in the loop; here is the way I used to do it with mysql:
$result42 = mysql_query("SELECT * FROM members");
while($row = mysql_fetch_array($result42, MYSQL_BOTH))
{
$user_id=$row['user_id'];
$user_name=$row['user_name'];
$email=$row['email'];
// do something with info for each user; like maybe echo their info...
}
I am attempting to do the same thing with PDO but not finding anything quite like what I am trying to do…
I found some code which uses fetchall and fetchassoc and seems to be putting it in an array; but I have no idea how to loop through the array and get each value on the row like i did with mysql above; and I am not even sure if the PDO that i have here can do that…
this is what I have:
$stmt = $dbh->prepare("SELECT * FROM members");
$products = array();
if ($stmt->execute()) {
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$products[] = $row;
}
}
All i want to do is end up cycling through each row getting the values, doing something with them and then moving on to the next row…
Can anyone help with this? Thanks...
as the question states.
I have implemented a function wherein it fetches multiple rows from a database (*1) and then (*2) instantiate each row as an Object. After instantiation, the Objects are then stored into an array and then return the result to caller function and then iterates through the result array and displays each Object and add html formatting for each.
Here is the snippet of the code:
function find_all() {
//(*1) Fetch 30 comments from DB
$sql = 'SELECT * FROM comments';
$sql .= ' ORDER BY datetime DESC LIMIT 30';
return find_by_sql($sql);
}
function find_by_sql($sql='') {
global $database;
$result_set = $database->query($sql);
$object_array = array();
while($row = $database->fetch_array($result_set)) {
//(*2) Instantiate each row to a Comment object
// and then stores each comment to an object array
$object_array[] = Comment::instantiate($row);
}
return $object_array;
}
//(*3) Format and display each result.
$comments = find_all();
foreach ( $comments as $comment ) {
// Not sure if syntax is correct.. anyhow..
echo "<li>$comment->get_text()</li>";
}
However, I like the above approach since it's cleaner, easier to read, maintainable, and more OOP. But the problem is it takes a longer time to display than just simply iterating through each result than display each result once it's fetched, like so:
while ($row = mysql_fetch_array($sql)) {
echo "<li>$row['text']</li>";
}
I know the reason behind why it is slow. What I want to know is there a better way to solve the problem above?
While caching might be a good idea, it won't help because I need an updated list every time the list is fetched.
I think it can be a little faster if the script gets only the part you are interested in the result set, because fetch_array() returns 2 arrays with the same result set: associative, and numeric.
By adding MYSQLI_ASSOC (if you use mysqli): mysqli_fetch_array($result, MYSQLI_ASSOC), or try with mysql_fetch_assoc(), the script receives only the associative array.
You can test in pmpMyAdmin to see the diferences.
Is there a PHP function to get the full result with a mysql query in a multidimensional array?
SELECT * FROM table
Usually I would make something like this:
$query = mysql_query = ("SELECT * FROM table");
while ($result = mysql_fetch_array($query){
echo $result[0];
}
You can create your own function like mysql_fetch_array_complete() and imagine that it's builtin ;-)
If you are using PDO to access mysql there is.
http://www.php.net/manual/en/pdostatement.fetchall.php
Otherwise you need to do it yourself.
$query = mysql_query = ("SELECT * FROM table");
$all_results = array();
while ($result = mysql_fetch_array($query){
$all_results[] = $result;
}
print_r($all_results);
The $all_results variable will be a multi-dimensional array with all the records.
You could always write your own function to do this, but it would often lead to an unnecessary iteration through the result set (once when you call your function, another time when you actually USE the resulting array).
Since you're in php5, you could create a database result class that implements the Iterator interface. Then, you can use your class in foreach () loops and have much of the ease-of-use that you get from an array.
As of PHP 5.3 there is a built in function:
fetch_all
I have this method in my db class
public function query($queryString)
{
if (!$this->_connected) $this->_connectToDb(); //connect to database
$results = mysql_query($queryString, $this->_dbLink) or trigger_error(mysql_error());
return mysql_num_rows($results) > 0 ? mysql_fetch_assoc($results) : false;
}
This works great for queries that return 1 row, but how can I get an array returned something like this?
$array[0]['name'] = 'jim'
$array[0]['id'] = 120
$array[1]['name'] = 'judith'
$array[1]['ID'] = 121
Now I know I could use a while loop to insert this data into the array like so, but I was wondering if PHP could do this with an internal function? I havn't been able to find on the docs what I'm after.
The reason I don't want to run the while within the method is because I am going to reiterate back over the array when it's returned, and I'd rather not run through the results twice (for performance reasons).
Is there a way to do this? Do I have a problem with my general query method design?
Thank you muchly!
public function query($queryString)
{
if (!$this->_connected) $this->_connectToDb(); //connect to database
$results = mysql_query($queryString, $this->_dbLink) or trigger_error(mysql_error());
$data = array();
while($row = mysql_fetch_assoc($results))
{
$data[] = $row;
}
return $data;
}
this will always return an array.
EDIT:
I didn't read the question well.
If you realy don't want to use the loop then I would do this:
public function query($queryString)
{
if (!$this->_connected) $this->_connectToDb(); //connect to database
return mysql_query($queryString, $this->_dbLink) or trigger_error(mysql_error());
}
then loop over it, however I would just use the loop.
You might also want to look at the PDO extension. You can load the entire result set into an array or you can loop using foreach.
<?php
$db = new PDO($connection_string, $username, $password);
$result = $db->query($queryString);
foreach($result as $row) {
// do something
}
// or
$result = $db->query($queryString);
$result_array = $result->fetchAll(PDO::FETCH_ASSOC);
?>
Most people use a while() loop in the query to do exactly what you want and then loop over the array to process it.
However, you're right: it wastes memory, which could be a problem with a large dataset. An alternative is for your query method to return the resultset resource. Then your while loop can use that to fetch each row as it requires it.
To abstract that away, I would suggest another class to do that for you. Then your query call would return a new instance of that class which has the MySQL resultset resource as an instance variable and packages up the mysql_fetch_assoc() call.
Look at PEAR::MDB2 (Quickstart Cheatsheet). It provides lots of different functions for doing something like this. It also does not tie you down into using MySQL specific functions because it is a database abstraction layer.
$result = $db->queryRow($query, MDB2_FETCHMODE_ASSOC);
There are other abstraction layers such as ADO as well.
thanks for the ideas. I have a function that returns an associative array from the sql (used in Moodle).
$results = get_records_sql($sql);
//to create a numerically indexed array:
$data = array();
foreach ($results as $row)
{
$data[] = $row;
}
return $data;
}