I'm trying to nest foreach loops with PDO statements (this previously worked for me in mysql,btw). The first example works and the second one doesn't. However I'd prefer not to run a SQL query every time (isn't that the point of PDO?) and would prefer to use something more like example 2. However, it doesn't 'nest' the loop inside the other, it seems, rather it runs the first then the next.
Example 1)
foreach($db->query('SELECT country FROM db GROUP BY `country`') as $row1) {
echo $row1['country']."<br/>";
foreach($db->query('SELECT * FROM db') as $row2) {
if ($row1['country']==$row2['country']){
echo $row2['name']."<br/>";
}
}
}
Example 2)
$cntry = $db->query('SELECT country FROM db GROUP BY `country` ');
$rslts = $db->query('SELECT * FROM db');
foreach ($cntry as $row1) {
echo "<div id='".$row1['country']."'>".$row1['country']."<br/>";
foreach($rslts as $row2) {
if ($row1['country']==$row2['country']){
echo $row2['name']."<br/>";
}
};
echo "</div>";
}
(isn't that the point of PDO?)
No. The point of PDO is to send your query to database server and to return the results back. But PDO cannot reduce the number of queries executed.
So, here goes the proper solution:
$stmt = $db->query('SELECT country, name FROM db ORDER BY country, name');
$data = $stm->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP);
foreach ($data as $country => $row)
{
echo $country."<br/>\n";
foreach ($row as $name)
{
echo $name."<br/>\n";
}
}
As a matter of fact, fetchAll() is just a syntax sugar for the code like this:
$data = array();
while ($row = $stmt->fetch())
{
$data[] = $row;
}
it just creates a regular PHP array out of query result. And of course you can loop over this array as many times as you wish. Means you an always replace fetchAll() with manual looping over results, and of course you may group the results whatever way you wish.
While using foreach on $stmt is just a syntax sugar again, intended to confuse PHP users. Because $stmt is not an array but a way more complex structure.
not sure, but as I remember it would be like this
$cntry = $db->query('SELECT country FROM db GROUP BY `country` ')->fetchAll (PDO::FETCH_COLUMN);
$rslts = $db->query('SELECT * FROM db')->fetchAll(PDO::FETCH_COLUMN);
foreach ($cntry as $row1) {
echo $row1['country']."<br/>";
foreach($rslts as $row2) {
if ($row1['country']==$row2['country']){
echo $row2['name']."<br/>";
}
}
}
Related
I want to output all records in my database. So far so good, but when I loop through it, php gives me an error " Array to string conversion ".
I added an index to the array but then it does just output obviously the first or secound ( etc. ) column.
$conn = new PDO("mysql:host=localhost;dbname=database","root","");
$stmt = $conn->prepare('SELECT * FROM de');
$stmt ->execute();
$result = $stmt ->fetchAll();
if (is_array($result) || is_object($result))
{
foreach ($result[0] as $value)
{
echo "<table><tr><td>'$value'</td></tr></table>";
}
}
So, with the index, it does work. But I need all records, not just one.
I appreciate every comment and help!
I would start with a nested loop. I also wonder if you want a table for every value
$conn = new PDO("mysql:host=localhost;dbname=database","root","");
$stmt = $conn->prepare('SELECT * FROM de');
$stmt ->execute();
$result = $stmt ->fetchAll();
if (is_array($result) || is_object($result))
{
foreach ($result as $row){ //Go through every row in the result
echo('<table>');
foreach ($row as $value){ //Go through every value in the row
echo "<tr><td>'$value'</td></tr>";
}
echo('</table>');
}
}
This will print every row as a new table, but you can search out the variation you want.
A nested foreach loop should work.
foreach ($result as $values)
{
foreach ($values as $value) {
echo "<table><tr><td>'$value'</td></tr></table>";
}
}
An alternative to nested loops, if you know the number of fields and said number is constant for each execution; A state that's found in most situations; You can use vsprintf () to print out the rows.
Quick example:
$result = {{'John', 'Doe'}, {'Sarah', 'Jane'}};
$output = '<table>';
foreach ($result as $row) {
$output .= vsprintf ("<tr><td>%s</td><td>%s</td></tr>\n", $row);
}
echo $output."</table>";
Cuts down a bit on the code, and quite a bit on the code complexity. The template for the rows themselves can also be extracted to a variable (or template view), outside of the loop, to make the code even cleaner.
In my database I store email addresses. In the foreach loop how can I skip all email addresses that has #sample.com.ru?
$sql = "SELECT * FROM myMovieCustomers";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();
foreach ($result as $row) {
//skip if $row['email'] contains #sample.com.ru{
//do someting with these
//}
}
it's more efficient to do filtering at the database level for a couple of reasons
you're not wasting network resources transmitting unneeded data across the wire
with a well indexed table, the DBMS will be faster at making the search than php will with the result data
as is pointed out in the comments and other answers, you can use the LIKE operator
$sql = "SELECT * FROM myMovieCustomers WHERE email NOT LIKE '%#sample.com.ru'";
You can achieve what you want by using php function strstr() like below:
$all = array(
'name' => array('Thanga','Kima','Zara'),
'email'=> array('thanga#gmail.com','kima#gmail.com','zara#sample.com.ru')
);
echo '<pre>';
print_r($all);
foreach($all as $key=>$val):
foreach ($val as $k=>$v):
if(strstr($v,'#')=='#sample.com.ru'){
}else{
echo $v;
}
endforeach;
endforeach;
Just change the first line...
$sql = "SELECT * FROM myMovieCustomers WHERE email NOT LIKE'%#sample.com.ru'";
I have a PHP code that takes an 'empfullname' from a drop down selection and displays a timecard based on the selection. However, I want to make it have the capability to allow a user to select 'All' and it just print all the employees available. I am thinking I have to do this with a foreach loop, but I can't seem to get it to work. Here is the if statement that I think I need.
if ($empfullname == 'All') {
$query = "select * from ".$db_prefix."employees order by empfullname asc";
$result = mysql_query($query);
$tmp_empfullname = stripslashes("".$row['empfullname']."");
foreach ($tmp_empfullname){
print timecard_html($empfullname,$local_timestamp_in_week);
}
} else {
print timecard_html($empfullname,$local_timestamp_in_week);
}
print '<script language="JavaScript" type=
"text/javascript" src="../scripts/jquery.totals3.js"></script>';
print <<<End_Of_HTML
<table align="center" border="0" cellpadding="0" cellspacing="3" class="buttons">
<tr><td><a href="timecardrpt.php"><img src=
"../images/buttons/done_button.png" border="0" /></a></td></tr>
</table>
End_Of_HTML;
include '../footer.php';
This is a huge mess and it's clear you aren't thinking through the logic or structure very well and you haven't looked at many examples of PHP MySQL functions. There are TONS of examples and tutorials you should be looking at. Regarding foreach, you need to understand how foreach works. Specifically, the syntax is foreach ($myArray as $value) and not just foreach ($myArray). There's a lot of other stuff as well.
You don't run any query in your "else" block.
You don't fetch rows from the result.
You use the deprecated and insecure mysql function instead of mysqli or PDO.
You are inconsistent in your variable names (you have $tmp_empfullname in your foreach but $empfullname in the statement block.
Strictly speaking, you don't need a foreach loop as a while works fine. You could use a foreach, but meh.
This should fix it:
//Do your mysqli connection here. it's different from the mysql connection.
if ($empfullname == 'All') {
$query = "select * from ".$db_prefix."employees order by empfullname asc";
} else {
$query = //put a SQL query here
}
if ($result = mysqli->query($query)){
while ($row = $result->fetch_assoc()){ //you could also do foreach ($result as $row)
print timecard_html(stripslashes($row['$empfullname']), $local_timestamp_in_week);
}
}
The poblem is that you are calling this $row without ever declaring it in a foreach so you should make the code after $result = mysql_query($query); look like:
foreach ($result as $row) {
$tmp_empfullname = stripslashes("".$row['empfullname']."");
}
Once that is done you should just need to do what Aleatoric to get each name that is in the $tmp_empfullname variable.
I often need to retrieve results and access them by a given column.
Is there a way to write this without walking through the whole dataset each time?
I looked into various PDO fetch modes, but nothing jumped out as being simpler than that. Thanks.
function get_groups() {
$stmt = $dbc->prepare("SELECT * FROM groups ORDER BY group_name");
$stmt->execute();
$groups = $stmt->fetchAll();
$return = [];
foreach($groups as $group) {
$return[$group['id']] = $group;
}
return $return;
}
My proposed solution was pretty obsolete. The right solution comes from this answer
$stmt = $pdo->query("SELECT foo,baz FROM bar")
$groupedByFooValuesArray = $stmt->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE)
to group it by another column, change the first column you select
if your goal is to have your same array indexed by different column values, I think the only option is to actually index them by different column values.
you can do that by controlling by which field the array is returned
function get_groups($sql,$key,$values='') {
if ($values != '') {
$stmt = $dbc->prepare($sql);
$stmt->execute($values);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
else {
$rows = $dbc->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
foreach ($rows as $row) {
$indexed[$row[$key]] = $row;
}
return $indexed;
}
then, use get_groups to build an indexed array:
$sql = 'SELECT * FROM groups ORDER BY group_name'
var_dump(get_groups($sql,'id'));
There might be a way to store a resultset in some way that you can fetchAll() it multiple times, that would be awesome. but I don't know it.
I am querying like this, in snippet below 1st loop takes column names and second loops push values in another array(i know this may not be an optimal way but this is what came in my mind and is solving my task). The problem is
$results = '';
$dataArray = array();
$columns_array = array();
$dataArray = array();
$results = mysqli_query($mysqli, ("SELECT
DISTINCT states_drg.`Provider State`,
SUM(states_drg.`Total Discharges`) AS discharges
FROM states_drg
GROUP BY states_drg.`Provider State`")
);
$columns_names = mysqli_fetch_assoc($results);
foreach ($columns_names as $key => $value) {
array_push($columns_array, $key);
}
array_push($dataArray, $columns_array);
foreach ($results as $result) {
array_push($dataArray, mysqli_fetch_row($results));
}
print_r($dataArray);
echo json_encode($dataArray, JSON_NUMERIC_CHECK);
exit;
);
Query runs absolutely fine in query browser, but when I take dump of print_r($dataArray); I get only 26 records where as I have around 51 records in total if I run the Query in Query Browser.
You're using mysqli totally wrong.
foreach($results as $result)
is NOT how you fetch data from a query result. You should have
while($row = mysqli_fetch_assoc($result)) {
$dataArray[] = $row;
}
And not to mention the multiple syntax errors in your pasted code...