Foreach PHP looping troubles - php

I'm having trouble decoding my json it seems only to decode one of the "geometry->coordinates" fields like only one polygon. It has something with # LINE 5 to do. How can i fix it will actual work.
i've built what i got now with help from here:
How to extract and access data from JSON with PHP?
# LINE 5
foreach($polygon->features[0]->geometry->coordinates as $coordinates)
# FULL CODE
<?php
$str = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[9.78281,54.923985],[9.80341,54.901586],[9.819803,54.901981],[9.83551,54.908396],[9.825897,54.91481],[9.822721,54.927142],[9.807186,54.927931],[9.792767,54.926797],[9.78281,54.923985]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[9.914474,54.930298],[9.901085,54.912343],[9.849243,54.912146],[9.846497,54.928917],[9.890785,54.946865],[9.930267,54.937399],[9.914474,54.930298]]]}}]}';
$polygon = json_decode($str);
foreach($polygon->features[0]->geometry->coordinates as $coordinates)
{
print_r($coordinates);
}
?>

You are only looping over the first (or zeroth) item by doing $polygon->features[0]. Instead, loop over those features, too:
foreach($polygon->features as $feature){
foreach($feature->geometry->coordinates as $coordinates)
{
print_r($coordinates);
}
}
Demo: https://3v4l.org/kk0uZ

<?php
$str = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[9.78281,54.923985],[9.80341,54.901586],[9.819803,54.901981],[9.83551,54.908396],[9.825897,54.91481],[9.822721,54.927142],[9.807186,54.927931],[9.792767,54.926797],[9.78281,54.923985]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[9.914474,54.930298],[9.901085,54.912343],[9.849243,54.912146],[9.846497,54.928917],[9.890785,54.946865],[9.930267,54.937399],[9.914474,54.930298]]]}}]}';
$polygon = json_decode($str);
foreach($polygon->features as $feature) {
foreach($feature->geometry->coordinates as $coordinates) {
print_r($coordinates);
}
}

Related

PHP - What is the best way to access a property of an object which is an array element

I have an object which is an array of JSON objects. Kinda Like this,
$object = [
{
"id":1,
"name":"blue",
"order":4
},
{
"id":2,
"name":"green",
"order":6
},
{
"id":3,
"name":"yellow",
"order":2
}
]
I wanted to access the properties in a simple way and a single line maybe like this,
Say if I wanted the "order" of the object with name "blue"
$blue_order = $object[something]->[name="blue"]->order;
Kinda mixed Jquery in this. But I hope you understand. Right now the best I've got is this,
for($i=0; $i<count($object); $i++){
if($object[$i]->name == "blue"){
$blue_order = $object[$i]->order;
}
}
This seems very inefficient though and I don't want to use a loop because the array is very large and looping through it will be very slow. So how do I do this?
I used a "for" loop instead of foreach because the array can be null. And also the order of the array elements will not always be the same.
So I can't do something like
$object[0]->order
<?php
$arr = array(
array('id'=>1,'name'=>'blue','order'=>4),
array('id'=>2,'name'=>'green','order'=>6),
array('id'=>3,'name'=>'yellow','order'=>2),
);
// $json is JSON version of the arrays in $arr
$json = json_encode($arr);
// show $json
echo $json . "\n";
// create arrays from JSON so it can be used in PHP easier
$obj = json_decode($json);
$color = 'blue';
$blue_order = array_filter($obj, function($i) use ($color) { return $i->name == $color; })[0]->order;
echo "Blue Order: " . $blue_order;
You may be able to use array_filter to help this become a one-liner. I included the json_decode and json_encode so I could have a complete example.
You could still use foreach but check if the array isn't empty first, like this:
if(!empty($object)){
foreach($object as $element){
if($element->name == "blue"){
$blue_order = $element->order;
}
}
}
Also, your code looks efficient to me, what I would probably add is a break after you find the value, like this:
if(!empty($object)){
foreach($object as $element){
if($element->name == "blue"){
$blue_order = $element->order;
break;
}
}
}
If your object has a lot of information and you're going to do a lot of searches, then you could do some pre-processing so it get easier to search, like this:
$object_by_name = array();
if(!empty($object)){
foreach($object as $element){
$object_by_name[$element->name] = $element;
}
}
Then, you could search it like this:
if(!empty($object_by_name['blue'])){
$blue_order = $object_by_name['blue']->order
}
Keep it simple.
You're writing way too much code.
$array_list = ($array_list)?:[];
$array_list = array_filter($array_list,function($var) {
return ($var->name=="blue");
});
$order = ($array_list)? $array_list[0]->order :'';

