Probleam using classes , array , json and php - php

Hi, this is my first time trying to create some code in PHP and it took me a long time but I'm able to convert data to xml. Now I need create a JSON object and it's not going well. The biggest problem is trying to create a new class in PHP (I don't know if what I did is ok or not) and if this is the correct way to attach a list. I think some of it's good but to me since I only use java and c# it seems a little crazy. I think I'm doing something wrong. The line that's showing me an error is $array['data']->attach( new Cake($name,$ingredients,$prepare,$image)); but i don't know what I'm doing wrong.
I haven't yet written the line that includes and transforms the array into json
Thanks
//opens the file, if it doesn't exist, it creates
$pointer = fopen($file, "w");
// writes into json
$cake_list['data'] = new SplObjectStorage();
for ($i = 0; $i < $row; $i++) {
// Takes the SQL data
$name = mysql_result($sql, $i, "B.nome");
$ingredients = mysql_result($sql, $i, "B.ingredientes");
$prepare = mysql_result($sql, $i, "B.preparo");
$image = mysql_result($sql, $i, "B.imagem");
// assembles the xml tags
// $content = "{";
// $content .= "}";
$array['data']->attach( new Cake($name,$ingredients,$prepare,$image));
// $content .= ",";
// Writes in file
// echo $content;
$content = json_encode($content);
fwrite($pointer, $content);
// echo $content;
} // close FOR
echo cake_list;
// close the file
fclose($pointer);
// message
// echo "The file <b> ".$file."</b> was created successfully !";
// closes IF($row)
class Cake {
var $name;
var $ingredients;
var $prepare;
var $image;
public function __construct($name, $ingredients, $prepare, $image)
{
$this->name = $name;
$this->ingredients = $ingredients;
$this->prepare = $prepare;
$this->image = $image;
}
}
function create_instance($class, $arg1, $arg2, $arg3, $arg4)
{
$reflection_class = new ReflectionClass($class);
return $reflection_class->newInstanceArgs($arg1, $arg2,$arg3, $arg4);
}

The error you are experiencing is because you are doing $array['data'] when you mean $cake_list['data'] so change the error line to:
$cake_list['data']->attach(new Cake($name, $ingredients, $prepare, $image));
Also a simple way to simple way to create a JSON object (or more accurately a string representation of a JSON object) is to do this:
$array = array(
'name' => $name,
'ingredients' => $ingredients,
'prepare' => $prepare,
'image' => $image
);
$json = json_encode($array);
You can also create simple easy to use objects like this:
$myObject = new stdClass(); // stdClass() is generic class in PHP
$myObject->name = $name;
$myObject->ingredients = $ingredients;
$myObject->prepare = $prepare;
$myObject->image = $image;

Related

Dynamically compose the name of function to call on php

I have csv like this.
id,startScore,endScore,total
1,12,34,46
2,10,20,30
.
.
Now I have Entity with the same column name.
So,it has the functions like these below.
setStartScore()
setEndScore()
setTotal()
For now my php code is like this below
$lines = explode('\n',$csvFile); // get CSV Content
$header = array_shift($lines); // get header
$headers = explode(",",$header)
foreach($lines as $line){ // each csv line
$table = new Table();
foreach(explodes(',',$line) as $l){
$i = 0;
foreach($headers as $h){
$table->set{$headers[$i]}($l[$i]) //how can I make dynamically make set***() function.
$i++;
}
I guess if I get doctrine setter/getter naming regulation, it works well though....
You can use a constructor to set the data.
Class Table
// ..
public function __construct($id, $startScore, $endScore, $total){
$this->id = $id;
$this->startScore = $startScore;
$this->endScore = $endScore;
$this->total = $total;
}
Then you can create the objects like:
foreach($lines as $line){ // each csv line
$data = explodes(',',$line);
$table = new Table($data[0], $data[1], $data[2], $data[3]);
$em->persist($table);
}
// ..flush

Connecting to Lastfm Api, can get all information except from the artist image

so I am connecting to the last fm API which the info looks like this
{"topartists":{"artist":[{"name":"Bee Gees","mbid":"bf0f7e29-dfe1-416c-b5c6-f9ebc19ea810","url":"https://www.last.fm/music/Bee+Gees","streamable":"0","image":[{"#text":"https://lastfm-img2.akamaized.net/i/u/34s/1df682d5ba6e45db843c45a336170470.png","size":"small"},{"#text":"https://lastfm-img2.akamaized.net/i/u/64s/1df682d5ba6e45db843c45a336170470.png","size":"medium"},{"#text":"https://lastfm-img2.akamaized.net/i/u/174s/1df682d5ba6e45db843c45a336170470.png","size":"large"},{"#text":"https://lastfm-img2.akamaized.net/i/u/300x300/1df682d5ba6e45db843c45a336170470.png","size":"extralarge"},{"#text":"https://lastfm-img2.akamaized.net/i/u/300x300/1df682d5ba6e45db843c45a336170470.png","size":"mega"}],"#attr":{"rank":"1"}}
In my php code i use
class LastFm{
private $api_key;
const url = 'http://ws.audioscrobbler.com/2.0/';
function __construct($api_key){
$this->api_key = $api_key;
}
function call($method,$params=array()){
$lastfm = self::url.'?method='.$method.'&format=json&api_key='.$this->api_key;
foreach($params as $key => $value){
$lastfm .= '&'.$key.'='.urlencode($value);
}
$json = file_get_contents($lastfm);
return json_decode($json, true);
}
}
?>
<?php
$lastfm = new LastFm('63692beaaf8ba794a541bca291234cd3');
$tracks = $lastfm->call('tag.gettopartists&tag=disco');
foreach($tracks['topartists']['artist'] as $track){
?>
Which successfully returns the artist name. But how do I get the medium sized image? I've tried -
`echo $artist['image'];`
but nothing gets returned.
echo '<img src="'.$track['image'][0]['#text'].'">'; is what you're looking for.
The 0 is the index within the $track['image'] array, you may want to change that based on the image size you want... Or, you can loop it and populate a new array of images
$images = [];
foreach($track['image'] as $image){
$images[] = [ $image['size']=>$image['#text'] ];
}
echo '<img src="'.$images['small'].'"/>;

Getting SOAP response in PHP even if value is not set

I don't work with PHP very often, at least not at this level, so I need some help. I have a SOAP response in PHP that turns into an Object:
stdClass Object
(
[Food_Document] => stdClass Object
(
[Food_Type] => Fruit
[Food_Serial] => 923490123
[Food_Name] => Apple
[Food_PictureName] => rotten_apple.jpg
[Food_PictureData] => sdlkff90sd9f90af9903r90wegf90asdtlj34kljtklsmdgkqwe4otksgk
)
)
What I need is the data from Food_PictureName and Food_PictureData, but it explodes with a warning every time I try to access it if it doesn't exist. Some objects will contain Food_PictureName and Food_PictureData, but not all of the time. Sometimes, only one or the other will exist, or neither. Basically, "0 or more times."
Here's the code I'm using:
function get_food_photo($serial)
{
$soap = new SoapClient("WSDL_LINK", array('trace' => true));
$params = new StdClass;
$params->serialNumber = $serial; // or whatever serial number you choose
$res = $soap->GetFoodDocuments($params);
$res = $res->GetFoodDocumentsResult;
$thumbnail_data = $res->FoodDocument[0]->Food_PictureData;
$ext = str_replace('.', '', $res->FoodDocument[0]->Food_PictureExtension);
return '<img src="data:image/'.$ext.';base64,'.$thumbnail_data.'"/>';
}
Now, accessing this data and displaying it DOES work if the Food_PictureData property is not null or empty, but otherwise, it will generate a warning every time: Fatal error: Cannot use object of type stdClass as array
I have tried the following: isset(), empty(), property_exists(), __isset(), strlen(), and some others.
How do I get this data without throwing an exception if it doesn't exist?
Rewrite the function as
function get_food_photo($serial)
{
$soap = new SoapClient("WSDL_LINK", array('trace' => true));
$params = new StdClass;
$params->serialNumber = $serial; // or whatever serial number you choose
$res = $soap->GetFoodDocuments($params);
$res = $res->GetFoodDocumentsResult;
if (is_array($res->FoodDocument)) {
$document = $res->FoodDocument[0];
} else {
$document = $res->FoodDocument;
}
if (property_exists($document, 'Food_PictureData')) {
$thumbnail_data = $document->Food_PictureData;
} else {
$thumbnail_data = '';
}
if (property_exists($document, 'Food_PictureExtension')) {
$ext = str_replace('.', '', $document->Food_PictureExtension);
} else {
$ext = '';
}
return '<img src="data:image/'.$ext.';base64,'.$thumbnail_data.'"/>';
}

Retrieve all values in my loop and format it to json

I'm trying to build a page which queries my database and then formats output so another webservice/page can access the data.
Ideally I wanted to explore having the data in JSON format, but that is not working. The other problem I have which is more major than the JSON not working is, if I have 3 records in $reportsResult, only the last one is displayed.
Anyone with some help please. Oh do I also need to print_r for the external webpage to retrieve the data or is there a better way?
class Pupil {
public $FirstName = "";
public $LastName = "";
}
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil = new Pupil();
$Pupil->FirstName = $reportRecord->getField('FName');
$Pupil->LastName = $reportRecord->getField('SName');
}
json_encode($Pupil);
OK managed to figure out how how to get all records from the loop, but its still not displaying in json format when I do a print_r - am I missing something?
$AllPupils = array();
foreach($reportsResult->getRecords() as $reportRecord)
{
$Pupil = new Pupil();
$Pupil->FamID = $reportRecord->getField('FName');
$Pupil->ChildName = $reportRecord->getField('SName');
array_push($AllPupils, $Pupil);
}
json_encode($AllPupils);
Everytime your foreach loop starts again, it will override your $Pupil variable.
Try an array instead:
$Pupil = array()
$i = 0;
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil[$i] = new Pupil();
$Pupil[$i]->FirstName = $reportRecord->getField('FName');
$Pupil[$i]->LastName = $reportRecord->getField('SName');
$i++;
}
echo json_encode($Pupil);
Edit: mikemackintosh's solution should also work and could be a little bit faster (depending on the size of your foreach loop).
To display the results you need to echo your data (not only json_encode).
You will probably run into issues since json_encode wont handle the whole object. for that, you may want to serialize the $Pupil object.
Something like below may work for you though. It will assign the values to a returned array, which will allow json_encode to execute gracefully:
class Pupil {
public $FirstName = "";
public $LastName = "";
public function getAttr(){
return array("FirstName" => $this->FirstName, "LastName" => $this->LastName);
}
}
$json = array();
foreach($reportsResult->getRecords() as $reportRecord) {
$Pupil = new Pupil();
$Pupil->FirstName = $reportRecord->getField('FName');
$Pupil->LastName = $reportRecord->getField('SName');
$json[] = $Pupil->getAttr();
}
echo json_encode($json);
I am not sure why you have that class defined, but you know what in your for each have something like
foreach ($reportsResult->getRecords() as $key => $record) {
$data[$key]['firstname'] = $record->getField('Fname');
$data[$key]['lastname'] = $record->getField('Sname');
}
And then you can check the final array using print_r
and while output you can simply do a print json_encode($data) and it will give you a json string of all the items in the data array.
In php (at least), json_encode takes an array as parameter.
Therefore you should add a constructor to your class
function __construct($first, $last)
{
this.$FirstName = $first;
this.$LastName = $last;
}
and one for getting the full name as an array, ready to be jsoned
function getNameArray()
{
$nameArray = array();
$nameArray['firstName'] = this.$FirstName;
$nameArray['lastName'] = this.$LastName;
return $nameArray;
}
then in that foreach you build another array with all the pupils
$pupils = array();
foreach (bla bla)
{
$first = $reportRecord->getField('FName');
$last = $reportRecord->getField('SName');
$Pupil = new Pupil($first, $last);
array_push($pupils, $pupil.getNameArray());
}
finally, you have everything preped up
json_encode($pupils);
I'm sure there's other ways to debug your stuff, I use print_r mainly also.

How to print the array that contains the tags and the data in this xml parser?

<?php
class Simple_Parser
{
var $parser;
var $error_code;
var $error_string;
var $current_line;
var $current_column;
var $data = array();
var $datas = array();
function parse($data)
{
$this->parser = xml_parser_create('UTF-8');
xml_set_object($this->parser, $this);
xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1);
xml_set_element_handler($this->parser, 'tag_open', 'tag_close');
xml_set_character_data_handler($this->parser, 'cdata');
if (!xml_parse($this->parser, $data))
{
$this->data = array();
$this->dat1 = array();
$this->error_code = xml_get_error_code($this->parser);
$this->error_string = xml_error_string($this->error_code);
$this->current_line = xml_get_current_line_number($this->parser);
$this->current_column = xml_get_current_column_number($this->parser);
}
else
{
$this->data = $this->data['child'];
}
xml_parser_free($this->parser);
}
function tag_open($parser, $tag, $attribs)
{
$this->data['child'][$tag][] = array('data' => '', 'attribs' => $attribs, 'child' => array());
$this->datas[] =& $this->data;
$this->data =& $this->data['child'][$tag][count($this->data['child'][$tag])-1];
echo("");
}
function cdata($parser, $cdata)
{
$this->data['data'] .= $cdata;
echo "$cdata";
}
function tag_close($parser, $tag)
{
$this->data =& $this->datas[count($this->datas)-1];
//echo "$this->datas[]";
array_pop($this->datas);
}
foreach ($this->data as $i1 => $n1)
foreach ($n1 as $i2 => $n2)
foreach ($n2 as $i3 => $n3)
printf('$data[%d][%d][%d] = %d;<br>', $i1,$i2,$i3,$n3);?>
}
$file = "BLR_HOSP-1.kml";
if (!($fp = fopen($file, "r"))) {
die("could not open XML input");
}
$data = fread($fp, filesize($file));
fclose($fp);
$xml_parser = new Simple_Parser;
$xml_parser->parse($data);
?>
The foreach loop didn't work . So how do give an output of the xml file I parsed and that I have stored as an array . I want to print the tags and also the data in the tag .
Looking at the code, there looks to be a few syntactical errors. Correct the following errors first, and then let us know if the problem persists:
The line printf('$data[%d][%d][%d] = %d;<br>', $i1,$i2,$i3,$n3);?> has a closing PHP tag at the end. (see the ?>.)
I'm not sure that the 'foreach' loop is correct where you've placed it. I reviewed the braces ( {, }) a few times to make sure I'm right. It looks like the foreach function is not contained inside a function. It looks like it's still inside the class though, which is even worse..
My suggestion is to place the 'foreach' statement, after removing the ?> characters, after the '$xml_parser->parse($data);' command. (Make sure to edit it so the $this is replaced with $xml_parser.)
I haven't reviewed the rest of your code for errors--I may edit/update this answer if what I've suggested doesn't currently fix your problem, or at least help you figure out what else is wrong. :)

Categories