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
Related
A sample of my associative array is as follows:
// Sets Array
["modern masters 2015"]=>
string(3) "MM2"
["modern masters"]=>
string(3) "MMA"
["mercadian masques"]=>
string(3) "MMQ"
The element that is giving me trouble is "modern masters 2015." Here is a snippet of the code:
$currentSet = "Modern Masters 2015";
$currentSet = strtolower($currentSet);
var_dump($sets[$currentSet]);
When I do var_dump(), it returns NULL only for this particular set. The sets array has over 100 elements, all of which work in the above code EXCEPT "modern masters 2015." However, if I call:
var_dump($sets["modern masters 2015"]);
...it works just fine and returns "MM2" as desired. It's only when I use a variable in between the brackets it returns null (for some odd reason).
What is also weird is that this particular set did not used to be bugged. I speculated that it may have been the integers, but other sets with integers in the name worked perfectly. I'm not too sure what is going on here; some guidance would be appreciated.
Problem had nothing to do with my code. Was a problem on with the file that the program was reading from. "Modern Masters 2015" was the first line of the file and was being read into the program with a length of 22, despite having an actual length of 19. There must have been some invisible characters in front or at the end, causing the length to increase to that number, and was not removed if a trim() operation was performed on it.
I currently have some json data that I am retrieving via PHP, however, my result has String(20) in front of it;
** Answer - Var_dump causes this, just echo.
The string(20) is because you asked for a var_dump() of the item. var_dump() does more than echo the item, it describes it.
From the docs -
This function displays structured information about one or more expressions that includes its type and value. Arrays and objects are explored recursively with values indented to show structure.
Extra Answer - yes, try str_replace()
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"
}
}
*/
I'm using the SimpleViewer flash image gallery on a site, and it uses an XML file for information about the images it displays.
For the site, I need to dynamically generate the XML, so I'm using a PHP file with a text/xml Content-type declared. However, for some reason when I access one of the GET variables in the $_GET array SimpleViewer tells me that there are no images in the gallery, even though when I view the source it looks the exact same and is well-formed.
Here's the code:
$photos = array(
"1" => array("house1_1.JPG")
);
foreach($photos[$_GET["hid"]] as $p){
echo '';
}
If I replace $_GET["hid"] with "1" then it works fine, but when I make the reference to $_GET it returns the error.
Is there some reason as to why accessing a GET variable would cause scripts linking to the XML (the SimpleViewer flash) to malfunction, and is there a way to get around this?
*Note: The "hid" GET variable is 100% sure set to "1", and there is no PHP error.
Also, the output looks exactly the same for when I use $_GET["hid"] versus "1", the only difference is the SimpleViewer script refuses to see that the images are there.
Also, the stuff in the empty quotes is some XML, but I don't know how to get it to appear in the tags...
Var dump of $photos and $_GET, respectively:
array(1) {
[1]=>
array(1) {
[0]=>
string(12) "house1_1.JPG"
}
}
array(1) {
["hid"]=>
string(1) "1"
}
I would first check and make sure $_GET["hid"] is returning "1". If it's possible that it is not returning "1" then it should throw an error accessing a bad index of $photos.
Is the $_GET hid variable set in your request? If not this will trigger a PHP warning.
var_dump($_GET['hid']); to see the value of the $_GET variable and ensure it as you expect.
Also please ensure that you have error reporting set to at least E_ALL and display errors is set to yes/true to make your debugging easier.
I think you're probably having an issue with the difference between "1" and 1. When you use a get with something like ?hid=1, it's not coming through as a string, that's being converted to a number, whereas your actual array is using the string "1" as the key.
Either change your key to 1 instead of "1" or cast the hid to string.
Issue was never resolved -- I ended up having to just move on and go for a longer and less elegant solution. Oh well.
On stream.get, I try to
echo $feeds["posts"][$i]["attachment"]["href"];
It return the URL, but, in the same array scope where "type" is located (which returns string: video, etc), trying $feeds["posts"][$i]["attachment"]["type"] returns nothing at all!
Here's an array through PHP's var_dump: http://pastie.org/930475
So, from testing I suppose this is protected by Facebook? Does that makes sense at all?
Here it's full: http://pastie.org/930490, but not all attachment/media/types has values.
It's also strange, because I can't access through [attachment][media][href] or [attachment][media][type], and if I try [attachment][media][0][type] or href, it gives me a string offset error.
["attachment"]=> array(8) {
["media"]=> array(1) {
[0]=> array(5) {
["href"]=> string(55) "http://www.facebook.com/video/video.php?v=1392999461587"
["alt"]=> string(13) "IN THE STUDIO"
["type"]=> string(5) "video"
My question is, is this protected by Facebook? Or we can actually access this array position?
Well, once the data is returned to you, it can no longer be protected by Facebook. You have full access to everything in that result as a regular data structure.
From the looks of it, there are multiple href properties throughout, so you'll want to be careful which one you're going for. $feeds["posts"][$i]["attachment"]["href"] is a valid element for some items, but $feeds["posts"][$i]["attachment"]["media"][0]["href"] is also a valid element.
There doesn't appear to be a $feeds["posts"][$i]["attachment"]["type"] element though, so that's why you're getting nothing for that particular item. There is a type inside ["attachment"]["media"][0] however, which is probably what you want.
If you are getting a string offset error when using array syntax, you've probably mixed up an element somewhere. Strings can be accessed via array syntax. For example:
$str = "string";
echo $str[1]; //echos 't'
You would get an offset warning if you tried to access an index that was larger than the string. In any case, from the looks of that output, $feeds["posts"][$i]["attachment"]["media"][0]["type"] should work.