Unable to get object of array by index - php

EDITED:
I am generating a 2D array and storing it in db as json string. When I need to modify anything in the array, I then fetch the json string and decode it like
$myarray = (array)json_decode($jsonString);
The dump of array is as
$index = 2;
When I wan to access object at index '2' like $myarray[$index] I get null. Please guide what I am doing wrong?

In your comment you said this "array" was decoded from JSON. When you use json_decode, send true as the 2nd parameter. That tells it to make arrays instead of objects when decoding.
You're having trouble because the array is being decoded as an object, which you access using -> instead of [].
$newArray = json_decode($jsonString, true);
UPDATE: You were trying to do (array)json_decode($jsonString) and that wasn't working. That's because PHP is silly when it comes to type-casting.
Here's a quote from the PHP docs:
If an object is converted to an array, the result is an array whose
elements are the object's properties. The keys are the member variable
names, with a few notable exceptions: integer properties are
unaccessible; private variables have the class name prepended to the
variable name; protected variables have a '*' prepended to the
variable name. These prepended values have null bytes on either side.
This can result in some unexpected behaviour.
Source: http://php.net/manual/en/language.types.array.php#language.types.array.casting
So, it wasn't working because PHP said so.

try with
$index = '2';
I think you defined the array as associative.

Related

purpose of (array) in PHP

