Sending multidimensional array from jQuery to php - php

I am passing an array from jQuery to php.
The array is generated from a table with this code:
var stitchChartArray = [];
var row = 0;
// turn stitch chart into array for php
$('#stitchChart').find('tr').each(function (index, obj) {
//first row is table head- "Block #"
if(index != 0){
stitchChartArray.push([]);
var TDs = $(this).children();
$.each(TDs, function (i, o) {
var cellData = [$(this).css('background-color'), $(this).find("img").attr('src')];
stitchChartArray[row].push(cellData);
});
row++;
}
});
In console it looks like this:
[[["rgb(75, 90, 60)", "symbols/177.png"], ["rgb(75, 75, 60)", "symbols/184.png"], ["rgb(75, 90, 60)", "symbols/177.png"], 7 more...], [["rgb(105, 105, 105)", "symbols/163.png"], ["rgb(75, 75, 60)", "symbols/184.png"], ["rgb(75, 90, 60)", "symbols/177.png"], 7 more...], [["rgb(105, 105, 105)", "symbols/163.png"], ["rgb(75, 90, 60)", "symbols/177.png"], ["rgb(75, 75, 60)", "symbols/184.png"], 7 more...], [["rgb(75, 90, 60)", "symbols/177.png"], ["rgb(75, 90, 60)", "symbols/177.png"], ["rgb(98, 119, 57)", "symbols/210.png"], 7 more...], [["rgb(105, 105, 105)", "symbols/163.png"], ["rgb(105, 105, 105)", "symbols/163.png"], ["rgb(150, 150, 195)", "symbols/72.png"], 7 more...], [["rgb(75, 165, 105)", "symbols/187.png"], ["rgb(134, 158, 134)", "symbols/64.png"], ["rgb(165, 180, 180)", "symbols/171.png"], 7 more...], [["rgb(60, 150, 75)", "symbols/189.png"], ["rgb(120, 120, 90)", "symbols/225.png"], ["rgb(143, 163, 89)", "symbols/209.png"], 7 more...]]
It represents each row of a table->each cell of row->[0]rgb value of bg of cell [1]icon in cell.
This jQuery code returns the correct element(and rgb value) from the array:
alert(stitchChartArray[1][1][0]); //row 1,cell 1, first value(rgb)
But when it gets sent to the php script with this:
$.post('makeChartPackage.php', {'stitchChart[]': stitchChartArray }, function(data){
alert(data);
});
The php throws an error:
Cannot use string offset as an array in /Users/tnt/Sites/cross_stitch/makeChartPackage.php on line 33
$stitchChart = $_POST['stitchChart'];
echo $stitchChart[1][1][0]; //line 33
I am assuming I am either constructing the array incorrectly or passing it to the php script incorrectly.
EDIT:
I did this to return the array to jQuery:
$stitchChart = $_POST['stitchChart'];
print_r($stitchChart);
And here was the result:
Array
(
[0] => rgb(75, 90, 60),symbols/177.png,rgb(75, 75, 60),symbols/184.png,rgb(75, 90, 60),symbols/177.png,rgb(98, 119, 57),symbols/210.png,rgb(180, 195, 105),symbols/388.png,rgb(165, 165, 120),symbols/235.png,rgb(75, 75, 60),symbols/184.png,rgb(90, 90, 45),symbols/195.png,rgb(120, 120, 75),symbols/156.png,rgb(105, 105, 105),symbols/163.png
[1] => rgb(105, 105, 105),symbols/163.png,rgb(75, 75, 60),symbols/184.png,rgb(75, 90, 60),symbols/177.png,rgb(75, 90, 60),symbols/177.png,rgb(165, 165, 120),symbols/235.png,rgb(120, 120, 75),symbols/156.png,rgb(75, 90, 60),symbols/177.png,rgb(75, 90, 60),symbols/177.png,rgb(105, 105, 105),symbols/163.png,rgb(120, 120, 90),symbols/225.png
[2] => rgb(105, 105, 105),symbols/163.png,rgb(75, 90, 60),symbols/177.png,rgb(75, 75, 60),symbols/184.png,rgb(75, 90, 60),symbols/177.png,rgb(98, 119, 57),symbols/210.png,rgb(75, 90, 60),symbols/177.png,rgb(75, 75, 60),symbols/184.png,rgb(105, 105, 105),symbols/163.png,rgb(120, 120, 90),symbols/225.png,rgb(105, 105, 105),symbols/163.png
It appears the array is not multidimensional?

$_POST['stitchChart'] in the context you have addressed it there is (effectively) a JSON representation of a multidimensional array, stored as a string. When you treat a string as a multidimensional indexed array in PHP, you will get that error. The first [x] is treated as a "string offset" - i.e. the character at position x - but the next and any subsequent [x] addresses can only be treated as arrays (you cannot get a substring of a single character) and will emit the error you have received.
To access your data as an array in PHP, you need to use json_decode():
$stitchChart = json_decode($_POST['stitchChart'],TRUE);
echo $stitchChart[1][1][0];
EDIT
Because the jQuery data argument seemingly can't deal with multidimensional arrays, you should use Douglas Crockford's JSON-js library and pass the result into data as a string. NB: use json2.js.
Here is how you could do this:
stitchChartArray = JSON.stringify(stitchChartArray);
$.post('makeChartPackage.php', {'stitchChart': stitchChartArray }, function(data){
alert(data);
});
If you use this code, my original PHP suggestion should work as expected.

Related

pass array to chart.js option [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last year.
Improve this question
i have this array:
array (
0 => 'rgba(202, 63, 20, 1)',
1 => 'rgba(35, 14, 225, 1)',
2 => 'rgba(73, 128, 13, 1)',
3 => 'rgba(238, 62, 10, 1)',
4 => 'rgba(85, 152, 95, 1)',
5 => 'rgba(57, 156, 150, 1)',
)
but i have to use it as a parameter in a chart.js chart and i need this format:
['rgba(202, 63, 20, 1)', 'rgba(35, 14, 225, 1)', 'rgba(73, 128, 13, 1)']
and i have to do it in PHP.
some ideas ?
thanks
C.
This is how I fixed it: I pass my rgba array to the "backgroundColor" option in Chart.js with this string:
backgroundColor: <?php echo json_encode($ColorArray); ?>,
and now it works.
My mistake was in passing the php variable directly to the backgroundColor option of chart.js like this:
backgroundColor: $ColorArray,

Output to file doesn't look the way it should

So I try to send some output to a file but it doesn't look the way I want.
I have a file with some random integer values , it looks like this:
78, 60, 62, 68, 71, 68, 73, 85, 66, 64, 76, 63, 81, 76, 73, 68, 72, 73, 75, 65, 74, 63, 67, 65, 64, 68, 73, 75, 79, 73
4, 6, 9, 11, 16
9, 10, 16, 18, 20
1, 3, 8, 10, 15
Now what I want to do is for each of these lines print the average, max and min number into another file.
My code for this part is:
while (!feof($aFile))
{
$cnt += 1;
$anArray = array();
$anArray = explode(",", fgets($aFile));
foreach ($anArray as $value)
{
$value = (int)$value;
}
$line = "Line $cnt: Average=" . array_sum($anArray) / count($anArray) . " Max=" . max($anArray) . " Min=" . min($anArray);
fwrite($resultsFile, $line);
fwrite($resultsFile, "\n");
}
The problem is that the resultsFile looks like this:
Line 1: Average=70.6 Max= 85 Min= 60
Line 2: Average=9.2 Max= 16
Min=4
Line 3: Average=14.6 Max= 20
Min=9
Line 4: Average=7.4 Max= 15 Min=1
I couldn't exactly copy paste this , because when I do it pastes it the right way
The problem is that it changes line and then prints Min .
Total Average=50.533333333333 Total Max= 85 Total Min=1
This is kinda tricky and is a combination of several moments.
First - you have new line symbol (\n) in each string of your file.
So, for example string 9, 10, 16, 18, 20 is really a 9, 10, 16, 18, 20\n string.
When you explode this string by ,, last element of your $anArray is not 20, but 20\n (with new line).
Now you're trying to cast each element to int, but as by default php works with copy of array, your initial values in $anArray are unchaged. As correctly stated in comments - to apply changes to original array, use $&value notation:
foreach ($anArray as &$value)
{
$value = (int)$value;
}
And last - all following operations on your $anArray silenlty cast 20\n to int (20). But as noticed in max manual, for example:
The actual value returned will be of the original type with no conversion applied
So, in array ['9', '10', '16', '18', '20\n'] max value will be 20, but returned value will be 20\n which creates a new line and moves Min=... output to next line.

PHP - Counting array elements in a specific range

I have an array with 950 elements. Values of elements are between 80-110. I want to count how many of them between 80-90, 90-100 and 100-110. Then I'll show them on a graph. Is this possible to count elements like that in php ?
You can simply do it by running a for loop. Create an array containing a range of elements and run a for loop. While you will run the loop on that time count the array element according to your given three groups. Finally you will get the total number of elements inside the given range. For your better help below I am giving an example :
<?php
$number = array(80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110);
$count1 = $count2 = $count3 = 0;
for ($i = 0; $i < sizeof($number); $i++) {
if($number[$i] >= 80 && $number[$i] <= 90 ) {
$count1++;
}
if($number[$i] >= 90 && $number[$i] <= 100 ) {
$count2++;
}
if($number[$i] >= 100 && $number[$i] <= 110 ) {
$count3++;
}
}
echo "The number between 80-90 = ".$count1."<br>";
echo "The number between 90-100 = ".$count2."<br>";
echo "The number between 100-110 = ".$count3."<br>";
?>
I think OP may have been going for a more pythonic answer (but in PHP)
//only valid in php 5.3 or higher
function countInRange($numbers,$lowest,$highest){
//bounds are included, for this example
return count(array_filter($numbers,function($number) use ($lowest,$highest){
return ($lowest<=$number && $number <=$highest);
}));
}
$numbers = [1,1,1,1,2,3,-5,-8,-9,10,11,12];
echo countInRange($numbers,1,3); // echoes 6
echo countInRange($numbers,-7,3); // echoes 7
echo countInRange($numbers,19,20); //echoes 0
the 'use' keyword indicates a 'closure' in php. Taken for granted in other languages, for example javascript, variables in an outer function are imported scope-wise into the inner function automatically (i.e. without special keywords), the inner function may also be called a "partial function".
For some reason in PHP 5.2x or lower, variables were not imported scope-wise automatically, and in PHP 5.3 or higher, the use keyword can overcome this. The syntax is very simple:
$functionHandle = function(<arguments>) use (<scope-imported variables>){
//...your code here...
}
To avoid having too many comparisons jump to next loop when you have determined where your number belongs.
function countOccurences( array $numbersArray ):array
{
$return = array('n80to90' => 0, 'n90to100' => 0, 'n100to110' => 0);
foreach( $numbersArray as $number ){
if( $number < 80 || $number > 110 )
continue;
if($number < 91){
$return['n80to90']++;
continue;
}
if($number < 101){
$return['n90to100']++;
continue;
}
$return['n100to110']++;
}
return $return;
}
I cannot imagine that your statistical graphic that would want to represent values on the cusp of two groups as belonging to both groups. For this reason, I'll offer a condition-less function-less technique which can be execute in a foreach loop.
Code: (Demo)
$sampleData = range(80, 110);
$result = array_fill_keys(['80s', '90s', '100s'], 0); // set 0 defaults for incrementation
foreach ($sampleData as $value) {
++$result[(10 * ((int)($value / 10) <=> 9) + 90) . 's'];
}
var_export($result);
Output:
array (
'80s' => 10,
'90s' => 10,
'100s' => 11,
)
My technique manufactures the appropriate keys from the values by:
Dividing by 10
Truncating the decimal (same effect as floor()
Making a 3-way comparison via the spaceship operator (returns -1, 0, or 1)
Multiplying the "-1|0|1" by 10
Adding 90
And finally concatenating an "s".
The ++ means add 1 to the current value of the element with the corresponding key.
Alternatively, if you wanted to group the values as "90+below" (80-90), "100+below" (91-100), and "110+below" (101-110), then it is a simple matter of adjusting the key-generating factors.
Instead of counting, I'll show the elements assigned to each group.
Code: (Demo)
$sampleData = range(80, 110);
foreach ($sampleData as $value) {
$result[(10 * ((int)(($value - 1) / 10) <=> 9) + 100) . '+under'][] = $value;
}
var_export($result);
Output:
array (
'90+under' =>
array (
0 => 80,
1 => 81,
2 => 82,
3 => 83,
4 => 84,
5 => 85,
6 => 86,
7 => 87,
8 => 88,
9 => 89,
10 => 90,
),
'100+under' =>
array (
0 => 91,
1 => 92,
2 => 93,
3 => 94,
4 => 95,
5 => 96,
6 => 97,
7 => 98,
8 => 99,
9 => 100,
),
'110+under' =>
array (
0 => 101,
1 => 102,
2 => 103,
3 => 104,
4 => 105,
5 => 106,
6 => 107,
7 => 108,
8 => 109,
9 => 110,
),
)

How to get array key with less than values

I have 2 arrays:
$arr_1=array(200, 300, 200, 200);
$arr_2=array(
1 => array(70, 90, 70, 20),
2 => array(115, 150, 115, 35),
3 => array(205, 250, 195, 55),
4 => array(325, 420, 325, 95),
5 => array(545, 700, 545, 155)
);
Now I need some way to get array keys for arrays in $arr_1 where all their values are less than all values from $arr_2.
In the above example it must return key 1 AND key 2 from $arr_2 without using a foreach loop.
You can use array_filter to filter the elements (it preserves keys) and then pass the result to array_keys to receive an array of keys.
Also, your condition can be spelled this way: "return subarrays from $arr_2 where highest value is smaller than smallest value of $arr_1."
$arr_1=array(200, 300, 200, 200);
$arr_2=array(
1 => array(70, 90, 70, 20),
2 => array(115, 150, 115, 35),
3 => array(205, 250, 195, 55),
4 => array(325, 420, 325, 95),
5 => array(545, 700, 545, 155)
);
$filtered = array_filter($arr_2, function($value) use ($arr_1) {
return max($value) < min($arr_1);
});
$keys = array_keys($filtered);
var_dump($keys);
If you are only interested in comparing the subarrays against the lowest value in $arr_1, then best practices dictates that you declare that value before entering the array_filter(). This will spare the function having to call min() on each iteration. (Demo)
$arr_1=[200,300,200,200];
$arr_2=[
1=>[70,90,70,20],
2=>[115,150,115,35],
3=>[205,250,195,55],
4=>[325,420,325,95],
5=>[545,700,545,155]
];
$limit=min($arr_1); // cache this value, so that min() isn't called on each iteration in array_filter()
$qualifying_keys=array_keys(array_filter($arr_2,function($a)use($limit){return max($a)<$limit;}));
var_export($qualifying_keys);
/*
array(
0=>1,
1=>2,
)
*/

if input code is equal to code, set icon

So, I am making a weather app using php and some weather apis. API that I use is giving me code that says what is the weather like. So, for example, if code is 200, that means that current weather is 'Thunderstorm with light rain'. What I want to do is show an icon for every code.
icon-lightning-4 { 200, 201, 202, 210, 211, 212, 221, 230, 231, 231 }
icon-rainy-2 { 300, 301, 302, 310, 311, 312, 313, 314, 321, 520, 521, 522, 531 }
icon-rainy { 500, 501, 502, 503, 504 }
icon-snowy-3 { 511, 600, 601, 602, 611, 612, 615, 616, 620, 621, 622 }
icon-air { 701, 711, 721, 731, 741, 751, 761, 761, 771, 781 }
icon-sun { 800 }
icon-moon { 800 }
icon-cloudy { 801 }
icon-cloud-3 { 801 }
icon-cloud-4 { 802 }
icon-cloudy-2 { 803, 804 }
Above you can see Icon name and codes inside curly brackets. How to achieve this with PHP to show icon instead of code. I am not a PHP developer, but I am learning and that's why I am asking this. Help very appreciated. These icon names on the left are actually span classes that show icons.
I would just put the codes into an array and loop through them using the foreach construct:
<?php
$iconMap = array(
'icon-lightning-4' => array(200, 201, 202, 210, 211, 212, 221, 230, 231, 231),
'icon-rainy-2' => array(300, 301, 302, 310, 311, 312, 313, 314, 321, 520, 521, 522, 531),
'icon-rainy' => array(500, 501, 502, 503, 504),
'icon-snowy-3' => array(511, 600, 601, 602, 611, 612, 615, 616, 620, 621, 622),
'icon-air' => array(701, 711, 721, 731, 741, 751, 761, 761, 771, 781),
'icon-sun' => array(800),
'icon-moon' => array(800),
'icon-cloudy' => array(801),
'icon-cloud-3' => array(801),
'icon-cloud-4' => array(802),
'icon-cloudy-2' => array(803, 804)
);
$icon = '';
foreach ($iconMap as $iconString => $codes) {
if (in_array($result, $codes, true)) {
$icon = $iconString;
break; // stop looping, for efficiency
}
}
I've called the result from the API $result here.
What this code is doing:
Creating an associative array with the codes corresponding to each icon name
Looping through this array
For each icon name, it is checking whether $result is in the array of codes using in_array
If it is, it will set $icon to be the icon name and stop looping.
If the code is not found, $icon will simply be an empty string.
You can use the string $icon to output your image, for instance:
if (!empty($icon)) {
echo "<img src='{$icon}.png' alt='...'>";
}
Well its hard to give you the right code since there isn't that much there,... But this is what I would do:
PHP:
// for the lightning icon...
if ($code == 200||201||202||210||211||212||221||230||231||231){
$image_URL = "icon_lightning.png";
}
HTML:
<img src='<?php echo $image_URL ?>' width='50px' height='50px'></img>

Categories