PHP foreach loop - php

I have the array example below that I am using to dynamically create an SQL query based on the options ticked in a form. The code below tests whether there is a value, if so, append it to the array:
if ($lookchild) { $val[]='lookchild'; }
if ($mentalcap) { $val[]='mentalcap'; }
if ($mentalheal) { $val[]='mentalheal'; }
if ($olderpeople) { $val[]='olderpeople'; }
if ($palcare) { $val[]='palcare'; }
I am then looping through the array and adding the rest of the SQL statement:
foreach ($val as $r){
echo $r.'=1 AND ';
}
This produces:
olderpeople=1 AND palcare=1 AND lookchild=1 AND
When the loop reaches the last entry, I don't want it to append the AND to it as the SQL statement needs to close after that point.
How I want it to complete:
olderpeople=1 AND palcare=1 AND lookchild=1

Implode
In these situations you can use implode
It 'glues' an array together.
implode ( string $glue , array
$pieces )
Example:
echo implode('=1 AND ', $val);
echo '=1';

A common trick is to use 'WHERE 1=1' then you can append ' AND foo = bar' without a syntax error.
WHERE 1=1 AND olderpeople=1 AND palcare=1 AND lookchild=1

This is what implode() is for:
$result = array();
foreach ($val as $r){
$result[] = "$r=1";
}
$result = implode($result, ' AND ');
Live Example

Just don't print the AND for the last value of the foreach loop. Here is the code to use:
foreach ($val as $r){
echo $r.'=1';
if (next($val)) {
echo ' AND ';
}
}

use the implode function
$sql = implode("=1 AND ", $array)."=1";
and you wont have to use a for loop :)

Instead on assigning palcare to $val[], assign $val[] = "palcare = 1" etc. Them
implode(" AND ", $val);

Try this :
$isFirst = true;
foreach ($val as $r){
if(!$isFirst){
echo ' AND ';
}else{
$isFirst = false;
}
echo $r.'=1';
}

I would remove the last 4 characters of the string with:
$r = '';
foreach ($val as $r){
$r.'=1 AND ';
}
$r = substr($r, 0, -4);
echo $r;
Checkout http://ca3.php.net/manual/en/function.substr.php, quick and easy

If you have to do it with a foreach (and for some reason you cant use implode, which is a good suggestion) you will need a way to keep track of where you are.
I thought to add the "AND" before anything but the first item, instead of adding it after anything but the last item, something like this:
$sqlwhere = "";
foreach ($val as $r){
if($sqlwhere ==""){
$sqlwhere = $r;
}
else {
$sqlwhere .= " AND " . $sqlwhere;
}
}
echo $sqlwhere;
I used a varable instead of just echoing it out too, which I find useful in complicated sql statements anyway.

Use implode. But if for some reason you need to loop (such as you need to do more logic than just joining the strings), use a separator approach:
$seperator = '';
$result = '';
foreach ($array as $value) {
// .. Do stuff here
$result .= $seperator . $value;
$seperator = ' AND ';
}
The benefit is both brevity and flexibility without checking conditions all the time...

Since you are using an array, you can also use count to figure out how many are in the array and if you are on the last item, don't append the 'AND'.
$result = array();
$totalcount = count($val);
$currentCount = 0;
foreach ($val as $r){
$currentCount ++;
if ($currentCount != $totalcount){$result[] = "$r=1 AND ";}else{$result[] = "$r=1";}
}

Related

concatinating two array elements with a string within a foreach loop

I am trying to combine two array elements with the string "OR" and create one string of elements.
The array looks like this:
$myarray = array(2282396,1801345)
This is the code i have used.
$bool = ' OR ';
foreach($myarray as $element){
echo $element .= $bool;
}
I trying to get this output after looping using a foreach loop.
2282396 OR 1801345
However, the output i get looks like this:
2282396 OR 1801345 OR
How do i get rid of the 'OR' after the second element? Thanks in advance
You have to check if you're in the first/last iteration or not.
$first = true;
$bool = ' OR ';
foreach ($myarray as $element) {
if (!$first) {
echo $bool;
}
echo $element;
$first = false;
}
If your array is indexed by numeric indexes 0-x, you an use
$bool = ' OR ';
foreach ($myarray as $key => $element) {
if ($key > 0) {
echo $bool;
}
echo $element;
}
Use implode as:
echo implode(" OR ", $myarray);
Documentation implode
Live example: 3v4l

while foreach loop is outputting twice

