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.
Related
I am saving data in JSON file for retrieving after redirect. If I check if the value matches in the json array, I always get false and something must be wrong, but I cannot figure it out. How can I the object with the specific SSL_SESSION_ID
Here's my json
[
{
"SSL_CLIENT_S_DN_CN": "John,Doe,12345678912",
"SSL_CLIENT_S_DN_G": "JOHN",
"SSL_CLIENT_S_DN_S": "DOE",
"SSL_CLIENT_VERIFY": "SUCCESS",
"SSL_SESSION_ID": "365cb4834f9d7b3d53a3c8b2eba55a49d5cac0112994fff95c690b9079d810af"
},
{
"SSL_CLIENT_S_DN_CN": "John,Doe,12345678912",
"SSL_CLIENT_S_DN_G": "JOHN",
"SSL_CLIENT_S_DN_S": "DOE",
"SSL_CLIENT_VERIFY": "SUCCESS",
"SSL_SESSION_ID": "e7bd2b6cd3db89e2d6fad5e810652f2ae087965e64b565ec8933b1a67120b0ac"
}
]
Here's my PHP script, which always returns It doesn't match
$sslData = Storage::disk('private')->get('ssl_login.json');
$decodedData = json_decode($sslData, true);
foreach ($decodedData as $key => $items) {
if ($items['SSL_SESSION_ID'] === $SSL_SESSION_ID) {
dd("It matches");
} else {
dd("It doesn't match");
}
}
Your script will always end after the first iteration, since you're using dd() regardless if it was a match or not and you will always get the "no-match"-message if the first iteration isn't a match.
You should iterate through all the items and then see if there was a match or not:
$match = null;
foreach ($decodedData as $key => $items) {
if ($items['SSL_SESSION_ID'] === $SSL_SESSION_ID) {
$match = $items;
// We found a match so let's break the loop
break;
}
}
if (!$match) {
dd('No match found');
}
dd('Match found');
That will also save the matching item in the $match variable if you need to use the data somehow.
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.
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 :'';
public function onRun(int $currentTick){
foreach (glob($this->plugin->getDataFolder()."/players/*.json") as $plData) {
$str = file_get_contents($plData);
$json = json_decode($str, true);
$levels = $json["level"];
}
}
I want to get top 5 higher values from all json files in "players" folder, I only know how to get that value from all files, but don't know how to select 5 higher. Can someone help please?
EDIT: Json file looks like this:
{
"coins": 0,
"rank": "Guest",
"accept_friends": true,
"reward_time": 1440,
"level": "29",
"bio": "Today is very cool!c",
"progress": 24.939999999999998,
"local_ip": "10.0.0.1",
"registred": true,
"logged": true
}
Use usort!
Make a function that will handle your sorting:
function levelSort($a, $b)
{
return $a['level']>$b['level'];
}
next store your players to array, sort it and return first five elements:
public function onRun(int $currentTick){
$players = []; // declare aray with proper scope
foreach (glob($this->plugin->getDataFolder()."/players/*.json") as $plData) {
$str = file_get_contents($plData);
$json = json_decode($str, true);
$players[] = $json; // save to array
}
usort($players, 'levelSort'); // sort using custom function
return array_slice($players, 0, 5); // return 5 elements
}
Should work. didn't tested tho :D
Of course this example assuming that every $json is an array and $json['level'] exists and is int
You need to build an array of levels with $levels[] as you are overwriting $levels each time. Then just reverse sort and slice the top 5:
public function onRun(int $currentTick){
foreach (glob($this->plugin->getDataFolder()."/players/*.json") as $plData) {
$str = file_get_contents($plData);
$json = json_decode($str, true);
$levels[] = $json["level"];
}
rsort($levels);
return array_slice($levels, 0, 5);
}
If you want to return the entire top 5 arrays:
public function onRun(int $currentTick){
foreach (glob($this->plugin->getDataFolder()."/players/*.json") as $plData) {
$str = file_get_contents($plData);
$results[] = json_decode($str, true);
}
array_multisort(array_column($results, 'level'), SORT_DESC, $results);
return array_slice($results, 0, 5);
}
Why are you passing in an argument $currentTick and not using it? Maybe replace 5 with $currentTick so you can pass it in?
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