Not sure what issue was with first pastebin code, here is another attempt. I am connecting to Vimeo Live API, in doing so the response is huge > 500kb in total – I have an example with only one object here -> there are over 20 it returns. I have a better idea of what Im doing in JS than PHP, but returning the huge array or json to the browser doesn’t seem like a good idea and its use of repeated ajax calls isn’t good either. So this question is two fold, both in theory and practice. Is this a good design and how do I filter the result in PHP and only send what I need back to browser.
Here is the design, or at least what I think is best:
- page loads, sends ajax request to PHP script
- PHP script connects to API and gets response in an array (example of one object)
- Search through the array for ‘metadata->connections->live_video’ for one that has an associated array containing [status] => streaming’
- If one (there will only be one at a time) is found, return that whole object and that object only, not the entire array.
At this time I do not have a complete understanding of how this data should be returned or formatted for ease of sifting through. Ive tried using json_encode on the array, which gets nicely formatted JSON but I can’t iterate through it and can only get single objects like data[0]->metadata->connections->live_video. Ive tried json_encode, then json_decode and Im back to a similar array structure of what is originally sent.
However, in the browser I am able to return the whole array and in the success function of the ajax call sift through it via JS like so:
let live_stream = json.data.filter(function(value, key) { let connection = value.metadata.connections['live_video']; return connection && connection.status === 'streaming'; });
I know this isn’t the right way, I know I need to sift through the array, find the object / key Im looking for and only return that. Any advice is appreciated, once I get this figured out, I can apply it in a range of ways for this project.
The closest I can get in PHP is:
function live_event() { global xxx; $lib = xxx; $response = xxx; $body = $response['body']; header('Content-Type: application/json'); $jsonstr = json_encode($body); $json = json_decode($jsonstr); foreach ($json->data as $item) { if ($item->uri == "/live_events/2354796") { echo"one"; } } }
and this:
function live_event() { $global xxx; $lib = xxx; $response = xxx; $body = $response['body']; header('Content-Type: application/json'); $jsonstr = json_encode($body); $json = json_decode($jsonstr,true); $results = array_filter($json['data'], function($item) { return $item['metadata']['connections']['live_video']['status'] == "streaming"; }); var_dump($results); }
last one gets me this error “Warning: Trying to access array offset on value of type null in /var/www/vhosts/mysite.com/httpdocs/SSI/Vimeo.php on line 31
” is there something similar to optional chaining in PHP? if its null I don’t want it to log an error.
This at least output “one” as there is only one object with [uri]=>”/live_events/2354796″. I can’t get it to return that entire object or search one more nested array deeper.
Advertisement
Answer
There are a few things that come to mind.
OBJECTS:
If you’re using PHP 8 you could use the safe access operator
function live_event() { //... $results = [] foreach ($json->data as $item) { if($item?->metadata?->connections?->live_video?->status == 'streaming'){ $results[] = $item; } } return $results; }
ARRAYS:
For lower versions of PHP it’s better to work with arrays when dealing with keys that may or may not exists.
Generally speaking whatever fetch library you’re working with will allow you set the output to either array
or object
. If Object is your only option then yes doing the old json_decode(json_encode($data), true)
is the way to go.
checking first isset(). Assuming that’s it’s desired to filter out results without that key.
function live_event() { //... $results = array_filter($json['data'], function($item) { if(!isset($item['metadata']['connections']['live_video']['status'])) return false; return $item['metadata']['connections']['live_video']['status'] == "streaming"; }); header('Content-Type: application/json'); echo json_encode([ "status" => true, "data" => $results ]); }
or you can always just use the age old trick of suppressing the error with the @ symbol. TBH i’m not sure where the @ symbol would go to suppress the error, perhaps in front of the filter function definition.
function live_event() { //... $results = array_filter($json['data'], function($item) { return @$item['metadata']['connections']['live_video']['status'] == "streaming"; }); return $results; }