PHP - Find and Replace of JSON data

I'm trying to do a find replace of the json data below. I'm trying to replace "Consumer" with "CON", "Industrial" with "IND", and "Technology" with "TCH". Ideally, I would like to pass a function an array of finds (i.e., {"Consumer", "Industrial", "Technology"}) along with an array of replaces (i.e., {"CON", "IND", "TCH"}), or some other way to quickly define multiple find and replace pairs (there will be many more pairs than these 3). What is the best function to do this? Thanks, any help is appreciated.
[{"category":"Consumer","price":"18.9","number":"5"},{"category":"Industrial","price":"13.4","number":"4"},{"category":"Technology","price":"15.5","number":"3"}]
Here's a solution that goes through the json data object piece by piece (examining both key and values and replacing as possible only if the key/value is fully in the array of $replaces)
function replace(&$array, $replaces) {
foreach ($array as $k => $v) {
$new_k = replace_word($k, $replaces);
if (is_array($v)) {
replace($v, $replaces);
}
else {
$v = replace_word($v, $replaces);
}
$array[$new_k] = $v;
if ($new_k != $k) {
unset($array[$k]);
}
}
}
function replace_word($word, $replaces) {
if (array_key_exists($word, $replaces)) {
$word = str_replace($word, $replaces[$word], $word);
}
return $word;
}
/* TEST FUNCTIONS */
$json = '[{"category":"Consumer","price":"18.9","number":"5"},{"category":"Industrial","price":"13.4","number":"4"},{"category":"Technology","price":"15.5","number":"3"}]';
$replaces = array("category" => "cat", "Consumer" => "cons");
$json_data = json_decode($json, true);
var_dump($json_data);
replace($json_data, $replaces);
var_dump($json_data);
$json = json_encode($json_data);
preg_replace can take pattern and replacement as arrays.
http://php.net/manual/en/function.preg-replace.php
So, for example:
preg_replace(array('Consumer', 'Industrial', 'Technology'), array('CON', 'IND', 'TCH'), $json);
Note, however, that unless you're absolutely sure of the JSON you'll be getting it is probably better practice to parse the JSON and replace within the actual key/values.

Add element to array then encode it to json

I have this code
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
//print_r($arr);
}
echo json_encode($arr);
what I am trying to do is to add something => false to each record of the array
so lets say I got from the database
array of
title:"aaaaa",
start: "xxxx",
end: "cccc",
I want to add to each one something :false to become like
title:"aaaaa",
start: "xxxx",
end: "cccc",
something,false
for each record
but the problem is when I print using the print_r its fine, but the json_encode print only the last one.
Passing by value vs. by reference
You are passing your $arr by value in your foreach loop. Try to pass it by reference.
This is done by adding a & just before your $arr variable in your loop declaration:
foreach ($data['events'] as &$arr) {
settype($arr,"array");
$arr['something'] = false;
}
echo json_encode($data['events']);
How it works
Passing by value means that your foreach loop instanciates a local copy or your array. All modifications made inside the loop will affect only the local copy.
Passing by reference means that inside your loop, you are working directly on the original array. But be careful when doing that because it can be dangerous. For instance, I don't know what are the consequences of calling setType($arr,"array"); for the rest of your code.
You're not collecting $arr from each iteration of your loop into anything. It looks like you probably want to push $arr onto another array that stores everything, and then JSON encode that new array.
Try this:
$collection = array();
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
array_push($collection, $arr);
}
echo json_encode($collection);
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as &$arr) {
settype($arr,"array");//This if there is not array
$arr['something'] = false;
}
echo json_encode($data['events']);
Try to make your own json like this
$strJson = '';
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
//Assign value as yours in blow code
$strJson .= '{"title" : "'.$arr.'","start" : "'.$arr.'","end" : "'.$arr.'"},';
}
$strJson1=rtrim($strJson, ",");
$newStr = '['.$strJson1.']';
echo $newStr;

Get values from Multidimensional nested array in PHP

