Is this a bug with PHP array accessing? - php

I ran into this bug where an element of an array, if its index is the string "0", is inaccessible.
It's not a bug with unserialize, either, as this occurred in my code without invoking it.
$arr = unserialize('a:1:{s:1:"0";i:5;}');
var_dump($arr["0"]); //should be 5, but is NULL
var_dump($arr[0]); //maybe this would work? no. NULL
Am I doing something wrong here? How do I access this element of the array?

Yes, it looks as though it is a bug, related to PHPs automatic conversion of strings to integers. More information is available here: http://bugs.php.net/bug.php?id=43614
var_dump( $arr ); // => array(1) { ["0"]=> int(5) }
$arr2["0"]=5;
var_dump($arr2); // => array(1) { [0]=> int(5) }
print serialize($arr2); // a:1:{i:0;i:5;}
So it seems that older versions of PHP5 don't perform the string index to integer index conversion in unserialize.
This bug was reported in PHP 5.2.5, and is fixed in PHP 5.2.6 (see http://www.php.net/ChangeLog-5.php#5.2.6).

use var_dump on the structure to see how it's represented . maybe that will help. I was doing the same thing in Perl when I had problems like this with Data::Dumper

Actually, the code in your question yields
int(5)

Related

How to convert the string representation of array to normal array

I have string representation of an array in a file. I need to convert it to array . How to achieve this.
For example
$arr = 'array(1,2,3,4,5,6)';
echo getType($arr); // string
//convert $arr to type array
echo getType($arr); // array
It depends on if the file is made up entirely of valid PHP. If it is you could just include the file. Otherwise, given that this string is valid PHP you could eval the string, though typically this is viewed as bad solution to almost any problem.
If the entire file is valid PHP and you just want the array in another script use include.
somefile.php
return array(1,2,3,4,5,6);
someotherfile.php
$arr = include 'somefile.php';
var_dump($arr);
This gives you...
array(6) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
}
I don't know if the string format is fixed or not.
If not you could look at serialize() and unserialize().
The other approach, assuming the format is as written, would be to execute the file, through require or include, rather than read it as a string. That would create the variable in your context. There are a few little issues with this approach, such as enclosing tags, but perhaps that is resolvable in your situation.
Lastly I found this approach as well: Execute PHP code in a string. This is an improved variant of my second approach.
Use php-array-parser.
But it's not working well with different types of tokens in the same time, e.g. "array()" and "[]".

Error "Cannot use object of type stdClass as array" when accessing a clearly existing, integer type data from Laravel Database query result

I got my data from Laravel database query command:
$group = DB::table('groups')->where("id", $group_id)->first();
When I var dump my data, I get:
object(stdClass)#200 (7) {
["id"]=>
int(1)
["levels_id"]=>
int(1)
["title"]=>
string(8) "Novice 1"
["description"]=>
string(11) "Lorem Ipsum"
["max_question_display"]=>
int(5)
["created_at"]=>
NULL
["updated_at"]=>
NULL
}
I want to access the max_question_display. But when I do:
var_dump($group["max_question_display"]);
PHP returns error Cannot use object of type stdClass as array.
When I do:
var_dump($group->max_question_display);
I get:
int(5)
But I don't want the int. I only want the 5. In integer form.
If I foreach loop the $group:
foreach ($group as $t) {
echo "<pre>";
var_dump($t);
echo "</pre>";
}
I get each of the data as a single data each loop.
int(1)
int(1)
string(8) "Novice 1"
string(11) "Lorem Ipsum"
int(5)
NULL
NULL
This is obviously also not the way the result accessed that I'm looking for.
I also tried to get the first element of array, thinking that this might be an array with 1 element, but that also raise the same error.
I get it that the general answer in this site about this error is that "stdClass is not array". I have browsed several question with similar title like mine, but nothing address object that came from Laravel DB. When I read the manual on Laravel DB, I was assured that I can access the data returned like a simple dictionary / hashmap.
EDIT: Sorry, I understand my very, very newbie mistakes. No need to answer this. Thanks.
Notice the first line of your first var_dump:
object(stdClass)#200
Because you're dealing with an object, you access its properties with ->. When you do:
var_dump($group->max_question_display);
The reason you see (int) in the output is that the var_dump function shows the value type, next to the value. To access the value, do
$group->max_question_display;
If you want to see it on screen without the type, use echo
echo $group->max_question_display; // 5
stdClass is an object. You cannot use an object with array syntax to access its properties, if the class does not implement ArrayAccess interface.
As pointed out by #IbrahimLawal , var_dump outputs both the type and value. Just echoing $group->max_question_display will provide just the value
echo $group->max_question_display; // 5
In Summary: You must use arrow syntax when interacting with stdClass.

How to convert a Python List to a PHP array via a MySQL table

