Getting SOAP response in PHP even if value is not set - php

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.'"/>';
}

Related

PHP-cURL Adding entry to an array in a function not working

I can echo the response i get just fine in the function request_callback so I thought it trivial to just save the response into an array associative_array[], however this yields just single entries, like the array gets wiped after every entry.
I make use of https://github.com/LionsAd/rolling-curl/blob/master/RollingCurl.php
<?php
# Get the all the items numbers
$url1 = "http://api.guildwars2.com/v2/commerce/listings";
$response1 = file_get_contents($url1);
$data1 = json_decode($response1, true);
#retrieve item names and link with numbers
function request_callback($response) {
$temporary_array = json_decode($response, true);
$associative_array[] = array('name' => $temporary_array['name'],'id' => $temporary_array['id']);
// array[] places the new entry at end of urls stack, faster then array_push($array, new entry);
print_r ($associative_array);
echo "\n";
}
# Multiple curl request
require("rollingcurl.php");
for ($x=0;$x<5;$x++){
$itemurl1 = "http://api.guildwars2.com/v2/items/{$data1[$x]}";
$urls[$x]= $itemurl1;
}
$rc = new RollingCurl("request_callback");
$rc->window_size = 20;
foreach ($urls as $url) {
$request = new RollingCurlRequest ( $url ) ;
$rc -> add ( $request ) ;
}
$rc->execute();
?>
Your array is local to your function, hence reseting on each call.
Try adding global declaration and you will get what you expect (all values);
function request_callback($response) {
global $associative_array;
$temporary_array = json_decode($response, true);
$associative_array[] = array('name' => $temporary_array['name'],'id' => $temporary_array['id']);
// array[] places the new entry at end of urls stack, faster then array_push($array, new entry);
print_r ($associative_array);
echo "\n";
}
I'd create your array outside of your function. It looks like you're creating a new array on every function call.
$associative_array = array();
function request_callback($response) {
global $associative_array;
$temporary_array = json_decode($response, true);
$associative_array[] = array('name' => $temporary_array['name'],'id' => $temporary_array['id']);
// array[] places the new entry at end of urls stack, faster then array_push($array, new entry);
print_r ($associative_array);
echo "\n";
}

What is wrong with my PHP and json

I am trying to get a response from my json array:
stdClass Object ( [Foo] => stdClass Object ( [id] => 0001 [name] => Foo [profileIconId] => 550 [summonerLevel] => 30 [revisionDate] => 1408463933000 ) )
using my current code, I know that it is really easy to solve - but I don't know what I am doing wrong as I can't find anything similar to this from what I am searching:
api.php:
<?php
class runeapi {
const get_id_na = 'https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/';
const get_id_euw = 'https://euw.api.pvp.net/api/lol/euw/v1.4/summoner/by-name/';
const key = '...';
public function getID($summoner_name) {
$name = $summoner_name;
$call = self::get_id_euw .$name;
return $this->request($call);
}
private function request($call) {
$url = $call. '?api_key=' .self::key;
$json = file_get_contents($url);
$decode = json_decode($json);
$result = $decode; //<-- This is the Issue.
return $result;
}
}
?>
testing.php:
<?php
include('api.php');
$summoner_name = 'Foo';
$test = new runeapi;
$r = $test->getID($summoner_name);
print_r($r);
?>
$r returns $result
I'd like to be able to call for id but no matter where I tried looking, I couldn't find an example similar to what I have.
What I've tried:
$decode->{'id'};
$decode{'id'};
I believe this will work for you
private function request($call) {
$url = $call. '?api_key=' .self::key;
$json = file_get_contents($url);
return $json;
}
No need to decode it.
I had to add another variable to request():
public function getID($summoner_name) {
$name = $summoner_name;
$call = self::get_id_euw .$name;
return $this->request($call, $name); //<-- added $name
}
private function request($call, $name) { //<-- added $name
$url = $call. '?api_key=' .self::key;
$json = file_get_contents($url);
$decode = json_decode($json);
$result = $decode->{$name}->{'id'}; //<-- added $name
return $result;
}

Foreach loop in function only returns last item in array

