How Do I retrieve a string value JSON in PHP? - php

I have a returned string result from an API and it looks like this.. for the life of me, I cannot retried the WorkID value!
The returned string is a json string:
{"notes":"","RecordsStatus":"{\"0\":{\"WorkID\":\"0090210\",\"Message\":\"Record Created\"}}"}
It has two parts:
“notes” and “RecordStatus”.
If message is empty, means the batch is imported without error.
In RecordStatus, there are two parts too.
First is the index number of the record, and it has second part that the key for the record created(in my case it’s the WorkID) and a message tells the record is created or updated(in my case, it’s created).
Array
(
[notes] =>
[RecordsStatus] => {"0":{"WorkID":"0090210","Message":"Record Created"}}
)
Do a Var_dump() of decoded_json results in this:
array(2) {
["notes"]=>
string(0) ""
["RecordsStatus"]=>
string(52) "{"0":{"WorkID":"0090210","Message":"Record Created"}}"
}
I tried
foreach($decoded_json as $item) {
$uses = $item['RecordsStatus'][0]['WorkID']; //etc
}
but does not work

Related

PHP array cannot get value from key

I got an object that has some private properties that i cannot access.
var_dump($roomType);
// I deleted some of the results of var_dump
object(MPHB\Entities\RoomType)#2003 (6) {
["id":"MPHB\Entities\RoomType":private]=> int(15)
["originalId":"MPHB\Entities\RoomType":private]=> int(15)
["description":"MPHB\Entities\RoomType":private]=> string(0) ""
["excerpt":"MPHB\Entities\RoomType":private]=> string(0) ""
["imageId":"MPHB\Entities\RoomType":private]=> int(406)
["status":"MPHB\Entities\RoomType":private]=> string(7) "publish" }
So I convert the object to array.
$array = (array) $roomType;
print_r($array);
/*
Array (
[MPHB\Entities\RoomTypeid] => 15
[MPHB\Entities\RoomTypeoriginalId] => 15
[MPHB\Entities\RoomTypedescription] =>
[MPHB\Entities\RoomTypeexcerpt] =>
[MPHB\Entities\RoomTypeimageId] => 406
[MPHB\Entities\RoomTypestatus] => publish )
*/
but I still cannot access the values from key like this
var_dump($array["MPHB\Entities\RoomTypeimageId"]); // NULL
The only workaround i got is this :
$array = (array) $roomType;
$array_keys = array_keys($array);
$array_key_id = $array_keys[4];
echo $array[$array_key_id]; // 406
But I am not sure that the key is at the same position all the time, so I want to find an other way.
I escaped the slashes but still the same, any ideas?
Edit :
So I tried to compare the $array_key_id (which is MPHB\Entities\RoomTypeimageId) with the same value (copied from the browser) and it fails.
So I did a loop and pushed the key=>value to the existing $array and now I can get the value.
There must be something like null bytes as BacLuc said.
I would guess that escaping is the problem:
$array["MPHB\Entities\RoomTypeimageId"] -> $array["MPHBEntitiesRoomTypeimageId"] for which there is no value in the array.
But $array["MPHB\\Entities\\RoomTypeimageId"] might work.
Edit:
it's escaping plus on private properties have the class name prepended to the property name, surrounded with null bytes.
Test is here: http://sandbox.onlinephpfunctions.com/code/d218d41f22e86dd861f562de9c040febb011d577
From:
Convert a PHP object to an associative array
https://www.php.net/manual/en/language.types.array.php#language.types.array.casting

PHP: Defined Array value undefined

I have an array which I return from a class. It contains data for me which I need in the controller of my application. However something strange is happening. Some values are when I get them by key not defined. But when I print the whole array they are defined. But that's not all. Some keys return their value, some don't.
To test if the key can be found I used array_key_exists(), which returned true. Let's get to the example. When I print $this->case->data, it will return the following;
[id] => 1
[ticket_number] => 2334
[user_id] => 2
[ticket_state] => 1
Which is okay. To test this out I tried returning the ticket_number value. ($this->case->data['ticket_number']). It worked perfectly and returned it's value. However when I try to return ticket_state ($this->case->data['ticket_state']) I get an undefined as value.
It might be that I'm missing something here. What am I doing wrong? And if I'm doing it wrong how can it be that ticket_number works, but ticket_state does not?
Edit:
I do get undefined as value returned. Not an undefined index error. I did a var_dump() on the variable.
array(4) { ["id"]=> string(1) "1" ["ticket_number"]=> string(14) "2334" ["user_id"]=> string(1) "2" ["ticket_state"]=> string(1) "1" }
Edit II:
My code where I try to receive the value is the following simple if statement;
if($this->case->data['ticket_state'] == 2){
$this->case->reopen();
}
I've tried adding the 2 in quotes, but since $this->case->data['ticket_state'] is undefined it the statement will be executed regardless. (Which I found strange too. Why should it still be executed when undefined is not the same as 2 or '2'?).
The current value of my column ticket_state is 1.