I have inherited a MySQL database where one of the fields in a table returns a string that was once a Python list so I get something like this:
$test = "[u'Person 1', u'Person 2']";
What is the cleanest/easiest/best/simplest (I'm not sure how to phrase this) to get this data back into an array in PHP? I am using PHP4 but I could upgrade to PHP5.4 if necessary.
I don't have much experience programming in PHP and my first thought was to do something like this:
$new = explode(",",$test);
This kind of works but it would need cleaning up afterwards (for instance each element of the array has at least u' in front of it) and is obviously fragile if any of the elements contain a comma.
Is there a cleaner/easier/better/simpler way of doing this?
Your best bet is to write a Python script that updates the mysql datastore with JSON, which can be easily parsed by just about every language out there. ( as #Hugo Dozois noted ]
Personally, I wouldn't try to read this in PHP. The example you showed has 2 unicode strings in a flat list... but you're likely going to run into more issues and edge cases as time goes on. You might have some unicode strings, other byte strings, some numbers... possibly even nested lists or dicts.
If you didn't inherit it, and were 100% sure of what's going on - then sure, you could parse stuff. But it should take less than 5 minutes to write and run a Python script that converts this to JSON and solves all your problems.
You could use preg_match_all and do this:
$test = "[u'Person 1', u'Person 2']";
preg_match_all('/u\'(.*?)\'/', $test, $matches);
var_dump($matches);
/*
array(2) {
[0]=> array(2) {
[0]=> string(11) "u'Person 1'"
[1]=> string(11) "u'Person 2'" }
[1]=> array(2) {
[0]=> string(8) "Person 1"
[1]=> string(8) "Person 2"
}
}
*/

in_array() works fine but throws error?

AFAIK - in_array() should return TRUE or FALSE.
In my case, It does validate as true - but still throwing an error:
[function.in-array]: Wrong datatype for second argument
The line is this :
in_array($key,$instance['cfl2']);
and the $instance['cfl2'] is a verified array which looks like this :
array(2) { [0]=> string(8) "price" [1]=> string(6) "age" }
My questions are :
What am I doing wrong.
Why it is throwing an error (but still working fine and returns true)
Is the problem occur because I use some kind of nested array ? (meaning that an array item $instance['cfl2'] is actually an array by itself ?
I also tried $is = $instance['cfl2'] and in_array($key,$is) - but the result was the same error.
You can cast a variable to an array to avoid this error:
in_array($key, (array) $instance['cfl2'])
in_array() will deal as in_array("search", $instance).
If you are using a nested or multidiamentional array, then in_array() wont work and you should write a separate function to handle this. Or use array_key_exists() instead. It will work for certain specific situations. Find out if your requirement is met.
ie
if(array_key_exists($key,$instance['cfl2']))

Associative array with 2 names that are the same?

I'm working on a PHP script that updates some tracking numbers based on an uploaded CSV file. The import worked fine for some time, then the exports started having quotation marks around the values. I thought this would be fine, but it started rejecting the files. Doing some debugging and var_dumps, I discovered a very strange situation I have never seen before - An associative array with two indices with the same name. I ran the code setting the fields (shown below) and added a line:
$v['order_id'] = '119205';
After running that line, the var_dump was as follows:
array(15) {
["order_id"]=>
string(6) "119205"
["Tracking Number"]=>
string(22) "6735675476254654756"
["Postage"]=>
string(4) "1.64"
["order_id"]=>
string(6) "119205"
}
Some fields removed for brevity. As you can see, there are two ["order_id"] indices. How is this even possible?
Here is the code that sets the values of the array dumped above:
$v = array();
foreach ($map as $k => $n) {
$v[$n] = #$data[$k];
}
with $map being the CSV header row. Trying to reference $v['order_id'] without running the $v['order_id'] = '119205'; line resulted in this error:
Notice: Undefined index: order_id in /dir/to/php/file/php_file.php</b> on line 29
Manually setting the index worked as expected, pulling the rest of the data from $v without issue.
EDIT:
Dumping the array_keys resulted in:
[0]=>
string(11) "order_id"
and:
[14]=>
string(8) "order_id"
making the first one three characters longer.
var_export still resulted in identical indices.
How can I get rid of these invisible characters? I've already tried $v[trim($n)] = #$data[$k]; in the foreach().
Try var_dump(array_keys($v)). Find the key that looks like order_id and make sure the string's length is exactly 8. I suspect there may be a NUL character in there, which would give it a length of 9 and cause it to not respond to order_id.
Quote:
In the output of var_dump(), the null bytes are not visible.
Technically you can not have two times the same key in PHP in an array. It might be that var_dump is not giving the right keys here (e.g. probably some null-chars or other non-displayable chars are dropped).
Instead you might want to check, what's going on:
var_dump(array_keys($data));
Maybe it helps, the following is a related question which demonstrates when var_dump hides some information:
Array to Object and Object to Array in PHP - interesting behaviour

Categories