I have the following JSON array, in this case it has only three entries, but there could also be more.
[
{
"id": 45,
"text": "apple"
},
{
"id": 37,
"text": "pear"
},
{
"id": 22,
"text": "strawberry"
}
]
Now my question is: How do I get the text variable of the entry with (for example) id being 37 in PHP? Is it possible to get that easily?
What I know: I could use a for loop for finding the text like this (in PHP):
<?php
$fruits = json_decode(file_get_contents("file.json"), true); // First I decode the file
for ($i = 0; $i < count($fruits); $i++) {
// Using this for loop and if condition, I get the text I need
if ($fruits[$i]['id'] == 37) echo $fruits[$i]['text'];
}
?>
But I don't want to use a for loop, as my JSON array has more than 3 entries, and if i request a lot of data in short time it takes long time till the for loop goes through every entry. So is there a more effective way to get to the same result? Can somebody explain me this in PHP?
The solution with array_filter():
$yourEntry = current(array_filter($jsonArray, function(\stdClass $entry) {
return ($entry->id == 37);
}));
See the example
if you can change your json structure then it is possible.
If you create json like this
{
"45":{
"text": "apple"
},
"37":{
"text": "pear"
},
"22":{
"text": "strawberry"
}
}
and in php
echo $item['37']['text'];
This will help :)
You could do it simply with this:
foreach($fruits as $item) {
if($item['id'] == 37) { echo $item['text']; break; }
}
Example
Change this code:
<?php
$fruits = json_decode(file_get_contents("file.json"), true); // First I decode the file
for ($i = 0; $i < count($fruits); $i++) {
// Using this for loop and if condition, I get the text I need
if ($fruits[$i]['id'] == 37) echo $fruits[$i]['text'];
}
?>
to
<?php
$fruits = json_decode(file_get_contents("file.json"), true); // First I decode the file
foreach ($fruits as $fruit) {
// Using this for loop and if condition, I get the text I need
if ($fruits['id'] == 37) {
echo $fruits['text'];
//rest of your code you like to add
}
}
?>
if you intend to use for loop only then use below code:
<?php
$fruits = json_decode(file_get_contents("file.json"), true); // First I decode the file
for ($i = 0; $i < count($fruits); $i++) {
// Using this for loop and if condition, I get the text I need
if ($fruits['id'] == 37) {
echo $fruits['text'];
//rest of your code you like to add
}
}
?>
Are you in control of the json data structure? If so, you could change to access via array key, e.g.
{
'37': 'pear',
'45': 'apple',
'22': 'strawberry'
}
$fruits = json_decode(file_get_contents("file.json"), true);
echo $fruits['37']; // pear
Related
I know this question has been asked, but i'm at my wit's end and cannot figure this out.
I have a json file that looks like this:
{
"objects": [
{
"url": "http://whatever",
"name": "whatever"
},
{
"url": "http://anything",
"name": "anything"
}
] }
In my PHP file, I have this:
// Read JSON file
$json = require('blogtest.json');
//Decode JSON
$arr = json_decode($json,true);
// Loop through Object
if (is_array($arr) || is_object($arr))
{
foreach ($ar as $arr)
{
echo $ar["objects"]["name"] + "<br>";
}
}
and instead of printing the name values - it prints the entire json file. I've tried changing the filters, writing it different ways, and I just cannot get json to ever do what I need.
Is there any possible way to just get this to print out the two "name" values?!
Replace require with file_get_contents.
What require does is to include the file, not to return the contents of the file.
Then you can loop the items with
foreach($ar["objects"] as $item) {
// $item['name'];
}
Your foreach loop is wrong.
The foreach block should be written as:
foreach ($arr['objects'] as $ar) {
echo $ar["name"] . '<br />';
}
Also, use file_get_contents instead of require.
How do I get access to the "thumburl" if I do not know the "pageid"?
{
"continue": {
"iistart": "2004-12-19T12:37:26Z",
"continue": "||"
},
"query": {
"pages": {
"30260": {
"pageid": 30260,
"ns": 6,
"title": "File:Japanese diet inside.jpg",
"imagerepository": "local",
"imageinfo": [
{
"thumburl": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/Japanese_diet_inside.jpg/130px-Japanese_diet_inside.jpg",
"thumbwidth": 130,
"thumbheight": 95,
"url": "https://upload.wikimedia.org/wikipedia/commons/e/e1/Japanese_diet_inside.jpg",
"descriptionurl": "https://commons.wikimedia.org/wiki/File:Japanese_diet_inside.jpg",
"descriptionshorturl": "https://commons.wikimedia.org/w/index.php?curid=30260"
}
]
}
}
}
}
With multiple objects in php I can do this imageinfo[0] but If I put $imageurl = $data->query->pages[0]->imageinfo[0]->thumburl; It is not working because it is an object not an array.
How can I do that?
You can call get_object_vars to get an associative array of the object properties, then get the first of these.
$props = array_values(get_object_vars($data->query->pages));
$imageurl = $props[0]->imageinfo[0]->thumburl;
You could use reset() to get the first element :
$data = json_decode($json) ;
$elem = reset($data->query->pages) ;
$imageurl = $elem->imageinfo[0]->thumburl ;
Another alternative is to decode as an array and re-index so it always starts at 0:
$result = array_values(json_decode($json, true)['query']['pages'])[0];
Then you can access $result['imageinfo']['thumburl'] or append it to the above.
You can loop through it, so you don't need array key like this:
$pages = (array) $data->query->pages;
foreach($pages as $page) {
$imageinfo = $page->imageinfo[0]->thumburl;
}
But this will get you only last from list of pages. So in case you know there are more pages, you need to store these thumburl in array. Or in case you are sure you want only first, just exit after first loop.
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 :'';
I have 2 arrays translations(2-dimensional),and line(1-dimensional). translations holds arrays, when ever the index for line and translation[][i] matches i want to print that line bold.otherwise print next line as it is. i have tried it with this code.
$translations[0]=array("Volvo", "BMW", "Toyota");
$translations[1]=array("ferrari", "mustang", "bently");
$lines=array("mustang","BMW");
for($i=0;$i<count($translations);$i++){
for($j=0;$j<count($translations[$i]);$j++){
foreach ($lines as $key =>$line){
if($d==$translation[$i][$j]) {
echo "<b>" .$translation[$i][$j] . "</b><br>" ;
}
else{
echo $translation[$i][$j]."<br>";
}
}
}
}
the problem here is that it prints translation subarrays element 3 times. i know the problem is in the way i am iterating the arrays, how should i fix this problem? help will be appreciated.
Try this, Hope this will help you out. Instead of looping over $lines array, you can just check with in_array that whether an element is present or not.
Try this code snippet here
<?php
ini_set('display_errors', 1);
$translations[0] = array("Volvo", "BMW", "Toyota");
$translations[1] = array("ferrari", "mustang", "bently");
$lines = array("mustang", "BMW");
for ($i = 0; $i < count($translations); $i++)
{
for ($j = 0; $j < count($translations[$i]); $j++)
{
if (in_array($translations[$i][$j], $lines))
{
echo "<b>".$translations[$i][$j] ."</b>". PHP_EOL;
}
else
{
echo $translations[$i][$j] .PHP_EOL;
}
}
}
I am using PHP 5.5.12.
I have the following multidimensional array:
[
{
"id": 1,
"type":"elephant",
"title":"Title of elephant"
},
{
"id": 2,
"type":"tiger",
"title":"Title of tiger"
},
{
"id": 3,
"type":"lion",
"title":"Title of lion",
"children":[{
"id": 4,
"type":"cow",
"title":"Title of cow"
},
{
"type":"elephant",
"title":"Title of elephant"
},
{
"type":"buffalo",
"title":"Title of buffalo"
}]
}
]
I am iterating this array using foreach loop.
The array key type must be in elephant, tiger and lion. If not, then the result should return false.
How can I achieve this?
So you want to check if your $myArray contains a value or not:
// first get all types as an array
$type = array_column($myArray, "type");
// specify allowed types values
$allowed_types = ["lion", "elephant", "tiger"];
$count = count($type);
$illegal = false;
// for loop is better
for($i = 0; $i < $count; $i++)
{
// if current type value is not an element of allowed types
// array, then both set the $illegal flag as true and break the
// loop
if(!in_array($type[$i], $allowed_types)
$illegal = true;
break;
}
Since you're using PHP5.5.12, you can make use of array_column.
$arr = json_decode($json, true);
//Walk through each element, only paying attention to type
array_walk( array_column($arr, 'type'), function($element, $k) use(&$arr) {
$arr[$k]['valid_type'] = in_array($element, array('lion', 'tiger', 'elephant'));
});
From here, each element in the array ($arr) will have a new key valid_type with a boolean value - 1 if the type is valid, 0 if it isn't.
https://eval.in/350322
Is this something that you are looking for?
foreach($your_array as $item) {
if (!array_key_exists('type', $item)) {
return FALSE;
}
}
function keyExists($arr, $key) {
$flag = true;
foreach($arr as $v) {
if(!isset($v[$key])) {
$flag = false;
break;
}
}
return $flag;
}
Hope this helps :)