Stacking a variable in reverse in PHP - php

I have a loop spitting out values and are put into a string:
$all_values = "";
while loop {
$value = "...";
$all_values .= $value . ",";
}
Output: 1,3,8,2,10...
What's the simplest way to output the same thing but numbers in reverse so the above example would come out like ...10,2,8,3,1

Put everything into an array and then join it together, reversed:
$all_values = array();
while loop {
$value = "...";
$all_values[] = $value;
}
$all_values = implode(',', array_reverse($all_values));
This is also more efficient if there are millions of values.

Add after your code:
$ar = explode(',', $all_values);
$revAr = array_reverse($ar);
$all_values = implode(',', $revAr);

Related

PHP Merge with separators

I am trying to merge two strings in a specific way.
Essentially I need to merge the first two strings into a third with a pipe symbol between them then separated by commas:
$merge1 = "id1,id2,id3"
$merge2 = "data1,data2,data3"
Those two would become:
$merged = "id1|data1,id2|data2,id3|data3"
I hope this makes sense?
I mean there is no PHP function that can output what you need.
Code produced desired output could be
<?php
$merge1 = "id1,id2,id3";
$merge2 = "data1,data2,data3";
$merged = [];
$arr1 = explode(',', $merge1);
$arr2 = explode(',', $merge2);
foreach ($arr1 as $key => $val) {
$merged[] = $val . '|' . $arr2[$key];
}
echo implode(',', $merged);
// id1|data1,id2|data2,id3|data3
This script will help you
<?php
$merge1 = "id1,id2,id3";
$merge2 = "data1,data2,data3";
$merge1 = explode(",", $merge1);
$merge2 = explode(",", $merge2);
$final = [];
foreach ($merge1 as $index => $value) {
$final[] = $value . "|" . $merge2[$index];
}
$final = implode(",", $final);
print_r($final);
output
id1|data1,id2|data2,id3|data3
Try this.
<?php
$merge1 = "id1,id2,id3";
$merge2 = "data1,data2,data3";
$merge1 = explode(",",$merge1);
$merge2 = explode(",",$merge2);
$mergeArr = array_combine($merge1,$merge2);
$mergeStr = [];
foreach($mergeArr as $k => $v) {
$mergeStr[] = $k.'|'.$v;
}
$mergeStr = implode(",",$mergeStr);
echo $mergeStr;
?>

Moving an array to the end of an array

So I'm trying to combine $gender and $grade and then remove them from the middle of my array and put them at the end. This is what I have so far but it adds both to the end but they're still in the middle of the output file. I feel like I'm missing something simple here. Any suggestions?
<?php
$inputFile = "Student_Data.csv";
$outputFile = "test.csv";
$count = 0;
$out = fopen($outputFile, "w");
$in = fopen($inputFile, "r");
while ($row = fgetcsv($in)) {
$gender = array($row[6]);
$grade = array($row[7]);
$merge = array_merge ($gender, $grade);
$final = array_merge ($row, $merge);
$sisline = implode(",", $final) . "\r\n";
print_r ($sisline);
$count++;
}
fclose($out);
fclose($in);
?>
Once you extract the value, remove them from the soruce.
$gender = array($row[6]);
$grade = array($row[7]);
unset($row[6],$row[7]);
or to get fancy as single line solution.
$row = array_diff_key($row,array_flip(array(6,7))) + $row;
Because the two keys you want are consecutive, you can select them and remove them in one step with array_splice
$genderAndGrade = array_splice($row, 6, 2);
$final = array_merge($row, $genderAndGrade);

getting duplicated results from nested foreach loop

I'm trying to get the following output from mysql for Google Line Chart API:
[["product","diameter","width"],["Product 1","2","4"],["Product 2","4","8"]]
I have set up several input checkboxes to send field names (e.g width,diameter) to the database via $_POST["info"] and retrieve the values from those fields. Here's the part that generates the data from mysql:
$result = $users->fetchAll();
$comma = "";
$data="";
$data[0] = array_merge(array(product),$info);
$i = 1;
foreach ($result as $r)
{
foreach($_POST["info"] as $p)
{
$d .= $comma.$r[$p]; // trying to get "$r["width"],$r["diameter"]"
}
$comma = ",";
$data[$i] = array($r["name"], $d);
$i++;
}
echo json_encode($data);
My desired output should be like this:
[["product","diameter","width"],["Product 1","2","4"],["Product 2","4","8"]]
But that code is generating duplicated results like this
[["product","diameter","width"],["Product 1","24"],["Product 2","24,4,8"]]
I guess I shouldn't be using the nested foreach to loop over $_POST. Can anyone tell me how to fix that?
Full PHP Code:
$info = $_POST["info"]; // It contains an array with values like width,diameter,thickness etc...
$comma = "";
foreach($info as $in)
{
$field .= "".$comma."b.".$in."";
$comma = ",";
}
$sql = "
SELECT {$field},a.user_id,a.name
FROM `product_detail` a INNER JOIN
`attr` b ON a.model = b.model
WHERE a.user_id = ?
GROUP BY a.model
";
$users = $dbh->prepare($sql);
$users->bindValue(1, $_SESSION["user_id"]);
$users->execute();
$result = $users->fetchAll();
$comma = "";
$data="";
$i = 1;
$data[0] = array_merge(array(product),$info);
foreach ($result as $r)
{
foreach($_POST["info"] as $p)
{
$d .= $comma.$r[$p];
}
$comma = ",";
$data[$i] = array($r["name"], $d);
$i++;
}
echo json_encode($data);
$_POST["info"] Content:
Array
(
[0] => diameter
[1] => width
)
try it like this:
$result = $users->fetchAll();
$data="";
$data[0] = array_merge(array(product),$info);
$i = 1;
foreach ($result as $r)
{
$d[]=$r["name"];
foreach($_POST["info"] as $p)
{
$d[]= $r[$p];
}
$data[$i] = $d;
$d=array(); //set $d to empty not to get duplicate results
$i++;
}
echo json_encode($data);
The end result you are looking for, is valid JSON. You should not try to manually generate that.
Instead you should make an array of arrays in php and use json_encode($array) to get the result you are looking for.
Also note that by injecting your POST variables directly in your query, you are vulnerable to sql injection. When accepting fields, you should check them against a white-list of allowed values.
Try the below solution:
$result = $users->fetchAll();
$data="";
$data[0] = array_merge(array(product),$info);
$i = 1;
foreach ($result as $r)
{
$d = array();
foreach($_POST["info"] as $p)
{
$d[] = $r[$p]; // trying to get "$r["width"],$r["diameter"]"
}
$data[$i] = array($r["name"]) +$d;
$i++;
}
echo json_encode($data);