HY093 Error when executing prepared statement in PDO

I'm getting data from multiple API requests and storing each in a separate MySQL table. For each request I have an associated table, with field names matching the JSON API response. Since I'm not using all of fields from the API, I'm finding the fields in the MySQL table and using that to create the prepared statement with PDO, then feeding the results array into that for execution. Here's the function that accepts the statement and the results array:
function insert_array($sql,$args)
{
$this->connect();
$q = $this->con->prepare($sql);
foreach($args as $record) {
$q ->execute($record);
echo "<pre>";var_dump($record);echo "</pre>";
$arr = $q->errorInfo();
print_r($arr);
}
$this->disconnect();
return $q;
}
The last three lines in the foreach loop are just for debugging.
This worked fine for my first request, but no records are inserted, and I receive HY093, for others.
For the one that works, the prepared statement ($sql) comes out as
INSERT INTO fs_dynamicagents (agent_id, firstname, lastname) VALUES (:agent_id, :firstname, :lastname) ON DUPLICATE KEY UPDATE firstname=:firstname, lastname=:lastname
I'm finding unique fields first, so that's why agent_id isn't in the update statement. This inserts successfully, even though I'm not using all the fields. Here's the output of the var_dump and errorInfo:
array(4) {
["agent_id"]=>
string(3) "002"
["firstname"]=>
string(9) "Bill"
["lastname"]=>
string(5) "Murray"
["password"]=>
string(4) "1212"
}
Array ( [0] => 00000 [1] => [2] => )
Now here's an example of one that doesn't work:
INSERT INTO fs_queue (name, record) VALUES (:name, :record) ON DUPLICATE KEY UPDATE record=:record
And part of the first API record:
array(79) {
["name"]=>
string(7) "Choice1"
["fc_name"]=>
string(7) "Choice1"
["friendlyname"]=>
string(7) "Choice1"
["record"]=>
string(1) "1"
["agent_announcement_file"]=>
string(0) ""
["play_agent_announcement_file"]=>
string(1) "0"
["incoming_call_script"]=>
string(0) ""
["caller_agent_match"]=>
string(1) "0"
["survey_id"]=>
NULL
}
Array ( [0] => HY093 [1] => [2] => )
You can see I haven't included all 79 of the fields, but I've tried to include at least the fields with "name" in the label, and an empty string and a null value. Nothing but "name" and "record" should be bound, so I don't see those as a problem.
Every instance I've found online for this error code was due to a type (or case sensitivity). I've tried defining "record" as an int and a varchar.
Well, I had hoped that the process of typing this out would expose the problem to me, but no such luck. If a night's sleep doesn't help, I'd love to hear thoughts.
Edit: Something else I have tried is removing the ON DUPLICATE UPDATE section (and emptied the table so there will not be any duplicates) so that each parameter is only bound once. It sounds like that was a bug a few years ago that has been fixes, but even without that I receive the same error.
Edit2: Hmm, even stranger, removing the ON DUPLICATE UPDATE causes some of my previously working statements to fail with the same error. Not all of them, and of course those that don't fail for that reason will fail if it runs into a duplicate.
Edit3: Something else I have tried is removing the binding-by-key for the update statement, and changing this to
INSERT INTO fs_queue (name, record) VALUES (:name, :record) ON DUPLICATE KEY UPDATE record= VALUES(record)
I didn't think that would fix it, because it succeeds the first way on other tables, and this does in fact still fail.
Edit4: I was able to make one of these work by adding fields to the MySQL table so that all the columns from the input array were being used. However, I don't think that's what really solved the problem, because I have others succeeding without all columns being used, even in the middle of the array.
Ok, I figured it out. First, I was not setting ATTR_EMULATE_PREPARES at all, which means it would default to the database preparation engine unless the PDO engine was required. Since MySQL cannot re-use placeholders, it was using the PDO engine. Setting that to false would force the MySQL engine, and all requests would fail.
So the PDO engine can re-use placeholders, but however that happens it's not very good at finding the values. Even trying to find 2 out of 3 columns it would sometimes fail. So rather than let PDO sort it out, I'm throwing out everything I don't need before I send it to be inserted.
I'm using a function to delete columns that I found here.
<?php
function delete_col(&$array, $key) {
return array_walk($array, function (&$v) use ($key) {
unset($v[$key]);
});
}
$table_fields = array("id","fruit");
$insert_data = array(
array(
"id" => "1",
"fruit" => "Apple",
"color" => "Red"
),array(
"id" => "2",
"fruit" => "Apple",
"color" => "Green"
),array(
"id" => "3",
"fruit" => "Pear",
"color" => "Green"
)
);
foreach($insert_data[0] as $key=>$value) {
if(!in_array($key, $table_fields)) {
delete_col($insert_data, $key);
}
}
echo "<pre>";
print_r($insert_data);
echo "</pre>";
?>
This assumes that the first record will have an entry for every column. I do have some where that's not true, but so far it hasn't caused problems, but I will probably end up rewriting this to go through each row.