Hi I am trying to get fulltext values from this json file on this Link
I am getting only top of the array how can I get all values from all arrays even the nested ones
$json_output = json_decode($json, true);
var_dump($json_output);
foreach($json_output['results'] as $item) {
echo '<br/>'. $item['fulltext'];
}
Id try looking at spl in PHP, it gives you useful iterator classes including ones specially for complex arrays - http://php.net/manual/en/class.recursivearrayiterator.php
another approach would be to
1) convert your json to xml (json -> php array -> xml) - you can use this recursive function:
function to_xml(SimpleXMLElement $object, array $data)
{
foreach ($data as $key => $value)
{
if (is_array($value))
{
$new_object = $object->addChild($key);
to_xml($new_object, $value);
}
else
{
$object->addChild($key, $value);
}
}
}
$xml = new SimpleXMLElement('<rootTag/>');
to_xml($xml, $my_array);
2) query the xml with XPath to fetch the collection of data you need, for example
$titles = $xml->xpath('//#fulltext');
Utilising XPath you can easily fetch data also by complex constraints, check out the docs
Found a solution
foreach($json_output['results'] AS $result) {
foreach($result['printouts']['Covers topic'] AS $topic) {
echo "<ul><li>".$topic['fulltext']."</li></ul>";
}
echo "<br/>".$result['fulltext'];
}
Thanks for your help guys

Delete from json using php

my Current json code :
{"Results":[{"username":"test","password":"test"},{"username":"test","password":"test"},{"username":"google","password":"test"},{"username":"yahoo","password":"test"},{"username":"hotmail","password":"test"}]}
i want to remove this :
{"username":"google","password":"test"}
from the code using php.
i tried deleting by decoding json to array but cant get it done.
any solution ?
$json_obj = json_decode($json_string);
$unset_queue = array();
foreach ( $json_obj->Results as $i => $item )
{
if ($item->username == "google")
{
$unset_queue[] = $i;
}
}
foreach ( $unset_queue as $index )
{
unset($json_obj->Results[$index]);
}
// rebase the array
$json_obj->Results = array_values($json_obj->Results);
$new_json_string = json_encode($json_obj);
<?php
$JSON = '{"Results":['
. '{"username":"test","password":"test"},'
. '{"username":"test","password":"test"},'
. '{"username":"google","password":"test"},'
. '{"username":"yahoo","password":"test"},'
. '{"username":"hotmail","password":"test"}'
. ']}';
// use json_decode to parse the JSON data in to a PHP object
$jsonInPHP = json_decode($JSON);
// now iterate over the results and remove the one that's google
$results = count($jsonInPHP->Results);
for ($r = 0; $r < $results; $r++){
// look for the entry we are trying to find
if ($jsonInPHP->Results[$r]->username == 'google'
&& $jsonInPHP->Results[$r]->password == 'test'){
// remove the match
unset($jsonInPHP->Results[$r]);
// now we can either break out of the loop (only remove first match)
// or you can use subtract one from $r ($r--;) and keep going and
// find all possible matches--your decision.
break;
}
}
// now that we removed items the keys will be off. let's re-order the keys
// so they're back in-line
$jsonInPHP->Results = array_values($jsonInPHP->Results);
// dump the new JSON data, less google's entry
echo json_encode($jsonInPHP);
Would be how I approach it. I like to avoid foreach(...){} statements when I need to modify the array itself. The above code, by the way, leaves you with:
{
"Results":[
{"username":"test","password":"test"},
{"username":"test","password":"test"},
{"username":"yahoo","password":"test"},
{"username":"hotmail","password":"test"}
]
}
$json = '
{
"Results":[
{"username":"test","password":"test"},
{"username":"test","password":"test"},
{"username":"google","password":"test"},
{"username":"yahoo","password":"test"},
{"username":"hotmail","password":"test"}
]
}';
$arr = json_decode($json, true);
array_filter($arr, function($v) {
return !($v['username'] == 'google' && $v['password'] == 'test');
});
$json = json_encode($arr);
$input='{"Results":[{"username":"test","password":"test"},{"username":"test","password":"test"},{"username":"google","password":"test"},{"username":"yahoo","password":"test"},{"username":"hotmail","password":"test"}]}';
$json = json_decode($input,true);
$match = array('username'=>'google', 'password'=>'test');
unset($json['Results'][array_search($match,$json['Results'])]);
To do it without a foreach but assuming you know the exact values you want to remove
Old question, formatting your JSON differently would help a lot.
Each result entry should have a unique key to identify it.
This makes it easy when needing to remove or update that result.
No reason to iterate over entire JSON this way.
Code would look like this
<?php
$jsonString = '{"Results":{'
.'{"username1":{"username":"google","password":"test1"}}'
.'{"username2":{"username":"yahoo","password":"test2"}}'
.'{"username3":{"username":"msonline","password":"test3"}}'
. '}}';
$jsonInPHP = json_decode($jsonString);
$password = $jsonInPHP["username1"]["pasword"];//Returns test1
$username = $jsonInPHP["username1"]["username"];//Returns google
?>
$myArray=json_decode($theJSONstring);
unset($myArray['Results'][2]);

Categories