I'm really struggling to parse a JSON string with PHP. The link below contains the JSON that I'm trying to parse: http://finance.google.com/finance/info?client=ig&q=NASDAQ:MSFT,NASDAQ:GOOG,NASDAQ:AAPL
Can anyone help, I've tried everything but I'm still new to this.
Thanks.
if there are no // in start of string use
$json_data = '[ { "id": "358464" ,"t" : "MSFT" ,"e" : "NASDAQ" ,"l" : "25.80" ,"l_cur" : "25.80" ,"s": "1" ,"ltt":"4:00PM EDT" ,"lt" : "Sep 2, 4:00PM EDT" ,"c" : "-0.41" ,"cp" : "-1.56" ,"ccol" : "chr" ,"el": "25.44" ,"el_cur": "25.44" ,"elt" : "Sep 6, 4:35AM EDT" ,"ec" : "-0.36" ,"ecp" : "-1.40" ,"eccol" : "chr" ,"div" : "0.16" ,"yld" : "2.48" } ,{ "id": "694653" ,"t" : "GOOG" ,"e" : "NASDAQ" ,"l" : "524.84" ,"l_cur" : "524.84" ,"s": "0" ,"ltt":"4:00PM EDT" ,"lt" : "Sep 2, 4:00PM EDT" ,"c" : "-7.66" ,"cp" : "-1.44" ,"ccol" : "chr" } ,{ "id": "22144" ,"t" : "AAPL" ,"e" : "NASDAQ" ,"l" : "374.05" ,"l_cur" : "374.05" ,"s": "1" ,"ltt":"4:00PM EDT" ,"lt" : "Sep 2, 4:00PM EDT" ,"c" : "-6.98" ,"cp" : "-1.83" ,"ccol" : "chr" ,"el": "371.45" ,"el_cur": "371.45" ,"elt" : "Sep 6, 6:02AM EDT" ,"ec" : "-2.60" ,"ecp" : "-0.70" ,"eccol" : "chr" ,"div" : "" ,"yld" : "" } ]';
$json_object = json_decode($json_data);
with // use
$json_data = '......';
$json_data = trim(substr($json_data,2));
$json_object = json_decode($json_data);
result
array (
0 =>
stdClass::__set_state(array(
'id' => '358464',
't' => 'MSFT',
'e' => 'NASDAQ',
'l' => '25.80',
'l_cur' => '25.80',
's' => '1',
'ltt' => '4:00PM EDT',
'lt' => 'Sep 2, 4:00PM EDT',
'c' => '-0.41',
'cp' => '-1.56',
'ccol' => 'chr',
'el' => '25.44',
'el_cur' => '25.44',
'elt' => 'Sep 6, 4:35AM EDT',
'ec' => '-0.36',
'ecp' => '-1.40',
'eccol' => 'chr',
'div' => '0.16',
'yld' => '2.48',
)),
1 =>
stdClass::__set_state(array(
'id' => '694653',
't' => 'GOOG',
'e' => 'NASDAQ',
'l' => '524.84',
'l_cur' => '524.84',
's' => '0',
'ltt' => '4:00PM EDT',
'lt' => 'Sep 2, 4:00PM EDT',
'c' => '-7.66',
'cp' => '-1.44',
'ccol' => 'chr',
)),
2 =>
stdClass::__set_state(array(
'id' => '22144',
't' => 'AAPL',
'e' => 'NASDAQ',
'l' => '374.05',
'l_cur' => '374.05',
's' => '1',
'ltt' => '4:00PM EDT',
'lt' => 'Sep 2, 4:00PM EDT',
'c' => '-6.98',
'cp' => '-1.83',
'ccol' => 'chr',
'el' => '371.45',
'el_cur' => '371.45',
'elt' => 'Sep 6, 6:02AM EDT',
'ec' => '-2.60',
'ecp' => '-0.70',
'eccol' => 'chr',
'div' => '',
'yld' => '',
)),
)
json_decode documentation: http://php.net/json_decode
In your source they are commenting out the JSON. It's pretty weird that they do it, but anyway the // at the start is screwing it up.
$url = 'http://finance.google.com/finance/info?client=ig&q=NASDAQ:MSFT,NASDAQ:GOOG,NASDAQ:AAPL';
$json = preg_replace('#^\s+//#', '', file_get_contents($url) );
$decoded = json_decode( $json );
var_dump( $decoded );
Related
This is my array of objects in php:
Array( [0]=>
Array (
[added_time] => 2018-12-09 14:00:00+00
[id] => 123
[places] =>
[{
"place_id" : 1,
"total" : 5,
"empty" : 0,
"weight" : 68000,
"persons" :
[{
"person_id" : 2,
"person_name" : "ABC",
"total":100
},
{
"person_id" : 3
"person_name" : "DEF",
"total":200
}]
},
"place_id" : 4,
"total" : 10,
"empty" : 0,
"weight" : 54000,
"persons" :
[{
"person_id" : 2,
"person_name" : "ABC"
"total":100
},
{
"person_id" : 6
"person_name" : "GHI",
}
]
],
),
Array (
[added_time] => 2018-12-09 15:00:00+00
[id] => 456
[places] =>
[{
"place_id" : 1,
"total" : 5,
"empty" : 0,
"weight" : 68000,
"persons" :
[{
"person_id" : 2,
"person_name" : "ABC",
"total":200
},
{
"person_id" : 3
"person_name" : "DEF",
"total":300
}]
}]
)
)
I am trying to get sum on the base of person_id like group by person_id.
My desired result should be:
Array (
[added_time] => 2018-12-09 14:00:00+00
[id] => 123
persons:array(
Array([0]=>
[person_id] : 2,
[person_name] : "ABC",
[total]:200
),
Array([1]=>
[person_id] : 3,
[person_name] : "DEF",
[total]:300
),
Array([2]=>
[person_id] : 6,
[person_name] : "GHI",
[total]:500
)
),
[added_time] => 2018-12-09 15:00:00+00
[id] => 123
persons:array(
Array([0]=>
[person_id] : 2,
[person_name] : "ABC",
[total]:200
),
Array([1]=>
[person_id] : 3,
[person_name] : "DEF",
[total]:300
)
)
)
How can I achieve this result. I can use foreach but I don't want to use it because of three iterations.
Is there any other method to achieve this in php and without any performance issue?
You can have that by using PHP function as array-merge, array-column, array-reduce.
Let divided that to 3 step:
1.Sum total for all person given list of persons. Define the the following reduce function:
function reduce($carry, $item)
{
if (!in_array($item["person_name"], array_column($carry, "person_name")))
$carry[] = $item;
else {
foreach($carry as &$person) {
if ($item["person_name"] == $person["person_name"])
$person["total"] += $item["total"];
}
}
return $carry;
}
2.For every element in your array create you output using the reduce from step 1:
function reduceElement($arr) {
$res = array("added_time" => $arr["time"], "id" => $arr["id"]);
$persons = array();
foreach($arr["places"] as $place) {
$persons = array_merge($persons, $place["persons"]);
}
$res["persons"] = array_reduce($persons, "reduce", array());
return $res;
}
3.Combine it all:
$elemA= array("id"=>1, "time"=>"2018", "places" => array(array("persons" => array(array("person_name" => "ABC", "total" => 100), array("person_name" => "DEF", "total" => 200))), array("persons" => array(array("person_name" => "ABC", "total" => 100), array("person_name" => "GHI", "total" => 100)))));
$elemB = array("id"=>2, "time"=>"2017", "places" => array(array("persons" => array(array("person_name" => "ABC", "total" => 200), array("person_name" => "DEF", "total" => 300)))));
$arr = array($elemA, $elemB);
$res = array();
foreach($arr as $obj)
$res[] = reduceElement($obj);
print_r($res);
This will give you the require out put
I have the following :
$data = [
{model_num : "ABC", revision : "AA", "testRecipeID":85, value : 31.25, treatment : 'Pressure' },
{model_num : "ABC", revision : "AA", "testRecipeID":85, value : 31.25, treatment : 'Gas' },
{model_num : "ABC", revision : "AA", "testRecipeID":85, value : 33.12, treatment : 'Temp' },
{model_num : "ABC", revision : "AA", "testRecipeID":85, value : 25.87, treatment : 'Current' },
{model_num : "ABC", revision : "AB", "testRecipeID":86, value : 26.63, treatment : 'Pressure' },
{model_num : "ABC", revision : "AB", "testRecipeID":86, value : 26.00, treatment : 'Gas' },
{model_num : "ABC", revision : "AB", "testRecipeID":86, value : 23.75, treatment : 'Temp' }
];
and i would like to end up with something like this:
var data=[{model_num : "ABC", revision : "AA", "testRecipeID":85, "Pressure":31.25, "Gas":31.25, "Temp": 33.12,"Current":25.87 },{model_num : "ABC", revision : "AB", "testRecipeID":86, "Gas":26.00,"Temp":23.75}]
I know how to do this in JS but not on PHP and it turns out I need to do it in my php so that I can process the large amounts of data that I have. I have this based on another question that I found but It doesn't work it returns a 0
$table = array();
$round_names = array();
$total = array();
foreach ($data as $score)
{
$round_names[] = $score->treatment;
$table[$score->testRecipeID][$score->treatment] = $score->value;
$total[$score->testRecipeID] += $score->value;
print_r($round_names);
}
$round_names = array_unique($round_names);
foreach ($table as $player => $rounds)
{
echo "$player\t";
foreach ($round_names as $round)
echo "$rounds[$round]\t";
echo "$total[$player]\n";
}
any help will be greatly appreciated!
this is how i do it in JS
var result = [];
data.forEach(function(e) {
var a = e.model_num + '|' + e.revision+ '|'e.recipeID;
if(!this[a]) {
this[a] = {model_num: e.model_num, revision: e.revision, recipeID: e.recipeID}
result.push(this[a]);
}
this[a][e.treatment] = e.value;
}, {});
If you need the structure, you can try with JSON Encode:
<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
echo json_encode($arr);
?>
Which outputs:
{"a":1,"b":2,"c":3,"d":4,"e":5}
If you need it to be an array, use:
echo json_encode(array($arr));
This is your JS function in PHP
<?php
$data = '[
{"model_num" : "ABC", "revision" : "AA", "testRecipeID":85, "value" : 31.25, "treatment" : "Pressure" },
{"model_num" : "ABC", "revision" : "AA", "testRecipeID":85, "value" : 31.25, "treatment" : "Gas" },
{"model_num" : "ABC", "revision" : "AA", "testRecipeID":85, "value" : 33.12, "treatment" : "Temp" },
{"model_num" : "ABC", "revision" : "AA", "testRecipeID":85, "value" : 25.87, "treatment" : "Current" },
{"model_num" : "ABC", "revision" : "AB", "testRecipeID":86, "value" : 26.63, "treatment" : "Pressure" },
{"model_num" : "ABC", "revision" : "AB", "testRecipeID":86, "value" : 26.00, "treatment" : "Gas" },
{"model_num" : "ABC", "revision" : "AB", "testRecipeID":86, "value" : 23.75, "treatment" : "Temp" }
]';
$data = json_decode($data);
$result = [];
foreach ($data as $row) {
$a = $row->model_num . '|' . $row->revision . '|' . $row->testRecipeID;
if (! array_key_exists($a, $result)) {
$result[$a] = [
'model_num' => $row->model_num,
'revision' => $row->revision,
'testRecipeID' => $row->testRecipeID
];
}
}
Because neither of the previous answers managed to provide the desired output, I am compelled to answer this pivot question.
Create a temporary string from the 3 identifying column values.
Use that string as the first level key while grouping related row data.
The null coalescing assignment operator spares you needing to call isset() to check if the group has been encountered before. If it is the first encounter, save the three core elements to the row.
Unconditionally push the dynamically keyed value into the group's row.
5 When finished iterating clear away the temporary keys with array_values().
Code: (Demo)
$data = [
['model_num' => 'ABC', 'revision' => 'AA', 'testRecipeID' => 85, 'value' => 31.25, 'treatment' => 'Pressure'],
['model_num' => 'ABC', 'revision' => 'AA', 'testRecipeID' => 85, 'value' => 31.25, 'treatment' => 'Gas'],
['model_num' => 'ABC', 'revision' => 'AA', 'testRecipeID' => 85, 'value' => 33.12, 'treatment' => 'Temp'],
['model_num' => 'ABC', 'revision' => 'AA', 'testRecipeID' => 85, 'value' => 25.87, 'treatment' => 'Current'],
['model_num' => 'ABC', 'revision' => 'AB', 'testRecipeID' => 86, 'value' => 26.63, 'treatment' => 'Pressure'],
['model_num' => 'ABC', 'revision' => 'AB', 'testRecipeID' => 86, 'value' => 26.0, 'treatment' => 'Gas'],
['model_num' => 'ABC', 'revision' => 'AB', 'testRecipeID' => 86, 'value' => 23.75, 'treatment' => 'Temp']
];
$result = [];
foreach ($data as $row) {
$compositeKey = "{$row['model_num']}-{$row['revision']}-{$row['testRecipeID']}";
$result[$compositeKey] ??= [
'model_num' => $row['model_num'],
'revision' => $row['revision'],
'testRecipeID' => $row['testRecipeID']
];
$result[$compositeKey][$row['treatment']] = $row['value'];
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'model_num' => 'ABC',
'revision' => 'AA',
'testRecipeID' => 85,
'Pressure' => 31.25,
'Gas' => 31.25,
'Temp' => 33.12,
'Current' => 25.87,
),
1 =>
array (
'model_num' => 'ABC',
'revision' => 'AB',
'testRecipeID' => 86,
'Pressure' => 26.63,
'Gas' => 26.0,
'Temp' => 23.75,
),
)
In a lyrics application I'm coding, I'm using an array to print an artists table. The artists array looks like this:
$artists = [
[ "Avril Lavigne" ],
[ "3 Doors Down" ],
[ "Celine Dion" ],
[ "Evanescence" ],
[ "Shania Twain" ],
[ "Green Day" ],
//...
];
Before printing it, I do some modification to the array. I have a folder for each artist that contains the lyrics files. I add the folder names to the $artists array for later use:
$folder_fix = [
[" ", "_" ],
[".", "" ],
["&", "n" ],
];
for ($i = 0; $i < count($artists); $i++) {
$folder_name = strtolower($artists[$i][0]);
for ($k = 0; $k < count($folder_fix); $k++) {
$folder_name = str_replace($folder_fix[$k][0], $folder_fix[$k][1], $folder_name);
}
array_push($artists[$i], $folder_name);
}
Later, I add the album and track count for each artist to the array:
$lyrics_base = "lyrics/";
for ($i = 0; $i < count($artists); $i++) {
$albums_path = $lyrics_base . $artists[$i][1] . "/*";
$tracks_path = $lyrics_base . $artists[$i][1] . "/*/*";
$albums = count(glob($albums_path));
$tracks = count(glob($tracks_path));
array_push($artists[$i], $albums);
array_push($artists[$i], $tracks);
}
The end result of the array looks like this:
$artists = [
[ "Avril Lavigne", "avril_lavigne", 5, 61 ],
[ "3 Doors Down", "3_doors_down", 5, 13 ],
[ "Celine Dion", "celine_dion", 7, 22 ],
[ "Evanescence", "evanescence", 4, 10 ],
[ "Shania Twain", "shania_twain", 3, 12 ],
[ "Green Day", "green_day", 8, 26 ],
//...
];
Now, my problem is that this process happens every time I visit the page. The 2nd, 3rd, and the 4th columns are created again and again. I think this is redundant.
I want to save the end result of the array and use it on the page. If this was JavaScript I'd use JSON.stringify(), but in PHP I don't know how to get the end result of the array. print_r() doesn't do the job, because it prints it like this:
Array
(
[0] => Array
(
[0] => Avril Lavigne
[1] => avril_lavigne
[2] => 5
[3] => 61
)
[1] => Array
(
[0] => 3 Doors Down
[1] => 3_doors_down
[2] => 5
[3] => 13
)
...
I want it like this:
[
[
"Avril Lavigne",
"avril_lavigne",
5,
61
],
[
"3 Doors Down",
"3_doors_down",
5,
13
],
//...
]
Is there a way to print the array the JSON.stringify() way?
Is this what you want?
echo json_encode($artists)
PHP: json_encode
You can use this simple function from my CMS EFFCORE:
function data_stringify($data) {
switch (gettype($data)) {
case 'string' : return '\''.addcslashes($data, "'\\").'\'';
case 'boolean': return $data ? 'true' : 'false';
case 'NULL' : return 'null';
case 'object' :
case 'array' :
$expressions = [];
foreach ($data as $c_key => $c_value) {
$expressions[] = data_stringify($c_key).' => '.
data_stringify($c_value);
}
return gettype($data) === 'object' ?
'(object)['.implode(', ', $expressions).']' :
'['.implode(', ', $expressions).']';
default: return (string)$data;
}
}
TEST
var_dump( data_stringify(-1 ) === '-1' );
var_dump( data_stringify(-1.1 ) === '-1.1' );
var_dump( data_stringify(123e1 ) === '1230' ); # exponential notation
var_dump( data_stringify(0x123 ) === '291' ); # hexadecimal notation
var_dump( data_stringify(01234 ) === '668' ); # octal notation
var_dump( data_stringify(0b101 ) === '5' ); # binary notation
var_dump( data_stringify('а123') === "'а123'" );
var_dump( data_stringify('123а') === "'123а'" );
var_dump( data_stringify(true ) === 'true' );
var_dump( data_stringify(false ) === 'false' );
var_dump( data_stringify(null ) === 'null' );
array
var_dump(
data_stringify([
100,
'200',
'item3' => 300,
'item4' => '400',
'item5' => 'value500'
]) === "[".
"0 => 100, ".
"1 => '200', ".
"'item3' => 300, ".
"'item4' => '400', ".
"'item5' => 'value500']"
);
object
var_dump(
data_stringify((object)[
'prop1' => 100,
'prop2' => '200',
'prop3' => 'value300'
]) === "(object)[".
"'prop1' => 100, ".
"'prop2' => '200', ".
"'prop3' => 'value300']"
);
array with object
var_dump(
data_stringify([
100,
'200',
'item3' => (object)['prop1' => 1, 'prop2' => '2', 'prop3' => 'value3'],
'item4' => '400',
'item5' => 'value500'
]) === "[".
"0 => 100, ".
"1 => '200', ".
"'item3' => (object)['prop1' => 1, 'prop2' => '2', 'prop3' => 'value3'], ".
"'item4' => '400', ".
"'item5' => 'value500']"
);
object with array
var_dump(
data_stringify((object)[
'prop1' => 1,
'prop2' => '2',
'prop3' => [100, '200', 'item3' => '300', 'item4' => 'value400'],
'prop4' => 'value4'
]) === "(object)[".
"'prop1' => 1, ".
"'prop2' => '2', ".
"'prop3' => [0 => 100, 1 => '200', 'item3' => '300', 'item4' => 'value400'], ".
"'prop4' => 'value4']"
);
The print_r have second parameter.
$string=print_r($array, true);
{
code: "AL",
z: 3204
}, {
code: "DZ",
z: 35468
},
trying to return something similar. I am doing this :
$arr = array ('code'=>array('z'),'US'=>2233332,'c'=>3,'d'=>4,'e'=>5);
echo json_encode($arr);
Just follow the formatting your json:
$foo = array(
array(
'code' => 'AL',
'z' => 3204
),
array(
'code' => 'DZ',
'z' => 35468
)
);
this is the json that my code produces
{
"aaa":1,
"b":2,
"c":3,
"d":4,
"e":5,
"fff":{"a":11111,"b":222222,"c":33333,"d":444454,"e":55555555}
}
and this is the code
<?php
$c = array('a' => 11111, 'b' => 222222, 'c' => 33333, 'd' => 444454, 'e' => 55555555 );
$arr = array('aaa' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5 , 'fff'=>$c);
echo json_encode($arr);
?>
but I want to have some structure like this
{
"aaa":1,
"b":2,
"c":3,
"d":4,
"e":5,
"fff":{"a":11111,"b":222222,"c":33333,"d":444454,"e":55555555},
"last":[
{
"id": 8817,
"loc": "NEW YORK CITY"
},
{
"id": 2873,
"loc": "UNITED STATES"
},
{
"id": 1501,
"loc": "NEW YORK STATE"
}
]
}
I am new in json and php and I need this fast so I do not have time to read about this json structure... So please if someone know how to add this last element please provide some php code.
Thanks,
Take the "json-encoded" string and pass it to json_decode()
assign the return value to a variable
pass that variable to var_export() to get a "php-encoded" string representation of the data.
e.g.
<?php
$json = '{
"aaa":1,
"b":2,
"c":3,
"d":4,
"e":5,
"fff":{"a":11111,"b":222222,"c":33333,"d":444454,"e":55555555},
"last":[
{
"id": 8817,
"loc": "NEW YORK CITY"
},
{
"id": 2873,
"loc": "UNITED STATES"
},
{
"id": 1501,
"loc": "NEW YORK STATE"
}
]
}';
$php = json_decode($json, true);
echo var_export($php);
prints
array (
'aaa' => 1,
'b' => 2,
'c' => 3,
'd' => 4,
'e' => 5,
'fff' =>
array (
'a' => 11111,
'b' => 222222,
'c' => 33333,
'd' => 444454,
'e' => 55555555,
),
'last' =>
array (
0 =>
array (
'id' => 8817,
'loc' => 'NEW YORK CITY',
),
1 =>
array (
'id' => 2873,
'loc' => 'UNITED STATES',
),
2 =>
array (
'id' => 1501,
'loc' => 'NEW YORK STATE',
),
),
)