I am having trouble with my php code below. I am trying to have the function below to return the UPC and imageURL for each item. When I print_r the result after the loop I receive this.
Array
(
[upc] => 043396066731
[ImageURL] => http://ecx.images-amazon.com/images/I/51HKXNNT53L._SL200_.jpg
)
Array
(
[upc] => 096009394097
[ImageURL] => http://ecx.images-amazon.com/images/I/512NKNWC8EL._SL200_.jpg
)
However, when I use return result and then print_r I only receive the last response. Why is this and how can I fix my code to receive the values from both items? I have searched Google and other Stackoverflow questions and can find similar situations, but I am still struggling.
Array
(
[upc] => 096009394097
[ImageURL] => http://ecx.images-amazon.com/images/I/512NKNWC8EL._SL200_.jpg
)
Here is my function
function invokeGetMatchingProductForId(MarketplaceWebServiceProducts_Interface $service, $request)
{
// try {
$response = $service->getMatchingProductForId($request);
$dom = new DOMDocument();
$dom->loadXML($response->toXML());
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$parsed_xml = simplexml_import_dom($dom);
//print_r($parsed_xml);
$Result = array();
foreach($parsed_xml->GetMatchingProductForIdResult as $item )
{
$status = $item->attributes()->status;
if (stristr($status, "Success") == true)
{
$Result['upc'] = (string)$item->attributes()->Id;
$Result['ImageURL'] = str_replace('SL75','SL200',$item->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->SmallImage->URL);
} else {
$Result['upc'] = (string)$item->attributes()->Id;
$Result['ImageURL'] = "";
}
}
print_r($Result);
}
// return $Result;
// }
// $amazonResult =invokeGetMatchingProductForId($service, $request);
// print_r($amazonResult);
You need to assign second key for your array:
$Result['upc'][] = ;
$Result['ImageURL'][] = ;
^-----
Currently you are resetting this $Result['upc'] every time you assign new value.
according to your requirement you need to create two dimensional array
use foreach like this
foreach($parsed_xml->GetMatchingProductForIdResult as $item )
{
$status = $item->attributes()->status;
if (stristr($status, "Success") == true)
{
$Result[]['upc'] = (string)$item->attributes()->Id;
$Result[]['ImageURL'] = str_replace('SL75','SL200',$item->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->SmallImage->URL);
}
else
{
$Result[]['upc'] = (string)$item->attributes()->Id;
$Result[]['ImageURL'] = "";
}
}
print_r($Result);

Probleam using classes , array , json and 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;

Converting array into multidimensional array in PHP when result is send from Oracle

Here is example how my array should look like:
$library = array(
'book' => array(
array(
'authorFirst' => 'Mark',
'authorLast' => 'Twain',
'title' => 'The Innocents Abroad'
),
array(
'authorFirst' => 'Charles',
'authorLast' => 'Dickens',
'title' => 'Oliver Twist'
)
)
);
When I get results from oracle database:
$row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS);
But when I execute my code I only get one row.
For example: <books><book></book><name></name></books>
But I want all rows to be shown in xml.
EDIT:
This is my class for converting array to xml:
public static function toXml($data, $rootNodeName = 'data', &$xml=null)
{
// turn off compatibility mode as simple xml throws a wobbly if you don't.
if (ini_get('zend.ze1_compatibility_mode') == 1)
{
ini_set ('zend.ze1_compatibility_mode', 0);
}
if (is_null($xml))
{
$xml = simplexml_load_string("<".key($data)."/>");
}
// loop through the data passed in.
foreach($data as $key => $value)
{
// if numeric key, assume array of rootNodeName elements
if (is_numeric($key))
{
$key = $rootNodeName;
}
// delete any char not allowed in XML element names
$key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key);
// if there is another array found recrusively call this function
if (is_array($value))
{
// create a new node unless this is an array of elements
$node = ArrayToXML::isAssoc($value) ? $xml->addChild($key) : $xml;
// recrusive call - pass $key as the new rootNodeName
ArrayToXML::toXml($value, $key, $node);
}
else
{
// add single node.
$value = htmlentities($value);
$xml->addChild($key,$value);
}
}
// pass back as string. or simple xml object if you want!
return $xml->asXML();
}
// determine if a variable is an associative array
public static function isAssoc( $array ) {
return (is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array)))));
}
}
?>
Now with below responde I have tried problem is I get following output: <book>...</book> tags after each row.. then I tried 3 dimensional array now I get: <book><book>...</book></book> on the proper place but I have 2 of them.
This is the line where I have determine which is root on that array and that's why I get this output. But don't know how to change it : $xml = simplexml_load_string("<".key($data)."/>");
Thank you.
oci_fetch_array() will always return a single row, you need to call it until there are no more rows to fetch in order to get all of them:
while ($row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS))
{
$library['book'][] = $row;
}

Categories