I want the loop just to output once. Instead it outputs twice. Here is the code:
$results = mysql_query($query);
while ($c = mysql_fetch_array($results)){
$individualPostcode = explode(",", $c['postcode']);
foreach($individualPostcode as $val){
$val = trim($val); //Get rid of spaces
if($val === $postcode){
echo $c['url']."<br>";
}
}
}
}
Here is the output:
http://www.dyno.com/home-security/local-experts/greater-london/dyno-locks-and-alarms-enfield
http://www.dyno.com/home-security/local-experts/greater-london/dyno-locks--alarms-enfield
http://www.dyno.com/home-security/local-experts/greater-london/dyno-locks-and-alarms-enfield
http://www.dyno.com/home-security/local-experts/greater-london/dyno-locks--alarms-enfield
I've tried taken out the foreach loop but I need to go through that array checking against a user input.
Here is the initialisation of $postcode:
$userInput = $_POST["input"];
if(strlen($userInput) < 4)
echo "User Input : ".$userInput."<br>";
else //Below gets the first three chars of the users string
echo "User Input : $userInput<br>What is being used : ".mb_substr($userInput, 0, 3)."<br>";
$postcode = mb_substr($userInput, 0, 3);
You can always create an array of the URL's to stop them from duplicating by checking if the url has been put into the array:
$results = mysql_query($query);
$urlsArr = array();
while ($c = mysql_fetch_array($results)){
$individualPostcode = explode(",", $c['postcode']);
foreach($individualPostcode as $val){
$val = trim($val); //Get rid of spaces
if($val === $postcode){
if (!in_array($c['url'], $urlsArr)) echo $c['url']."<br>";
$urlsArr[] = $c['url'];
}
}
}
mysql_fetch_array returns both an associative and index array for each of your returned results. The foreach loop is going to loop over both and output twice. Try using mysql_fetch_assoc()
http://php.net/manual/en/function.mysql-fetch-array.php
Better still, try moving to the mysqli class. It's faster and mysql is depricated.
http://php.net/manual/en/intro.mysqli.php

Add space in String

I would like to add space during string assignment like:
$movie_genre.= $row["movie_genre"]." ";
where it should display genre1 genre2 genre3 and so on. Single space between these three genres is required. Currently it is showing genre1genre2genre3
Collect it in an array & then use implode:
{// your loop starts
$movie_genre[] = $row["movie_genre"];
}//// your loop ends
echo implode(" ", $movie_genre);
#MuhammadMuazzam,Please check below code.
//Suppose your data array like below.(Below is sample example)
$dataArray = array('data1','data2','data3');
$numItems = count($dataArray);
$i = 0;
$movie_genre = '';
foreach($dataArray as $value)
{
if(++$i === $numItems) {
$movie_genre.= $value;
} else {
$movie_genre.= $value." ";
}
}
echo $movie_genre;
Your existing code is perfect,
just add a single line rtim()
$movie_genre.= $row["movie_genre"] . " ";
$movie_genre = rtrim($movie_genre);

exporting mysql query column headings

