PHP foreach array IDs - php

I have a foreach loop that is supposed to loop through JSON and return the appropriate ID of each video listed in JSON using the Youtube api.
Here is my code:
class Videos {
private $mVideoUrl;
function setVideoTitle($videoUrl){
$this->mVideoUrl= $videoUrl;
}
function getVideoTitle(){
return $this->mVideoUrl;
}
}
$jsonFile = file_get_contents($url);
$jfo = json_decode($jsonFile);
$items = $jfo->items;
$vidArray = array();
foreach ($items as $item){
if(!empty($item->id->videoId)){
$Videos = new Videos;
$Videos->setVideoUrl($item->id->videoId);
$id = $Videos->getVideoUrl();
array_push($vidArray, $id);
}
echo $vidArray[0];
}
Problem is, the array push is working correctly, but it is only adding the 1st ID in the list only for each loop iteration when i echo it. When I echo the $id variable, it prints all IDs just fine.
Ultimately i want to be able to create an object for each video, storing it's ID and other information.
I feel like this is a simple fix but i can't figure it out for the life of me.
I would appreciate any help!
Also if i am going about this all wrong, advice is appreciated as well!
Thanks!

I've played little bit with your code. I've modified your class. I've renamed plurar Videos to Video (singular).
Then I've added an attribute $id, because name of properties should be simple and represent the data we want to store in them.
Then I've added getter and setter for the $id property.
I don't know the $url, so I've just write simple JSON string instead. I tried to mimic the structure that you're using in your code.
Then I've added () to the end of new Video() to have proper constructor called.
And instead of pushing elements into array, I'm using proper $array[$index] = assignment.
Last thing, I've moved writing out the data out of the foreach-cycle. And I'm using var_export to get proper php code to play with if redirected to another file.
<?php
class Video
{
private $mVideoUrl;
private $id; // added id attribute
/**
* #return mixed
*/
public function getId() // added getter
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id) // added setter
{
$this->id = $id;
}
function setVideoTitle($videoUrl)
{
$this->mVideoUrl = $videoUrl;
}
function getVideoTitle()
{
return $this->mVideoUrl;
}
}
// ignored for now
// $jsonFile = file_get_contents($url);
$jsonFile = '{"items": [
{ "id": { "videoId": 1, "url": "http://www.youtube.com/1" } },
{ "id": { "videoId": 2, "url": "http://www.youtube.com/2" } },
{ "id": { "videoId": 3, "url": "http://www.youtube.com/3" } },
{ "id": { "videoId": 4, "url": "http://www.youtube.com/4" } },
{ "id": { "videoId": 5, "url": "http://www.youtube.com/5" } }
]
}';
$jfo = json_decode($jsonFile);
$items = $jfo->items;
$vidArray = array();
foreach ($items as $item)
{
if (!empty($item->id->videoId))
{
$Video = new Video(); // added brackets
$Video->setId($item->id->videoId); // changed to setId
$Video->setVideoTitle($item->id->url);
$id = $Video->getId();
$vidArray[$id] = $Video;
}
}
// write out all data
var_export($vidArray);

In your code your class Videos contains two functions
setVideoTitle(...),
getVideoTitle()
but in your foreach you have called $videos->getVideoUrl() , $videos->setVideoUrl(...)
what is this ???

Related

How to show array in Json with Fractal?

I want to save REST API data with array to database, its work, all value save to the table, but i still get error when i want to view the result in json.
Here is my error
"message": "Argument 1 passed to App\\Transformers\\NewLoanOfferTransformer::transform() must be an instance of App\\Model\\AntiAttrition, array given, called in /home/insko23/testing.insko.my/vendor/league/fractal/src/Scope.php on line 338",
My Controller
public function new_loan_offer(Request $request, AntiAttrition $antiattrition)
{
$new = array_map(null, $request->mo_id, $request->id_clrt,$request->TaskID,$request->ACID,$request->CustIDNo);
foreach($new as $new) {
$request = new AntiAttrition;
$request->mo_id = $new[0];
$request->id_clrt = $new[1];
$request->TaskID = $new[2];
$request->ACID = $new[3];
$request->CustIDNo = $new[4];
$request->save();
}
$response = fractal()
->item($new)
->transformWith(new NewLoanOfferTransformer)
->toArray();
return response()->json($response,201);
}
My App\Transformer
<?php
namespace App\Transformers;
use App\Model\AntiAttrition;
use App\Model\SettlementInfo;
use League\Fractal\TransformerAbstract;
class NewLoanOfferTransformer extends TransformerAbstract
{
public function transform (AntiAttrition $antiattrition)
{
return[
'id' => $antiattrition->id,
'mo_id'=> $antiattrition->mo_id,
'assign_by'=> $antiattrition->assigned_by,
'id_clrt' => $antiattrition->id_clrt,
'TaskID'=> $antiattrition->TaskID,
'ACID'=> $antiattrition->ACID,
'CustIDNo'=> $antiattrition->CustIDNo
];
}
}
I want to show the result in json, like below
{
"data": [
{
"mo_id": "123",
"id_clrt": "10000000049",
"ACID": "123",
.....
},
{
"mo_id": "1234",
"id_clrt": "10000000045",
"ACID": "1235",
.....
},
{
"mo_id": "124",
"id_clrt": "10000000044",
"ACID": "1245",
.....
},
],
}
Please help me to solve this problem
In the foreach loop, avoid using same name for array and elements of the array you are iterating over, you can rename foreach($new as $new) to foreach($newArray as $new), or something meaningful with your code logic. Also rather than using $new[0] use $new['mo_id'] for referring to the key of the array