creating multiple php arrays

I have a html form with checkboxes. Someone selects one or more checkboxes and hit the delete button then it will delete the files references out of the database and delete the files out of Amazon S3. This is the code I used to find all the checkboxes
$checkbox_select = JRequest::getVar('checkboxselect', '', 'POST'); //just a Joomla way of doing a $_POST with extra security
var_dump($checkbox_select); //this returns: array(2) { ["video_1.mp4"]=> string(2) "on" ["video_2.mp4"]=> string(2) "on" ["video_3.mp4"]=> string(2) "on"}
// Localize and sanitize each individual value
foreach (array_keys($checkbox_select) as $element) {
$deleteNames[] = $db->quote($element);
}
var_dump($deleteNames); //array(3) { [0]=> string(13) "'video_3.mp4'" [1]=> string(13) "'video_2.mp4'" [2]=> string(13) "'video_1.mp4'" }
My problem is with Amazon S3 and multiple file deletion. The format I need to put S3 deletion in is quite confusing:
$s3->delete_objects('mybucket', array(
'objects' => array( // accepts a *list* of one or more *hashes*
// a *hash* that contains a "key" key with a value, and maybe a "version_id" key with a value
array('key' => 'object (file) name'),
// a second hash representing a file
// a third hash representing a file
// and so on...
),
));
As far as I understand (from S3 delete_objects function) the final associated array has key as the actual key value. With the last var_dump I've got all video names in an array now I just need to convert that array to a bunch of arrays in this format:
array ('key' => 'video_1.mp4'),
array ('key' => 'video_2.mp4'),
array ('key' => 'video_3.mp4'),
...and so on
How can I create these arrays? Should I be using the first var_dump I have or the second (they both have the video file names listed)? Thanks in advance.
You can use foreach to loop over your array and create a new array in the desired format.
Example:
<?php
foreach (array_keys($checkbox_select) as $element) {
$deleteNames[] = array('key' => $db->quote($element));
}
Untested, may contain errors
have a look at this post in the php documentation for array_push(). You'll get a brief idea of how to achieve it.

Why can I not echo the value of this multimensional array in PHP?

This is so incredibly basic that I am totally baffled as to why it doesn't work. I have an array called $elements, and I want to just echo out one of the values.
I use NetBeans as an IDE, and if I use that to examine the contents of the multidimensional array in question, it looks like this:
So far as I can tell, everything looks normal. It is a multidimensional array, where the first level is numbered "0", and the second level has four named entries.
I just want to echo the value of "parameters", which is a string.
However, this code outputs nothing:
echo "This is the value of 'parameters': " . $elements[0]['parameters'];
Have I got this most basic code wrong in some way?
This is what I get if I do var_dump($elements):
array(1) { [0]=> object(Element)#3 (4) { ["type":"Element":private]=>
string(4) "Text" ["resource":"Element":private]=> string(1) "0"
["parameters":"Element":private]=> string(209) "IP1 111.111.111.111
IP2 222.222.222.222 IP3 333.333.333.333 IP4 444.444.444.444 IP5
555.555.555.555 IP6 666.666.666.666 IP7 777.777.777.777 IP8 888.888.888.888 IP9 999.999.999.999 IP10 111.111.111.112" ["parent":"Element":private]=> NULL } }
... and this is the output from print_r($elements):
Array ( [0] => Element Object ( [type:Element:private] => Text [resource:Element:private] => 0 [parameters:Element:private] => IP1 111.111.111.111 IP2 222.222.222.222 IP3 333.333.333.333 IP4 444.444.444.444 IP5 555.555.555.555 IP6 666.666.666.666 IP7 777.777.777.777 IP8 888.888.888.888 IP9 999.999.999.999 IP10 111.111.111.112 [parent:Element:private] => ) )
Your var dump is saying that element 0 is an object, so you will need to access it like so:
echo $elements[0]->parameters;
The problem is that from your dump, the parameters element is marked as private, so you will not be able to access it.
Solutions are:
Change parameters to public
Write a getter (getParameters()) and use that method to get your parameters.
Entry 0 at $elements is not just an array of attributes it's a class Element instance so in order to access its properties do something like:
echo( $elements[ 0 ]->parameters );
Although the parameters field seems private so you'd better add an accessor method to the object like getParameters() which would be public and return the value of parameters.

Categories