I have the following query...
public function get_invoice_user_summary_csv($invoice_table_id)
{
$sql_get_user_summ = "
SELECT `billingHistory`.`$invoice_table_id`.userId as userId, ipCore.users.firstname, ipCore.users.surname, COUNT(`billingHistory`.`$invoice_table_id`.id) AS totalNum, SUM(`billingHistory`.`$invoice_table_id`.durationSeconds) AS totalDuration, (SUM(`billingHistory`.`$invoice_table_id`.priceMin)+SUM(`billingHistory`.`$invoice_table_id`.priceCon)) AS totalCost
FROM `billingHistory`.`$invoice_table_id`
LEFT JOIN ipCore.users ON `billingHistory`.`$invoice_table_id`.userId = ipCore.users.id
GROUP BY userId
ORDER BY ipCore.users.surname ASC, ipCore.users.firstname ASC;";
$query = $this->db_mtvm->query($sql_get_user_summ);
if($query->num_rows() > 0)
{
foreach ($query->result_array() as $row)
{
$line = '';
$value = '';
foreach($row as $value)
{
if((!isset($value)) || ($value == ""))
{
$value = ",";
}
else
{
$value = str_replace( '"' , '""' , $value );
$value = '"' . $value . '"' . ",";
}
$line .= $value;
}
print substr(str_replace("\r", "", trim($line)), 0, -1)."\r\n";
flush();
ob_flush();
}
}
else return false;
}
this return formatted array for csv out put in a different controller.
however it is just the body of data (as i expected). However I have read a few questions with i think similar things, but canot quite work out in this example where I need to put the column headings. either manually entered, or I will assign these from the sql query.
You now loop through the results, by doing this:
foreach ($query->result_array() as $row)
You should change your script so that on the first iteration of this loop, you fetch the column headers and output them. A quick way to do this would be to change the line I quoted above to:
$i = 0;
foreach ($query->result_array() as $row)
{
if($i === 0)
echo implode(",", array_keys($row)) . "\r\n";
$i++;
[...]
I notice you're creating the CSV string yourself. An easier way to do that is by using fputcsv(). By default it writes to a file handle, but you can also buffer the output in memory and fetch the result as a string, like this example shows.

How can I easily remove the last comma from an array?

Let's say I have this:
$array = array("john" => "doe", "foe" => "bar", "oh" => "yeah");
foreach($array as $i=>$k)
{
echo $i.'-'.$k.',';
}
echoes "john-doe,foe-bar,oh-yeah,"
How do I get rid of the last comma?
Alternatively you can use the rtrim function as:
$result = '';
foreach($array as $i=>$k) {
$result .= $i.'-'.$k.',';
}
$result = rtrim($result,',');
echo $result;
I dislike all previous recipes.
Php is not C and has higher-level ways to deal with this particular problem.
I will begin from the point where you have an array like this:
$array = array('john-doe', 'foe-bar', 'oh-yeah');
You can build such an array from the initial one using a loop or array_map() function. Note that I'm using single-quoted strings. This is a micro-optimization if you don't have variable names that need to be substituted.
Now you need to generate a CSV string from this array, it can be done like this:
echo implode(',', $array);
One method is by using substr
$array = array("john" => "doe", "foe" => "bar", "oh" => "yeah");
$output = "";
foreach($array as $i=>$k)
{
$output .= $i.'-'.$k.',';
}
$output = substr($output, 0, -1);
echo $output;
Another method would be using implode
$array = array("john" => "doe", "foe" => "bar", "oh" => "yeah");
$output = array();
foreach($array as $i=>$k)
{
$output[] = $i.'-'.$k;
}
echo implode(',', $output);
I don't like this idea of using substr at all, since it's the style of bad programming. The idea is to concatenate all elements and to separate them by special "separating" phrases. The idea to call the substring for that is like to use a laser to shoot the birds.
In the project I am currently dealing with, we try to get rid of bad habits in coding. And this sample is considered one of them. We force programmers to write this code like this:
$first = true;
$result = "";
foreach ($array as $i => $k) {
if (!$first) $result .= ",";
$first = false;
$result .= $i.'-'.$k;
}
echo $result;
The purpose of this code is much clearer, than the one that uses substr. Or you can simply use implode function (our project is in Java, so we had to design our own function for concatenating strings that way). You should use substr function only when you have a real need for that. Here this should be avoided, since it's a sign of bad programming style.
I always use this method:
$result = '';
foreach($array as $i=>$k) {
if(strlen($result) > 0) {
$result .= ","
}
$result .= $i.'-'.$k;
}
echo $result;
try this code after foreach condition then echo $result1
$result1=substr($i, 0, -1);
Assuming the array is an index, this is working for me. I loop $i and test $i against the $key. When the key ends, the commas do not print. Notice the IF has two values to make sure the first value does not have a comma at the very beginning.
foreach($array as $key => $value)
{
$w = $key;
//echo "<br>w: ".$w."<br>";// test text
//echo "x: ".$x."<br>";// test text
if($w == $x && $w != 0 )
{
echo ", ";
}
echo $value;
$x++;
}
this would do:
rtrim ($string, ',')
see this example you can easily understand
$name = ["sumon","karim","akash"];
foreach($name as $key =>$value){
echo $value;
if($key<count($name){
echo ",";
}
}
I have removed comma from last value of aray by using last key of array. Hope this will give you idea.
$last_key = end(array_keys($myArray));
foreach ($myArray as $key => $value ) {
$product_cateogry_details="SELECT * FROM `product_cateogry` WHERE `admin_id`='$admin_id' AND `id` = '$value'";
$product_cateogry_details_query=mysqli_query($con,$product_cateogry_details);
$detail=mysqli_fetch_array($product_cateogry_details_query);
if ($last_key == $key) {
echo $detail['product_cateogry'];
}else{
echo $detail['product_cateogry']." , ";
}
}
$foods = [
'vegetables' => 'brinjal',
'fruits' => 'orange',
'drinks' => 'water'
];
$separateKeys = array_keys($foods);
$countedKeys = count($separateKeys);
for ($i = 0; $i < $countedKeys; $i++) {
if ($i == $countedKeys - 1) {
echo $foods[$separateKeys[$i]] . "";
} else {
echo $foods[$separateKeys[$i]] . ", \n";
}
}
Here $foods is my sample associative array.
I separated the keys of the array to count the keys.
Then by a for loop, I have printed the comma if it is not the last element and removed the comma if it is the last element by $countedKeys-1.

Categories