I am trying to get string from JSON, that i should use later. The problem is that my code (depending which file i use) doesn't give me my string with special characters. Strange thing is that one file does everything right, while other is not, even through they contain exactly the same PHP code.
This is that i get from the first one:
[title] => 1611 Plikiškiai–Kriukai (Incorrect)
And from another:
[title] => 1611 Plikiškiai–Kriukai (Correct one)
Here is some code:
function get_info($id) {
$json = file_get_contents('http://restrictions.eismoinfo.lt/');
$array = json_decode($json, true);
//get object/element with such id, so then it would be possible take needed parts/values
$result_array = array();
foreach ($array as $key => $value) {
if ($id == $value['_id']){
$result_array = $value;
}
}
//Street name
$title = $result_array['location']['street'];
echo $title;
}
get_info($id); //$id is some string like 143crt9tDgh5
1st file is located in folder "test", while 2nd in "project".
Any ideas why is that happening?
Related
I need to merge/join multiple json string that contains arrays (which also need to be merged) but I don't know what is the best way to achieve this :
Initial array of json strings (called $rrDatas in my example below):
Array
(
[0] => {"asset":[1],"person":[1]}
[1] => {"asset":[2]}
)
Expected result :
{"asset":[1,2],"person":[1]}
The main difficulty is that the number of arrays is undefined (my example is made with 2 arrays but it could be 3,4 etc.). The second difficulty is that there can be multiple properties (like "asset", "person" etc. however always arrays). These possible properties are known but are many so it would be better if the algorithm is dynamic.
What I am able to do at the moment :
$mergedAssets['asset'] = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
$mergedAssets['asset'] = array_merge($mergedAssets['asset'],$rrDataJson['asset']);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);
Result :
{"asset":[1,2]}
This works well but this is not dynamic, should I duplicate this part for each possible properties (i.e. "person", etc.) ?
Thanks,
Guillaume
Edit : Brett Gregson's and krylov123's answers below helped me build my own solution which is a mix between both suggestion:
$mergedJson = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
foreach(array_keys($rrDataJson) as $property)
{
$mergedJson[$property] = array_merge($mergedJson[$property] ?? [], $rrDataJson[$property]);
}
}
return \GuzzleHttp\json_encode($mergedJson, true);
Find below a better example :
$rrDatas = Array (
[0] => {"asset":[1,2],"person":[1],"passive":[1]}
[1] => {"asset":[3],"charge":[1],"passive":[2]}
)
Which must result in :
{"asset":[1,2,3],"person":[1],"passive":[1,2],"charge":[1]}
Edit 2 : I have just tried Progrock's solution and it seems to work perfectly as well : https://3v4l.org/7hSqi
You can use something like:
$output = []; // Prepare empty output
foreach($rrDatas as $inner){
foreach($inner as $key => $value){
$output[$key][] = $value;
}
}
echo json_encode($output); // {"asset":[1,2],"person":[1]}
Which should give you the desired output. This should work regardless of the keys within the individual arrays and even with empty arrays.
Working example here
Another example with more arrays and more keys and empty arrays
<?php
$array =
[
'{"asset":[1],"person":[1]}',
'{"asset":[2]}',
];
$array = array_map(function($v) { return json_decode($v, true);}, $array);
$merged = array_merge_recursive(...$array);
print json_encode($merged);
Output:
{"asset":[1,2],"person":[1]}
You need to use foreach ($array as $key => $value) iteration, to be able to dynamicaly use keys of your json array (e.g. "asset" and "person").
Solution:
$mergedAssets['asset'] = [];
foreach ($rrDatas as $key => $value)
{
$rrDataJson = \GuzzleHttp\json_decode($value, true);
$mergedAssets[$key] = array_merge($mergedAssets[$key],$rrDataJson[$key]);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);
I am recently facing a practical problem.I am working with ajax form submission and there has been some checkboxes.I need all checkboxes with same name as key value pair.Suppose there is 4 checkboxes having name attribute =checks so i want something like $arr['checks'] = array(value1, value2, ...)
So i am getting my ajax $_POST code as suppose like: name=alex&checks=code1&checks=code2&checks=code3
I am using below code to make into an array
public function smdv_process_option_data(){
$dataarray = array();
$newdataarray = array();
$new = array();
$notices = array();
$data = $_POST['options']; // data received by ajax
$dataarray = explode('&', $data);
foreach ($dataarray as $key => $value) {
$i = explode('=', $value);
$j = 1;
if(array_key_exists($i[0], $newdataarray)){
if( !is_array($newdataarray[$i[0]]) ){
array_push($new, $newdataarray[$i[0]]);
}else{
array_push($new, $i[1]);
}
$newdataarray[$i[0]] = $new;
}else{
$newdataarray[$i[0]] = $i[1];
}
}
die($newdataarray);
}
Here i want $newdataarray as like below
array(
'name' => 'alex',
'checks => array(code1, code2, code3),
)
But any how I am missing 2nd value from checks key array.
As I see it you only need to do two explode syntaxes.
The first on is to get the name and here I explode on & and then on name= in order to isolate the name in the string.
The checks is an explode of &checks= if you omit the first item with array_slice.
$str = 'name=alex&checks=code1&checks=code2&checks=code3';
$name = explode("name=", explode("&", $str)[0])[1];
// alex
$checks = array_slice(explode("&checks=", $str), 1);
// ["code1","code2","code3"]
https://3v4l.org/TefuG
So i am getting my ajax $_POST code as suppose like: name=alex&checks=code1&checks=code2&checks=code3
Use parse_str instead.
https://php.net/manual/en/function.parse-str.php
parse_str ( string $encoded_string [, array &$result ] ) : void
Parses encoded_string as if it were the query string passed via a URL and sets variables in the current scope (or in the array if result is provided).
$s = 'name=alex&checks=code1&checks=code2&checks=code3';
parse_str($s, $r);
print_r($r);
Output
Array
(
[name] => alex
[checks] => code3
)
You may think this is wrong because there is only one checks but technically the string is incorrect.
Sandbox
You shouldn't have to post process this data if it's sent correctly, as that is not included in the question, I can only make assumptions about it's origin.
If your manually creating it, I would suggest using serialize() on the form element for the data for AJAX. Post processing this is just a band-aid and adds unnecessary complexity.
If it's from a source outside your control, you'll have to parse it manually (as you attempted).
For example the correct way that string is encoded is this:
name=alex&checks[]=code1&checks[]=code2&checks[]=code3
Which when used with the above code produces the desired output.
Array
(
[name] => alex
[checks] => Array
(
[0] => code1
[1] => code2
[2] => code3
)
)
So is the problem here, or in the way it's constructed...
UPDATE
I felt obligated to give you the manual parsing option:
$str = 'name=alex&checks=code1&checks=code2&checks=code3';
$res = [];
foreach(explode('&',$str) as $value){
//PHP 7 array destructuring
[$key,$value] = explode('=', $value);
//PHP 5.x list()
//list($key,$value) = explode('=', $value);
if(isset($res[$key])){
if(!is_array($res[$key])){
//convert single values to array
$res[$key] = [$res[$key]];
}
$res[$key][] = $value;
}else{
$res[$key] = $value;
}
}
print_r($res);
Sandbox
The above code is not specific to your keys, which is a good thing. And should handle any string formatted this way. If you do have the proper array format mixed in with this format you can add a bit of additional code to handle that, but it can become quite a challenge to handle all the use cases of key[] For example these are all valid:
key[]=value&key[]=value //[key => [value,value]]
key[foo]=value&key[bar]=value //[key => [foo=>value,bar=>value]]
key[foo][]=value&key[bar][]=value&key[bar][]=value //[key => [foo=>[value]], [bar=>[value,value]]]
As you can see that can get out of hand real quick, so I hesitate to try to accommodate that if you don't need it.
Cheers!
I want to create a json object using php like below as I need to create a stacked bar chart using d3.js, hence I am using data from oracle table and need the json data as above image.
My table has these 3 columns. (ID, NAME, Layers) like:-
ID, NAME, Layers
1 ABC a:8,b:10
2 WWW c:8,d:7
When I am fetching data from oracle, my php code is:-
while (($row = oci_fetch_array($stid, OCI_ASSOC))) {
$streamArr[] = $row;
}
header("Access-Control-Allow-Origin: *");
echo json_encode($streamArr);
I am getting this error:-
Warning: [json] (php_json_encode) type is unsupported, encoded as null in line 48
json output as:-
[["1","ABC",{"descriptor":null}],["2","WWW",{"descriptor":null}]]
can you please help me in rectifying with this issue?
The error message refers to a field you didn't mention in the example. Maybe just don't select unneeded fields?
If you fix that, you still won't get the desired JSON structure. To get layers as an object in every element of data in the resulting JSON, you need to convert the string values stored in the database to PHP arrays before encoding.
You could do that with similar code:
while (($row = oci_fetch_array($stid, OCI_ASSOC)))
{
$row['layers'] = array_map(function($el) {
return explode(':', $el);
}, explode(',', $row['layers']));
$streamArr[] = $row;
}
#marekful answer is really nice, not easiest to understand but efficient and short!
Here you have a longer and not so efficient, but maybe easier to get.
$streamArr = array();
while (($row = oci_fetch_array($stid, OCI_ASSOC)))
{
// Get ID and NAME
$data = array(
'id' => $row['ID'],
'name' => $row['NAME'],
'layers' => array()
);
// Get Layers by split by comma
$layers = explode(',', $row['layers']);
foreach ($layers as $layer) {
// Get layer parts by slit with double-point
$layersPart = explode(':', $layer);
foreach ($layersPart as $key => $value) {
$data['layers'][$key] = $value;
}
}
// Add to global array
$streamArr[] = $data;
}
echo json_encode($streamArr);
I’m attempting to use the values from one JSON link to populate values in other JSON links resulting in a unique list of values from the combined JSON. I’ve gotten as far as creating the complete list of values, but I’m having a difficult time finding the syntax in the final loop to display only the unique values. Any help would be appreciated.
$collection_string = file_get_contents("http://some_json_url.com/json");
$collection_list = json_decode($collection_string, true);
foreach ($collection_list as $col_lists => $col_list) {
$object_string = file_get_contents('http://another_json_url.com/'.$col_list['key'].'/json');
$object_list = json_decode($object_string, true);
$object_array = array();
foreach ($object_list as $objects => $object) {
$object_array [] = array_unique($object); //Returns "Warning: array_unique() expects parameter 1 to be array, string given in..."
echo '<li>'.$object_array.'</li>'; //Returns "Array"
echo '<li>'.$object.'</li>'; //Returns complete list
}
}
Working code:
$collection_string = file_get_contents("http://some_json_url.com/json");
$collection_list = json_decode($collection_string, true);
$object_array = array();
foreach ($collection_list as $col_lists => $col_list) {
$object_string = file_get_contents('http://another_json_url.com/'.$col_list['key'].'/json');
$object_list = json_decode($object_string, true);
foreach ($object_list as $key => $value) {
array_push($object_array, $value);
}
}
$object_unique = array_unique($object_array);
natcasesort($object_unique);
foreach ($object_unique as $key => $value) {
echo '<li>'.$value.'</li>';
}
Simply change this
$object_array [] = array_unique($object);
to that
$object_array [] = $object; // edited !
array_unique($object_array);
Maybe you can also do this with one line of code, but I dont know how to write it. But the way the way I wrote it it's a little bit unoptimized, it would be better to simply do the array_unique() only one time, right after the final loop.
Btw your problem is/was that you tried to make $object unique, which is not an array. it's a string/object.
In a mysql database I store some image names without the exact path.
So what I like to do is add the path before I load the returned array into jQuery (json) to use it in the JQ Galleria plugin.
In the columns I've got names likes this:
11101x1xTN.png 11101x2xTN.png 11101x3xTN.png
Which in the end should be like:
./test/img/cars/bmw/11101/11101x1xTN.png
./test/img/cars/bmw/11101/11101x2xTN.png
I could just add the whole path into the database but that seems 1. a wast of db space. 2. Then I need to update he whole db if the images path changes.
I could edit the jQuery plugin but it doesn't seem practical to update the source code of it.
What is the right thing to do and the fasted for processing?
Can you add a string after you make a db query and before you fetch the results?
part of the function where I make the query:
$needs = "thumb, image, big, title, description";
$result = $get_queries->getImagesById($id, $needs);
$sth=$this->_dbh->prepare("SELECT $needs FROM images WHERE id = :stockId");
$sth->bindParam(":stockId", $id);
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
this is the foreach loop:
$addurl = array('thumb', 'image', 'big');
foreach ($result as $array) {
foreach ($array as $item => $val) {
if (in_array($item, $addurl)){
$val = '/test/img/cars/bmw/11101/'.$val;
}
}
}
the array looks like this:
Array
(
[0] => Array
(
[thumb] => 11101x1xTN.png
[image] => 11101x1xI.png
[big] => 11101x1xB.png
[title] => Title
[description] => This a blub.
)
)
The url should be add to thumb, image and big.
I tried to change the array values using a foreach loop but that didn't work. Also not noting if the use of that would course a unnecessary slowdown.
well, you almost nailed it. only thing you forgot is to store your $val back in array.
foreach ($result as $i => $array) {
foreach ($array as $item => $val) {
if (in_array($item, $addurl)){
$val = '/test/img/cars/bmw/11101/'.$val;
$result[$i][$item] = $val;
}
}
}
however, I'd make it little shorter
foreach ($result as $i => $array) {
foreach ($addurl as $item) {
$result[$i][$item] = '/test/img/cars/bmw/11101/'.$array[$item];
}
}
}
Assuming your array looks like this:
$result = array("11101x1xTN.png", "11101x2xTN.png", "11101x3xTN.png");
A simple array_map() can be used.
$result_parsed = array_map(function($str) { return './test/img/cars/bmw/11101/'.$str; }, $result);
As seen Here