Is there a way to parse the output of print_r [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Create array printed with print_r
Duplicate of How create an array from the output of an array printed with print_r?
which also has a nice code example to solve this
I need to reverse an error log which has as output print_r($data,true).
Example data would look like:
Array
(
[subject] => this is the subject
[body] => <p>Dear user,</p><p>this is the body of the email</p>
[from_id] => 0
[from_email] => admin#karakas.org
[to] => Array
(
[0] => Array
(
[id] => 0
[email] => 64909
)
)
[send_to_inbox] => 1
)

In the PHP manual there's a print_r_reverse() function in comments :
http://php.net/manual/en/function.print-r.php
However var_export() can be an alternative if your logs are generated using var_export(). This way, you only need eval() to retrieve the exported array.

The output of print_r() is not designed to parsed; it's designed to be read by a developer for debugging purposes. You should not be trying to parse it.
If you really must parse a PHP data dump of this nature, the var_export() function is intended for this kind of thing. However, I wouldn't recommend parsing this either -- it's still unlikely to be the best solution for you.
If your intention is to store a string representation of an array structure, and then parse it later, you would be better off using either the serialize()/unserialize() functions, or the json_encode()/json_decode() functions.
Both of these will give you a much more reliable and easily parseable data dump format. Of the two, I'd recommend json_encode() every time, as not only is it easy to work with, it's also supported by other languages, easy to read manually, and compact.
In short, don't parse print_r() output; use json_encode()/json_decode() instead.
http://uk1.php.net/manual/en/function.json-encode.php

Related

How to properly sanitise an array of user supplied data for JSON output?

My code
I have a function get_points_table() that returns an array like so:
Array
(
[0] => Array
(
[player] => steve
[points] => 10
)
[1] => Array
(
[player] => jess
[points] => 7
)
)
I would like to pass this array as JSON to a JavaScript script to output as HTML.
My current script looks like this:
<?php
require_once 'db.php';
$points_table = get_points_table($dbh);
echo json_encode($points_table);
?>
My problem
My understanding is that if I don't sanitise the data before echo'ing it back, there is a security risk posed by a player setting their username to something like steve<script>alert()</script> or using some other combinations of special characters.
My research suggests I need to use some combination of htmlentities() and/or htmlspecialchars() to safely output the data. However htmlentities() does not return utf8 encoded data, so I also need to use utf8_encode() in order for json_encode() to understand it. htmlentities() also does not allow you to pass an array as a value.
What I've tried
I've tried various combinations of array_walk(), array_walk_recursive() and array_map() to apply htmlentities() to each value of my array but to no success. I've also tried accessing the values in nested foreach loops to no success either. e.g.:
foreach($points_table as $key=>value) {
htmlspecialchars($value);
htmlentities($value);
utf8_encode($value);
}
echo json_encode($points_table);
What I need
I would like to know how to sanitise my array so I can safely pass it as JSON to be output as HTML, even if the user sets their username to something like steve<script>alert()</script><php echo "hello world";?> ;-- - &%00
Ideally I would like to do this so that the end result has the username in human readable format without converting symbols to html entities (i.e. steve<script> not steve"<script>")
This feels like a very common thing developers would do and should have a simple and easy answer, but I have done much searching and cannot work it out for myself.

Get array value when using file_get_contents [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Create array printed with print_r
Duplicate of How create an array from the output of an array printed with print_r?
which also has a nice code example to solve this
I need to reverse an error log which has as output print_r($data,true).
Example data would look like:
Array
(
[subject] => this is the subject
[body] => <p>Dear user,</p><p>this is the body of the email</p>
[from_id] => 0
[from_email] => admin#karakas.org
[to] => Array
(
[0] => Array
(
[id] => 0
[email] => 64909
)
)
[send_to_inbox] => 1
)
In the PHP manual there's a print_r_reverse() function in comments :
http://php.net/manual/en/function.print-r.php
However var_export() can be an alternative if your logs are generated using var_export(). This way, you only need eval() to retrieve the exported array.
The output of print_r() is not designed to parsed; it's designed to be read by a developer for debugging purposes. You should not be trying to parse it.
If you really must parse a PHP data dump of this nature, the var_export() function is intended for this kind of thing. However, I wouldn't recommend parsing this either -- it's still unlikely to be the best solution for you.
If your intention is to store a string representation of an array structure, and then parse it later, you would be better off using either the serialize()/unserialize() functions, or the json_encode()/json_decode() functions.
Both of these will give you a much more reliable and easily parseable data dump format. Of the two, I'd recommend json_encode() every time, as not only is it easy to work with, it's also supported by other languages, easy to read manually, and compact.
In short, don't parse print_r() output; use json_encode()/json_decode() instead.
http://uk1.php.net/manual/en/function.json-encode.php

From a text cell to a "real" php array [duplicate]

This question already has answers here:
How create an array from the output of an array printed with print_r?
(11 answers)
Closed 9 years ago.
I have, on a mysql table, a column in which are stored through a print_r on a previous step of the program.
So I have on a text cell of the mysql db this value:
Array
(
[id] => 129
[group_id] => 9
[rid] => 28
[date] => 2014-02-09 10:00:00
[real_time_start] => 00:00:00
[real_time_end] => 00:00:00
[site_id] => 1
[sub_site_id] => 2
[team1_id] => 9
[team2_id] => 13
[home] => 2
[result_type] => 2
[status] => 0
)
I have tried several ways, but with no success. How can I transform this one in a "real" php array?
Do you have any idea about it?
If you want to restore such data into readable PHP array do not use print_r() as its format is not easily readable by built-in parsers. You have several options:
convert it to JSON using json_encode() and then decode through json_decode,
convert to serialized format using var_export(), save to file and require() it,
use serialize() and unserialize(), as Leri said,
use YAML library (I recommend Symfony's one) and Yaml::dump() / Yaml::parse() your data.
The print_r() function prints a variable in a human-readable format. Therefore, it has no reverse equivalent.
If you’re wanting to transform a representation of an array to a plain text version for storage and back again, then use something like PHP’s serialize() and unserialize() functions.
To store an array to a table you should use serialize() function. When retrieving use unserialize() function to get the array back.
Thanks to all
The suggestion of Jasper was great, I've been able to convert the "print_r" output in a "serialize" one using the function proposed.
Now I will use serialize/unserialize to solve this problem.

Search sub arrays for specific key [duplicate]

This question already has answers here:
How to search by key=>value in a multidimensional array in PHP
(17 answers)
Closed 9 years ago.
What's the most efficient way to search an array element's sub arrays to check the value of a specific key? For example, given the following array, where I want to check both subarrays "msg" value, and if either is populated, return a boolean result:
[TGMN02] => Array
(
[2] => Array
(
[id] => 93143
[msg] =>
)
[3] => Array
(
[id] => 24876
[msg] =>
)
)
What I have at the moment is simply looping through and checking, which feels quite clunky.
I don't know about "most" efficient but this won't necessarily have to iterate through the whole array as it breaks the loop on the first value found, so technically more efficient.
function hasMsg($a){
foreach($a as $b)
if(!empty($b['msg'])) return true;
return false;
}
Okay... since some meager comments weren't accompanied by alternative suggestions - you could try using some PHP>5.3 - I really can't see how it would be any more efficient though - it must still loop through the array at some level (but I'm not 100% sure on the inner workings of the PHP interpreter - perhaps there is some internal magic that could speed things up), so this is probably purely aesthetic:
$hasMsg = !!(count(array_filter($a,function($b){ return !empty($b['msg']); })));
... if anything less efficient. There's nothing wrong with "looping" through an array - it's a tried and tested language construct that's been around since the dawn of digital time (almost).
First write some custom func and then try to use it with array_walk_recursive(array &$input , callable $funcname [, mixed $userdata = NULL ]) function. Php manual.

php json_encode

I have a symfony app that uses the json_encode and json_decode to keep a record of some prices.
The problem is that json_decode works OK in one file (I can decode the string stored in my PSQL database), but when I call it from other file json_decode returns null, I've check the file encodings (all are utf-8) the tables and database encoding(utf-8 too). So I don't know where the problem can be, tried utf8_encode() too...
Any help will be appreciated.
Thanks.
Here's the valid encoded json (It was an array encoded by php json_encode)
{"1":{"1":{"fechaInicio":"30-05-2011","precios":{"1":{"precio":"20000","abreviatura":"CLP"}},"fechaRetiro":"31-05-2011"}},"2":{"2":{"fechaInicio":"30-05-2011","precios":{"1":{"precio":"20000","abreviatura":"CLP"}},"fechaRetiro":"31-05-2011"}}}
The array:
$preciosOfertor = Array ( [unidades] => Array ( [1] => Array ( [1] => Array ( [fechaInicio] => 30-05-2011 [precios] => Array ( [1] => Array ( [precio] => 20000 [abreviatura] => CLP ) ) [fechaRetiro] => 31-05-2011 ) ) [2] => Array ( [2] => Array ( [fechaInicio] => 30-05-2011 [precios] => Array ( [1] => Array ( [precio] => 20000 [abreviatura] => CLP ) ) [fechaRetiro] => 31-05-2011 ) ) ) )
To encode it I use:
$preciosOfertor = json_encode($preciosOfertor);
Then I call
$precios = json_decode($databaseObject->getPreciosOfertor(),true);
When i use json_decode in the file that encodes the array it works, but then when I use it in other file of the project I just get NULL with var_dump().
Installed Services_JSON as suggested, but now I'm getting an empty array
The encoded json with Services_JSON is this one:
{"unidades":{"1":{"1":{"fechaInicio":"30-05-2011","precios":{"1":{"precio":"20000","abreviatura":"CLP"}},"fechaRetiro":"31-05-2011"}}}}
But when I call $json->decode() I get Array ( )
Ok people, first thank you all for the help.
I got the solution and It was all thanks to Zend Json library.
Symfony uses escaping strategies to prevent XSS attacks, SQL Injection attacks, etc. So what happened here in my case, when I called json_encode and json_decode it was inside the object that Doctrine generates to represent my object (In this case a reservation), so because it was a local call to the row data (valoresOfertor), the data from the database was not escaped thus the methods worked fine.
But then, when I tried to encode and decode the values of the row outside the reservation class, Symfony used it's escaping strategy so
"
became
&quot
So, trying different JSON libraries, I used Zend one, and saw the exception that displayed (Syntax Error:
at Zend_Json::decode('{"unidades":{"1":{"1":{"fechaInicio":"30-05-2011","precios":{"1":{"precio":"20000","abreviatura":"CLP"}},"fechaRetiro":"31-05-2011"}},"2":{"2":{"fechaInicio":"30-05-2011","precios":{"1":{"precio":"20000","abreviatura":"CLP"}},"fechaRetiro":"31-05-2011"}}}}')
in SF_ROOT_DIR/apps/saas/modules/editreserva/templates/habitacionesSuccess.php line 20 ...
So then i Added the following line:
htmlspecialchars_decode($jsonVariable);
And it worked.
I hope it helps someone if he experiments the same with symfony and json.
As far as I know, there were one or more bugs in json_encode() and json_encode() in previous versions of PHP. You could try to update PHP to the latest version or you could use an external library to encode and decode JSON. There are some, but I think PEAR JSON is the best.
it might be the UTF-8 BOM present. Try using UTF without BOM encoding. Also echo the json_last_error() to see what's the problem.
EDIT:
It IS a valid JSON
From php.net : NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit.
So either you've set e recursion limit lower than the data depth (which may not seem to be the case, if you say that it does work on another page), or the json cannot be decoded.
If it works on one page and it doesn't in another, check the file encoding.
The first page may be encoded to utf-8 (the encoding of your json) but the second one might be something else (like ascii). check the bom also.Youw may need to encode the page to utf-8 without bom.
If it's a template you're dealing it, have a look at:
$sf_data->getRaw();
http://www.geeganage.com/symfony-json-made-easy/

Categories