I came across (array) in WordPress in the following code but looked in the PHP manual search for (array) but could not find anything (https://www.php.net/manual-lookup.php?pattern=%28array%29&scope=quickref)
foreach ( (array) $cron as $timestamp => $hooks) {
foreach ( (array) $hooks as $hook => $args ) {
$key = md5(serialize($args['args']));
$new_cron[$timestamp][$hook][$key] = $args;
}
}
Could someone please explain what this (array) does?
This is called casting a variable (AKA casting or type-juggling). You are saying you want $cronhooks to be converted to and evaluated as an array. Look at this example:
$a = (int) 5.3;
print($a);
5
The (int) indicates that I want an integer from 5.3. so the PHP convert it.
It's casting the variable to an array. Perhaps $cronhooks was an object rather than an array, and could not be iterated as a key => value array.
Here's the manual page for Type Jugling in PHP
https://www.php.net/manual/en/language.types.type-juggling.php
Array members can be accessed using index or key as follow:
$cronhooks[0]; // the first member
$people['tom']; // the member with the key 'tom'
objects and classes have members which are accessed using the object operator:
$person->name; // name property of a person object
$person->save(); // might be a method to save the person back to the database
Interestingly wordpress has a built in internal function called _get_cron_array() which should return the cron jobs as an array.
Currently that source code is here:
https://github.com/WordPress/WordPress/blob/056b9c47a2114a23e9a892df2d5f79856dbe5a73/wp-includes/cron.php#L924-L945
But even in their own code they are casting it to array, which seems odd given the function professes to return an array in it's name!
That one casting example:
https://github.com/WordPress/WordPress/blob/056b9c47a2114a23e9a892df2d5f79856dbe5a73/wp-includes/cron.php#L95
Anyway this was fun to explore :D
This is infact known as type-juggling, or type-casting.
In some cases (such as int to float, int to string, string to an array, int to an array) the type will be converted (allowing a regular string or int to be looped though as in the example above).
However, some types cannot be effectively converted to another, such as an array to a string, int, or class object for some examples and PHP will issue a notice such as:
Notice: Array to string conversion in /path/file.php on line 10
and the array will be converted to a string with the contents "Array". However your PHP will not throw an error so the script will continue and not work as you probably expected.

PHP: Getting associative array returns null, despite existing in var_dump

I have an array of 'servers' that I'm storing in a JSON file.
The JSON file looks like this:
{"1":{"available":1,"players":0,"maxplayers":4}}
I retrieve this value with this:
$servers = (array) json_decode(file_get_contents("activeservers.json"));
However, when I try to access the array with $server = $servers[$id], $server is null. I noticed that the key is in quotes, so I also tried casting $id to a string, and surrounding it with quotes (") which didn't work.
Something to note, is that this code is returning "NULL":
foreach(array_keys($servers) as $key){
var_dump($servers[$key]);
}
Your code is wrong. Also you don't need to type cast when doing a json_decode, you can instead set the second parameter to true more info here.
Also you don't need to use the array_keys function in your foreach loop,
try this.
$json = '{"1":{"available":1,"players":0,"maxplayers":4}}';
$servers = json_decode($json, true);
foreach($servers as $key => $value) {
print $value["available"];
}
Do a print_r($value) to get all the array keys available to use. Also you could take advantage of the $key variable to print out the array key of the parent array.
Thanks, #Rizier123 (who solved the question).
Apparently passing TRUE as the second parameter to my json_decode function fixes the issue.
After checking the PHP documentation for json_decode() (PHP: json_decode), it seems that passing this parameter means that the resulting decoded array is automatically converted into an associative array (and this is recurring, meaning that this automatically happens for sub-arrays).
Edit: #Rizier123 also says that "you might want to read: stackoverflow.com/a/10333200 to understand a bit better why it is so "weird" and your method didn't work properly."

Getting value from string by index

I have a string of data formatted like so:
[{"pr_a_w":"10","pr_a_we":"10","pr_c_w":"10","pr_c_we":"10"},{"pr_a_w":"20","pr_a_we":"20","pr_c_w":"20","pr_c_we":"20"},{"pr_a_w":"111","pr_a_we":"11","pr_c_w":"111","pr_c_we":"111"}]
The string doesn't have any index/numbers like a regular array would and I'm finding it difficult to extract individual values e.g. with a regular array I could use:
$string[0]["pr_a_w"]
To get the first instance of "pr_a_w" and I could use:
$string[1]["pr_a_w"]
To get the second instance etc.
Is it possible to get single values from this string based on their number?
What you have there is valid JSON (serialized array of objects), so you could use json_decode to translate the serialized data into a native PHP array:
$array = json_decode('[{"pr_a_w":"10","pr_a_we":"10","pr_c_w":"10","pr_c_we":"10"},{"pr_a_w":"20","pr_a_we":"20","pr_c_w":"20","pr_c_we":"20"},{"pr_a_w":"111","pr_a_we":"11","pr_c_w":"111","pr_c_we":"111"}]',true);
$array will then allow you to do exactly what you stated you'd like to do above.
$array[0]["pr_a_w"]; // will give you 10
$array[1]["pr_a_w"]; // will give you 10
Try like this, No need to access with array index. You will get error if you access wrong index.
$json_arr= json_decode('[{"pr_a_w":"10","pr_a_we":"10","pr_c_w":"10","pr_c_we":"10"},{"pr_a_w":"20","pr_a_we":"20","pr_c_w":"20","pr_c_we":"20"},{"pr_a_w":"111","pr_a_we":"11","pr_c_w":"111","pr_c_we":"111"}]',true);
foreach($json_arr as $row){
echo $row['pr_a_w']."<br>";
}

JSON_ENCODE of multidimensional array giving different results

When doing a json_encode a multidimensional array in PHP, I'm noticing a different output simply by naming one of the arrays, as opposed to not naming them. For Example:
$arrytest = array(array('a'=>1, 'b'=>2),array('c'=>3),array('d'=>4));
json_encode($arrytest)
gives a single array of multiple json objects
[{"a":1,"b":2},{"c":3},{"d":4}];
whereas simply assigning a name to the middle array
$arrytest = array(array('a'=>1, 'b'=>2),"secondarray"=>array('c'=>3),array('d'=>4));
json_encode($arrytest)
creates a single json object with multiple json objects inside
{"0":{"a":1,"b":2},"secondarray":{"c":3},"1":{"d":4}};
why would the 1st option not return the same reasults as the 2nd execpt with "1" in place of "secondarray"
In JSON, arrays [] only every have numeric keys, whereas objects {} have string properties. The inclusion of a array key in your second example forces the entire outer structure to be an object by necessity. The inner objects of both examples are made as objects because of the inclusion of string keys a,b,c,d.
If you were to use the JSON_FORCE_OBJECT option on the first example, you should get back a similar structure to the second, with the outer structure an object rather than an array. Without specifying that you want it as an object, the absence of string keys in the outer array causes PHP to assume it is to be encoded as the equivalent array structure in JSON.
$arrytest = array(array('a'=>1, 'b'=>2),array('c'=>3),array('d'=>4));
// Force the outer structure into an object rather than array
echo json_encode($arrytest , JSON_FORCE_OBJECT);
// {"0":{"a":1,"b":2},"1":{"c":3},"2":{"d":4}}
Arrays with continuous numerical keys are encoded as JSON arrays. That's just how it is. Why? Because it makes sense.
Since the keys can be expressed implicitly through the array encoding, there is no reason to explicitly encoded them as object keys.
See all the examples in the json_encode documentation.
At the first option you only have numeric indexes (0, 1 and 2). Although they are not explicitly declared, php automatically creates them.
At the second option, you declare one of the indexes as an string and this makes PHP internally transform all indexes to string.
When you json encode the first array, it's not necessary to show the integers in the generated json string because any decoder should be able to "guess" that they are 0, 1 and 2.
But in the second array, this is necessary, as the decoder must know the key value in your array.
It's pretty simple. No indexes declared in array? Them they are 0, 1, 2, 3 and so on.
output of this as in json form is year1{a,b},year2{c}, year3{d}
**a has value 1 ,b=2,c=3,d=4 stored in array of year1's a,b years2's c and years3's d respectivily
$array1 = array('a'=>1, 'b'=>2);
$array2 = array('c'=>3);
$array3 = array('d'=>4)
$form = array("year1" =>$array1,
"year2" =>$array2,
"year3" =>$array3,
);
$data = json_encode($form);

How to find if a perversely constructed object is empty in PHP

I'm working with an object fed back from a class. For some reason, the class spits out an object with numbered properties (0, 1, 2, etc.). I need to check if the object is empty. The standard trick, empty(get_object_vars($obj)), won't work, because get_object_vars returns an empty array even when the object has (numbered) properties.
For reference, the object I'm working with is the one returned by the legislatorsZipCode method of the PHP interface for Sunlight's API. You can see a print_r of a sample response here.
Judging by the code, the author made the mistake of casting a numerically indexed array to an object. This makes getting object properties by name impossible, though you should still be able to foreach over it. You can also simply cast it back to an array: $results = (array) $obj;. Then, count the array.
This appears to work:
if (current($obj) === false)
echo "is empty\n";
It probably is doing an implicit cast to an array.

Categories