refactoring and using a counter?

I have the following structure:
$text_1 = $this->getValue('value_1');
$text_2 = $this->getValue('value_2');
$text_3 = $this->getValue('value_3')
And also the following:
foreach($text_1 as $t_1)
{
if(!$first)
{
$string_1 .= ",";
}
$first = false;
$string_1 .= $t_1;
}
foreach($text_2 as $t_2)
{
if(!$first)
{
$string_2 .= ",";
}
$first = false;
$string_2 .= $t_2;
}
foreach($text_3 as $t_3)
{
if(!$first)
{
$string_3 .= ",";
}
$first = false;
$string_3 .= $t_3;
}
I was wondering if this could be re-factored to use a counter, like in a for loop, to replace the _1, _2, _3 etc from my code?
Well, the foreach-loops can be replaced with implode.
Other than that, wouldn't it be better to use an array for your $text_?? variables? Eg.:
$text = $this->getValue('value');
foreach ($text as $value) {
$strings[] = implode(",", $value);
}
Hard to give more concrete advise, without the exact context, but that should get you in the right direction.
I hope this one helps u...
$arrOutput = compact('text_1', 'text_2', 'text_3');
foreach($arrOutput as $t1)
{
$out1[] = implode(",", $t1);
}
print_r($out1);
Yes, you should probably be using an array or map to hold the values and iterating over that, assuming that the values you're dealing with are all the same sort of thing.
Ok so I figured out a way of doing it:
for ($i=1;$i<=12;$i++) {
$choices = $this->getValue('question_'.$i);
$serialized = "";
$first = true;
foreach($choices as $choice)
{
if(!$first)
{
$serialized .= ",";
}
$first = false;
$serialized .= $choice;
}
$this->setValue('question_'.$i, $serialized);
}
This seems to work well!

How do I combine all elements in an array using comma?

I know this question has with out any doubt been asked a whole lot of times. I though can seem to find a solution. So forgive me if it's way to simple.
The question is how do access the end of a while loop.
E.g.
while($countByMonth = mysql_fetch_array($countByMonthSet)) {
$c = $countByMonth["COUNT(id)"];
echo $c . "," ;
}
How do I manage separate each value of the while loop by a comma but of course I don't want the comma at the end of the value.
In advance thank you very much for your help :)
You can:
1) Build a string, and remove the last character:
$c = '';
while ($countByMonth = mysql_fetch_array($countByMonthSet)) {
$c .= $countByMonth["COUNT(id)"] . ',';
}
$c = substr($c, 0, -1);
echo $c;
2) Build an array and use implode()
$c = array();
while ($countByMonth = mysql_fetch_array($countByMonthSet)) {
$c[] = $countByMonth["COUNT(id)"];
}
echo implode(',', $c);
Tip: You can use aliases in your query, like: SELECT COUNT(id) as count FROM .... Then you can access it as $countByMonth['count'], which looks cleaner IMO.
The simple1 solution:
$isFirst = true;
while($countByMonth = mysql_fetch_array($countByMonthSet)) {
$c = $countByMonth["COUNT(id)"];
if ($isFirst) {
$isFirst = false;
} else {
echo = ', ';
}
echo $c;
}
Alternatively, you could implode() the values. Or - perhaps easier to read/understand/maintain - concatenate it all into a string and remove the last "," (SO eats my whitespace; the string is comma-whitespace):
$list = '';
while($countByMonth = mysql_fetch_array($countByMonthSet)) {
$c = $countByMonth["COUNT(id)"];
$list .= $c . ', ';
}
echo substring($list, 0, -2); // Remove last ', '
(Several other answers propose the use of an accumulated array and then use implode(). From a performance perspective this method will be superior to string concatenation.)
1 See comments.
Alternatively you can do:
$arr = array();
while($countByMonth = mysql_fetch_array($countByMonthSet)) {
$arr[] = $countByMonth["COUNT(id)"];
}
echo implode(', ',$arr);
Or afterwards just trim it off with rtrim($c, ',')
While I think the implode solution is probably best, in situations where you can't use implode, think of the basic algorithm differently. Rather than "how can I add a comma behind every element but the last?" ask yourself "how can I add a comma before every element but the first?"
$str = '';
$count = count( $array );
if( $count ) {
$i = 0;
$str = $array[$i];
$i++;
while( i < $count ) {
$str .= ','.$array[$i];
$i++;
}
}
If you "shift" the first element, then you can use a foreach loop:
$str = '';
if( count( $array ) ) {
$str = array_shift( $array );
foreach( $array as $element ) {
$str .= ', '.$element;
}
}
Ty this:
int count;//
while(i)
{
count=i;
}

Categories