How can I access the "count" from the response in SPLObjectStorage? - php

I am getting this:
How do I receive the count. I've tried a couple of ways like $r->count and $r->count();
This is a gist.
// Results is an SplObjectStorage object where each request is a key
foreach ($results as $request) {
// Get the result (either a ResponseInterface or RequestException)
$result = $results[$request];
if ($result instanceof ResponseInterface) {
// Interact with the response directly
$r = $result->getBody();
echo $r;
} else {
// Get the exception message
echo $result->getMessage();
}
}

Since that's a JSON string, You could decode it into an object using json_decode
$r = $result->getBody();
$response=json_decode($r);
echo $response->count;
Fiddle

I found the answer myself. I had to use get_object_vars(). Converts an object to array.
$r = $result->getBody();
$response=json_decode($r);
$s = get_object_vars($response);
dd($s->count);

Related

How to update a decoded JSON array with new array in PHP?

I need to know how to update a decoded JSON array with new values (I don't mean a simple array_push though).
I'm going to post my code, here's my Users.json file:
[
{
"objID":"Y0FVVFZYCV",
"createdOn":{"type":"__date","date":"2018-09-21T16:48:09"},
"string":"lorem ipsum"
},
{
"objID":"YShAUqIcMg",
"username":"johndoe", // new key->value here!
"createdOn":{"type":"__date","date":"2018-09-21T16:48:14"},
"string":"lorem ipsum"
}
]
Here's my create.php file where I used to add JSON objects from a URL string:
// Prepare data to be saved:
if(!empty($_GET)){
foreach($_GET as $key => $value) {
// Random objID
$objects->objID = generateRandomID();
// Number
if( is_numeric($value) ){
$objects->$key = (float) $value;
// Boolean
} else if($value === 'true'){
$objects->$key = true;
} else if($value === 'false'){
$objects->$key = false;
// ClassName
} else if ($key === 'className'){
// String
} else { $objects->$key = $value; }
// createdOn & updatedOn Dates
$objects->createdOn = array('type'=>'__date','date'=>$formattedDate);
$objects->updatedOn = array('type'=>'__date','date'=>$formattedDate);
}// ./ foreach
// Save data into the JSON file
$jsonStr = file_get_contents($className.'.json');
// Decode the JSON string into a PHP array.
$jsonObjs = json_decode($jsonStr, true);
// Check if there's some new key and values -> update the $jsonObjs array
$result = array_diff($jsonObjs, $objects);
print_r('<br><br>DIFFERENCE: <br>'.$result[0].'<br>');
// Push array
array_push($jsonObjs, $objects);
// Encode the array back into a JSON string and save it.
$jsonData = json_encode($jsonObjs);
file_put_contents($className.'.json', $jsonData);
// echo JSON data
echo $jsonData;
I'm trying to get the difference between $jsonObjs and $objects with array_diff():
$result = array_diff($jsonObjs, $objects);
print_r(.$result[0].'<br>');
but it dones't work, it shows an empty row and also the error_log file shows this:
PHP Warning: array_diff(): Argument #2 is not an array on line 63
I launch 2 URL strings, the first one starts with
create.php?className=Users&string=lorem%20ipsum
In the 2nd one, I add an additional string object, like this:
create.php?className=Users&string=lorem%20ipsum&username=johndoe
So, what I need to achieve is to add the "username" key into the 1st object too, as it does on the 2nd object. In other words, my Users.json file should look like this after launching the 2nd URL string:
[
{
"objID":"Y0FVVFZYCV",
"username":"", //<-- upodated key with no value
"createdOn":{"type":"__date","date":"2018-09-21T16:48:09"},
"string":"lorem ipsum"
},
{
"objID":"YShAUqIcMg",
"username":"johndoe", // new key->value here!
"createdOn":{"type":"__date","date":"2018-09-21T16:48:14"},
"string":"lorem ipsum"
}
]
As was already pointed out in the comments, you can't pass "$objects" to the array_diff function because it expects an array and "$objects" is, well, an Object.
You could cast your object to an array by calling it like this:
$result = array_diff($jsonObjs, (array)$objects);
As pointed out my #miken32, my $objects object wasn't an array, but an StdClass Object, so I simply had to replace:
$objects->
with:
$objects[$key]
In this way, $objects becomes a valid array and I can use array_diff() like this:
$result = array_diff_assoc($jsonObjs, $objects);
print_r('DIFF: '.json_encode($result).'<hr>');
It prints out a valid JSON array.

Convert an array into string or object

Good day, I am trying to convert an array "$list" into string or object. I have used following methods:
<?php
include "medclass.php";
session_start();
if (isset($_SESSION['mail']))
{
$list = $_SESSION['basket'];
}
else
header("location: clientsigninpage.php?msg= Log-in First");
$obj = new med_class;
$obj->connectdb();
$val = implode(";",$list); //implode method
$val = (object) $list; //object method
$val = serialize($list); //serialize method
$result = $obj->searchMed($val);
while ($row = $result->fetchObject())
{
echo $row->MedPrice;
}
?>
With "(object)" its giving me following error: "Object of class stdClass could not be converted to string", with "implode": "Array to string conversion" and with "serialize()" it does not print anything.
The function that I am passing value is:
function searchMed($v1)
{
$sql = "select * from storepreview where MedName = '$v1'";
$ret = $this->con->query($sql);
return $ret;
}
I have used these methods by seen following links: (http://www.dyn-web.com/php/arrays/convert.php) ; (Convert an array to a string); (How to convert an array to object in PHP?)
I managed to reproduce your "Array to string conversion" error when using the implode command by running the following line of code:
implode(";", [[]]); // PHP Notice: Array to string conversion in php shell code on line 1
For converting a nested array into a string I found that a foreach loop worked:
$nestedArray = ['outerKeyOne' => ['innerKeyOne' => 'valueOne'], 'outerKeyTwo' => ['innerKeyTwo' => 'valueTwo']];
$arrayOfStrings = [];
foreach ($nestedArray as $key => $value) {
$arrayOfStrings[] = implode(",", $value);
}
implode(";", $arrayOfStrings); // string(17) "valueOne;valueTwo"
The second error associated with the line $val = (object) $list; is from trying to embed an object into the $sql string. It seems like an object is not what you want here, unless it is an object that has a __toString() method implemented.
I hope this is of some help. Using var_dump or something similar would provide more debug output to better diagnose the problems along with the above error messages. That's how I came up with the above code.
You can use json_encode to convert Array to String:
$FINAL_VALUE = json_encode($YOUR_OBJECT);
For more information, you can refer this link.

Search through a json array obtained from a database

First of all: Yes i did check other answers but they sadly didn't do the trick.
So i'm currently working on a script that checks if an email exists in the database. So the database data is obtained through a webservice and with an input filter function the following JSON object is returned:
{"customers":{"customer":{"lastname":"test","firstname":"login","email":"nielsvanenckevort#hotmail.com"}}}
Now i would like to check if the email is filled in correctly. I'm using a foreach() statement to compare the values but i'm always getting a not found returned. Maybe someone here is able to find the mistake i've made. So the full code is shown down below.
$resultEmail = ($webService->get( $optUser ));
$emailResult = json_encode($resultEmail);
$emailArray = json_decode($resultEmail);
echo ($emailResult);
echo ($chopEmail);
foreach($emailArray->customers->customer as $item)
{
if($item->email == $email)
{
echo "found it!";
}
}
// The $optUser is the JSON object
Probably the quickest way would be strpos function, so you can use it this way
function hasEmail($string, $email)
{
return strpos($string, $email) !== false;
}
//example
echo hasEmail($resultEmail, $email) ? 'Has email' : 'Email not found';
The easiest way to do this would probably be to decode the string as an associative array instead of a json object, and then check if the key email exists using the array_key_exists function.
// passing true to json_decode will make it return an array
$emailArray = json_decode($resultEmail, true);
foreach($emailArray['customers'] as $customer) {
if(array_key_exists('email', $customer)) {
echo 'Found it!';
}
}
It seems your mistake come from the foreach loop. You should write it this way :
foreach($emailArray->customers as $customer) {
if($customer->email == $email) {
echo "found it!";
}
}
Please note that $emailArray is not an array but an object when you don't set the second parameter of the json_decode function :
$obj = json_decode($data);
$array = json_decode($data,true);

Customize json_decode behaviour

I have a JSON string returned by a REST API which follows:
'{"success":true,"product":{"id":"2","category_id":"2","type":"9","name":".ch","description":"","visible":"1","domain_options":"0","stock":"0","qty":"0","autosetup":"2","subdomain":"","owndomain":"0","tax":"0","upgrades":"","sort_order":"0","client_limit":"0","rel":"Product","paytype":"DomainRegular","m_setup":"0.00","q_setup":"0.00","s_setup":"0.00","a_setup":"0.00","b_setup":"0.00","t_setup":"0.00","p4_setup":"0.00","p5_setup":"0.00","d_setup":"0.00","w_setup":"0.00","h_setup":"0.00","m":"0.00","q":"0.00","s":"0.00","a":"0.00","b":"0.00","t":"0.00","p4":"0.00","p5":"0.00","d":"0.00","w":"0.00","h":"0.00","ptype":"DomainsType","options":"3","module":"13","server":"","tlds":null,"periods":{"1":{"product_id":"2","period":"1","register":"17.00","transfer":"17.00","renew":"17.00"}},"tag_name":".ch","tag_description":"","free_domain":"0","product_id":"2","not_renew":"0","epp":true,"ns":["ns3.dfinet.ch","ns4.dfinet.ch","",""],"nsips":"|||","tld":".ch","nsip":["","","",""],"asciimode":true,"app_id":"1","app_ns1":"","app_ns2":"","app_ns3":"","app_ns4":"","app_ip1":"","app_ip2":"","app_ip3":"","app_ip4":"","emails":{"AfterRegistrarRegistration":"28","AfterRegistrarRenewal":"29","AfterRegistrarTransfer":"30","expiringDomain":"54"}},"config":false,"call":"getProductDetails","server_time":1412061849}'
I am trying to convert this to an object and then serve an XML for a soap webservice, what I was doing up to now was
retrieving the result from the rest API -> convert it to object with json_decode($obj)
serve the soap handle() with the converted object
The problem is that, with the following JSON, there are some properties that are "numeric" but not sequential, so the JSON convert the string to an object as follows:
$o = new stdClass();
$o->1 = 'a string';
The problem is that when soap converts object to XML, the node named <1> is an invalid XML markup.
What can I do to "pre-parse" the JSON and convert all of those fake objects to sequentials arrays?
EDIT: Solution based on dmikam answer
I did something cleaner based on the proposed solution:
function fixVariables($variables)
{
if (!is_array($variables) && !is_object($variables)) {
return $variables;
}
foreach ($variables as $k => &$variable) {
if (is_object($variable)) {
if (is_numeric(key($variable))) {
$values = array();
foreach ($variable as $value) {
$values[] = $value;
}
$variable = $values;
unset($values);
}
$this->fixVariables($variable);
} elseif (is_array($variable)) {
if (is_numeric(key($variable))) {
$variable = array_values($variable);
}
$this->fixVariables($variable);
}
}
return $variables;
}
Well, I think you could walk through the resulting parsed object and convert all items that contains numeric indexes into arrays. The function would be something like this:
function fixJsonObject($obj){
if (is_object($obj)){
foreach(get_object_vars($obj) as $key=>$value){
$obj->$key = fixJsonObject($obj->$key);
if (is_numeric($key)){
return (array)$obj;
}
}
}elseif (is_array($obj)){
foreach($obj as $key=>$value){
$obj[$key] = fixJsonObject($obj[$key]);
}
}
return $obj;
}
$json = json_decode('{your: "json"}');
$json = fixJsonObject($json);
I have tested it a bitand looks like it works.

Delete from json using php

my Current json code :
{"Results":[{"username":"test","password":"test"},{"username":"test","password":"test"},{"username":"google","password":"test"},{"username":"yahoo","password":"test"},{"username":"hotmail","password":"test"}]}
i want to remove this :
{"username":"google","password":"test"}
from the code using php.
i tried deleting by decoding json to array but cant get it done.
any solution ?
$json_obj = json_decode($json_string);
$unset_queue = array();
foreach ( $json_obj->Results as $i => $item )
{
if ($item->username == "google")
{
$unset_queue[] = $i;
}
}
foreach ( $unset_queue as $index )
{
unset($json_obj->Results[$index]);
}
// rebase the array
$json_obj->Results = array_values($json_obj->Results);
$new_json_string = json_encode($json_obj);
<?php
$JSON = '{"Results":['
. '{"username":"test","password":"test"},'
. '{"username":"test","password":"test"},'
. '{"username":"google","password":"test"},'
. '{"username":"yahoo","password":"test"},'
. '{"username":"hotmail","password":"test"}'
. ']}';
// use json_decode to parse the JSON data in to a PHP object
$jsonInPHP = json_decode($JSON);
// now iterate over the results and remove the one that's google
$results = count($jsonInPHP->Results);
for ($r = 0; $r < $results; $r++){
// look for the entry we are trying to find
if ($jsonInPHP->Results[$r]->username == 'google'
&& $jsonInPHP->Results[$r]->password == 'test'){
// remove the match
unset($jsonInPHP->Results[$r]);
// now we can either break out of the loop (only remove first match)
// or you can use subtract one from $r ($r--;) and keep going and
// find all possible matches--your decision.
break;
}
}
// now that we removed items the keys will be off. let's re-order the keys
// so they're back in-line
$jsonInPHP->Results = array_values($jsonInPHP->Results);
// dump the new JSON data, less google's entry
echo json_encode($jsonInPHP);
Would be how I approach it. I like to avoid foreach(...){} statements when I need to modify the array itself. The above code, by the way, leaves you with:
{
"Results":[
{"username":"test","password":"test"},
{"username":"test","password":"test"},
{"username":"yahoo","password":"test"},
{"username":"hotmail","password":"test"}
]
}
$json = '
{
"Results":[
{"username":"test","password":"test"},
{"username":"test","password":"test"},
{"username":"google","password":"test"},
{"username":"yahoo","password":"test"},
{"username":"hotmail","password":"test"}
]
}';
$arr = json_decode($json, true);
array_filter($arr, function($v) {
return !($v['username'] == 'google' && $v['password'] == 'test');
});
$json = json_encode($arr);
$input='{"Results":[{"username":"test","password":"test"},{"username":"test","password":"test"},{"username":"google","password":"test"},{"username":"yahoo","password":"test"},{"username":"hotmail","password":"test"}]}';
$json = json_decode($input,true);
$match = array('username'=>'google', 'password'=>'test');
unset($json['Results'][array_search($match,$json['Results'])]);
To do it without a foreach but assuming you know the exact values you want to remove
Old question, formatting your JSON differently would help a lot.
Each result entry should have a unique key to identify it.
This makes it easy when needing to remove or update that result.
No reason to iterate over entire JSON this way.
Code would look like this
<?php
$jsonString = '{"Results":{'
.'{"username1":{"username":"google","password":"test1"}}'
.'{"username2":{"username":"yahoo","password":"test2"}}'
.'{"username3":{"username":"msonline","password":"test3"}}'
. '}}';
$jsonInPHP = json_decode($jsonString);
$password = $jsonInPHP["username1"]["pasword"];//Returns test1
$username = $jsonInPHP["username1"]["username"];//Returns google
?>
$myArray=json_decode($theJSONstring);
unset($myArray['Results'][2]);

Categories