Use class and methods to get JSON data and echo out content

I'm trying to use OOP to create an effective class that loops through a JSON file and echo's out certain items. Inside of the class I need to use methods like "getName()" etc. The goal is to use a class as much as possible. Is there a better way of doing this?
$file= file_get_contents("swapi.json");
$data = json_decode($file);
$content = $data->results;
foreach($content as $item){
$name = $item->name;
$height = $item->height;
$person = new Character($name,$height);
echo $person->getName(),$person->getHeight();
}
class Character{
public $name;
public $height;
public static $number_of_char = 0;
function __construct($name,$height){
$this->name = $name;
$this->height = $height;
Character::$number_of_char++;
}
function getName(){
return "Character number ".Character::$number_of_char.":".'</br>'.
'<li>'."Namn: ".$this->name.'</li>';
}
function getHeight(){
return '<li>'."height: ".$this->height."cm".'</li>'.'</br>';
}
}
JSON
{
"count": 87,
"next": "https://swapi.co/api/people/?page=2",
"previous": null,
"results": [
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
This is as as compressed as I've managed to get it.
Echos out 10 different objects containing for example:
"Character number 1:"
- Name: Obi-Wan Kenobi
- height: 182cm
Is this good practice? Iv'e tried using loops inside the class to get the data but haven't been able to make it work. (The 'foreach($content..' is in a separate file)

PHP: Create JSON data for JS autocomplete from Database

I wish to prepare the JSON data and send to jquery autocomplete made by devbridge, it want the data be format as this scheme:
{
"suggestions": [
{ "value": "United Arab Emirates", "data": "AE" },
{ "value": "United Kingdom", "data": "UK" },
{ "value": "United States", "data": "US" }
]
}
So I'm trying to get the data from database and put in an array.
<?php
include '../core/config.php';
include '../core/db.class.php';
$DB->query("SELECT * FROM `prodotti`;");
$prodotti = $DB->fetchAll();
class json_prodotti {
public $suggestions = '';
}
class json_suggestions {
public $value = '';
public $data = '';
public $price = '';
}
$j = new json_prodotti;
$s = new json_suggestions;
$a = array();
foreach ($prodotti as $prd ) {
$s->value = $prd['name'];
$s->data = $prd['ID'];
$s->price = $prd['price'];
array_push($a,$s);
}
$j->suggestions = $a;
echo json_encode($j);
?>
As you can see I'm using a database class, this work as expected and I'm using it in other parts of project. Here is the function fetchAll() that is called to fetch the data, the __construct is working fine.
public function fetchAll(){
$this->execute();
return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
}
PROBLEM:
Something is wrong in my code, I got the JSON as expected, but the foreach cycle repeat the same database row as many rows I got in database.
EG:
{
"suggestions":[
{"value":"Item 4","data":"6","price":"0.48"},
{"value":"Item 4","data":"6","price":"0.48"},
{"value":"Item 4","data":"6","price":"0.48"},
{"value":"Item 4","data":"6","price":"0.48"}
]}
Just create a new suggestion each time:
$j = new json_prodotti;
$a = array();
foreach ($prodotti as $prd ) {
$s = new json_suggestions;
$s->value = $prd['name'];
$s->data = $prd['ID'];
$s->price = $prd['price'];
array_push($a,$s);
}
Otherwise you are modifying the same object... thats why in json_encode you get the same value for all suggestions... you are adding the same suggestion many times...

Get array data from JSON

My target is to make an array of Objets(Article), I manage to recuperate the pmid, doi and title but when it comes to the array location, I couldn't do it, this the code I have tried:
<?php
class Article
{
private $pmid;
private $doi;
private $title;
private $location=array();
public function setLocations($tabLocations){
foreach ($tabLocations as $key => $value) {
$location[]=$value;
}
}
public function setPmid($_pmid){
$this->pmid=$_pmid;
}
public function setDoi($_doi){
$this->doi=$_doi;
}
public function setTitle($_title){
$this->title=$_title;
}
//getters
public function getTitle(){
return $this->title;
}
}
//get pmid from DOM
require_once "simple_html_dom.php";
$html=new simple_html_dom();
$html->load_file('http://brainspell.org/search?query=psen+1');
$pmid=array();
foreach ($html->find('.paper-stuff') as $article) {
$pmid[]= str_replace("/article/","",$article->find('a',0)->getAttribute('href'));
}
//Create ALLArticles TAb
$articlesTab=array();
//upload data file
$json=file_get_contents("C:\wamp\www\projet1\json\allArticles.json");
$data=json_decode($json,true);
foreach ($pmid as $tabPmid) {
foreach ($data as $key=>$value) {
if($value["pmid"]==$tabPmid)
{
$details=new Article();
$details->setPmid($value["pmid"]);
$details->setDoi($value["doi"]);
$details->setTitle($value["title"]);
$details->setLocations($value['experiment']['location']);
$articlesTab[]=$details;
}
}
}
?>
This a portion of my JSON code:
{
"papers": {
"paper": [
{
"pmid": "6330179",
"doi": "10.1002/cne.902260203",
"experiment": [
{
"id": "12789",
"location": [
"-46.0,-80.0,2.0",
"-42.0,-76.0,-2.0",
"44.0,-72.0,-2.0",
"52.0,-68.0,-6.0",
"-32.0,-88.0,4.0",
"-32.0,-90.0,8.0",
"34.0,-82.0,8.0",
"34.0,-78.0,8.0",
"-30.0,-52.0,-12.0",
"-30.0,-52.0,-10.0",
"28.0,-66.0,-16.0",
"26.0,-66.0,-12.0",
"-46.0,-76.0,6.0",
"-46.0,-78.0,0.0",
"46.0,-70.0,4.0",
"48.0,-74.0,0.0"
]
}
]
},
{
"pmid": "10022492",
"doi": "10.1093/cercor/9.1.20",
"experiment": [
{
"id": "258",
"location": [
"-42.0,26.0,20.0",
"-36.0,30.0,16.0",
"-30.0,32.0,0.0",
"-28.0,14.0,48.0",
"-20.0,8.0,56.0",
"-32.0,4.0,52.0",
"50.0,10.0,36.0",
"48.0,24.0,20.0",
"32.0,0.0,56.0",
"8.0,-2.0,64.0",
"4.0,-8.0,68.0",
"-16.0,-4.0,12.0",
"-2.0,-18.0,12.0",
"-8.0,2.0,8.0",
"-44.0,-28.0,32.0",
"-4.0,-60.0,60.0",
"36.0,-58.0,52.0"
]
},
If there is anyone that could help me.Thanks in advance :D
If you notice location is another array so for you to get all its elements, it needs to be imploded. so try something like this .
$details->setLocations(implode(",",$value['experiment']['location']));
This will print the array as a string separated by comma ,; maybe you can choose what you want as the separator.
You simply missed $this to reference your object property in setLocations
public function setLocations($tabLocations){
foreach ($tabLocations as $key => $value) {
$this->location[]=$value; // $this->location is where you want to store your locations
}
}
and by the way, I don't see any need to iterate over $tabLocations in your setter. Wouldn't
public function setLocations($tabLocations){
$this->locations = $tabLocations;
}
do the trick too?
Or if you want to get rid of the keys:
public function setLocations($tabLocations){
$this->locations = array_values($tabLocations);
}

Threaded App.net Conversation Into Tree

I want to create a JSON tree from a flat structure - in this case an App.net Thread.
I want JSON like this
"id": "12345",
"name": "Ringo",
"data":
{
"avatar": "",
"text": "We All Live",
},
"children": [{
"id": "34567",
"name": "John",
"data":
{
"avatar": "",
"text": "In a pink submarine?",
},
"children": [{
"id": "35555",
"name": "George",
"data":
{
"avatar": "",
"text": "Don't be daft",
},
"children": []
}]
},{
"id": "98765",
"name": "Paul",
"data":
{
"avatar": "",
"text": "In a yellow submarine?",
},
"children": []
}]
So, each post can have multiple children. Each child can have children.
The JSON coming back from App.net is not threaded.
{
"id": "98765",
"parent": "12345"
"details": {
...}
},
{
"id": "34567",
"parent": "12345"
"details": {
...}
},
I've used json_decode() to get the JSON response in to an array. I can iterate through using foreach.
How do I put each post in the correct part of the multi dimensional array?
Parent
|_
|-child
|-child
| |-child
|-child
etc
I would use references, the oft forgotten hard link of PHP. Something like this:
I'm assuming you have a $posts array that you've gotten back from an App.net API call.
(untested, may not compile / run / may have errors / may be more efficient ways to do this)
// first throw everything into an associative array for easy access
$references = array();
foreach ($posts as $post) {
$id = $post['id'];
$post['children'] = array();
$references[$id] = $post;
}
// now create the tree
$tree = array();
foreach ($references as &$post) {
$id = $post['id'];
$parentId = $post['parent'];
// if it's a top level object, add it to the tree
if (!$parentId) {
$tree[] =& $references[$id];
}
// else add it to the parent
else {
$references[$parentId]['children'][] =& $post;
}
// avoid bad things by clearing the reference
unset($post);
}
// encode it
print json_encode($tree);
Just sketching out an answer here: all assuming you can hold all entries in RAM otherwise you will have to make some ordering assumptions and clear our your array when a full unit is done.
Create an array posts indexed by id holding structures with the details and an array of children.
Then iterate over your input array and for each element:
create posts[id] if it hasn't been created yet
fill in details for post[id]
if there is a parent, lookup (creating it if needed -- no idea how the ordering is) posts[parent_id] and add this structure to the children there.
At the end you can iterate over all posts and those without a parent are the roots with their children properly filled in.
I wrote a class and example script to accomplish what I think you wanted.
It converts a flat structure into a hierarchical one, and also accounts for orphan updates (ones without parent updates available).
Update.php
<?php
/**
* An App.net update.
*/
class Update extends ArrayObject
{
/**
* The update's children.
*
* #var array
*/
private $children = array();
/**
* The parent update.
*
* #var Update
*/
private $parent;
/**
* Adds a child to this update.
*
* #param Update The child update.
*/
public function addChild(self $child)
{
$child->setParent($this);
$this->children[] = $child;
}
/**
* Sets the parent update.
*
* #param Update The parent update.
*/
public function setParent(self $parent = null)
{
$this->parent = $parent;
}
/**
* Converts the update and its children to JSON.
*
* #param boolean $encode Automatically encode?
*
* #return string The JSON-encoded update.
*/
public function toJson($encode = true)
{
$data = $this->getArrayCopy();
if ($this->children) {
$data['children'] = array();
foreach ($this->children as $child) {
$data['children'][] = $child->toJSON(false);
}
}
if ($encode) {
return json_encode($data);
}
return $data;
}
}
build.php
<?php
require 'Update.php';
$updates = <<<UPDATES
[
{
"id": "12345",
"name": "Ringo",
"data": {
"avatar": "",
"text": "We All Live"
}
},
{
"id": "34567",
"parent": "12345",
"name": "John",
"data": {
"avatar": "",
"text": "In a pink submarine?"
}
},
{
"id": "98765",
"parent": "12345",
"name": "Paul",
"data": {
"avatar": "",
"text": "In a yellow submarine?"
}
}
]
UPDATES;
$original = json_decode($updates, true);
$parents = array();
$children = array();
foreach ($original as $update) {
if (empty($update['parent'])) {
$parents[$update['id']] = $parent = new Update($update);
if (isset($children[$update['id']])) {
foreach ($children[$update['id']] as $child) {
$parent->addChild($child);
}
unset($children[$update['id']]);
}
} else {
$child = new Update($update);
if (isset($parents[$update['parent']])) {
$parents[$update['parent']]->addChild($child);
} else {
if (false === isset($children[$update['parent']])) {
$children[$update['parent']] = array();
}
$children[$update['parent']][] = $child;
}
}
}
// Anything in children at this point are orphans
echo "Parents:\n";
foreach ($parents as $parent) {
echo $parent->toJson();
}
echo "\n\nOrphans:\n";
foreach ($children as $parent => $orphans) {
foreach ($orphans as $orphan) {
echo $orphan->toJson();
}
}

Categories