Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.6.0a3

Bug #4851 var_export severely broken! (new implementation attached)
Submitted: 2005-07-18 07:47 UTC Modified: 2006-12-24 14:57 UTC
From: giunta dot gaetano at sea-aeroportimilano dot it Assigned: aidan
Status: Closed Package: PHP_Compat
PHP Version: 4.0.4 OS: irrelevant
Roadmaps: 1.6.0a1    
Subscription  


 [2005-07-18 07:47 UTC] giunta dot gaetano at sea-aeroportimilano dot it
Description: ------------ The var_export distributed with compat 1.4.1 is so broken it's a joke: - no support for nested arrays above 2 levels - usage of str_replace with array alements is not compatible below php 4.0.5 - breaks hard on NULLS, BOOLEANS, FLOATS, RESOURCES Attached below is a mostly rewritten implementation, which has been hastily tested with php 4.04pl1. Hope it helps... Reproduce code: --------------- <?php // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2004 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Aidan Lister <aidan@php.net> | // +----------------------------------------------------------------------+ // // $Id: var_export.php,v 1.12 2005/02/28 08:46:06 aidan Exp $ /** * Replace var_export() * * @category PHP * @package PHP_Compat * @link http://php.net/function.var_export * @author Aidan Lister <aidan@php.net> * @version $Revision: 1.12 $ * @since PHP 4.2.0 * @require PHP 4.0.0 (user_error) */ if (!function_exists('var_export')) { function var_export($array, $return = false, $lvl=0) { // Common output variables $indent = ' '; $doublearrow = ' => '; $lineend = ",\n"; $stringdelim = '\''; // Check the export isn't a simple string / int if (is_string($array)) { $out = $stringdelim . str_replace('\'', '\\\'', str_replace('\\', '\\\\', $array)) . $stringdelim; } elseif (is_int($array) || is_float($array)) { $out = (string)$array; } elseif (is_bool($array)) { $out = $array ? 'true' : 'false'; } elseif (is_null($array)) { $out = 'NULL'; } elseif (is_resource($array)) { $out = 'resource'; } else { // Begin the array export // Start the string $out = "array (\n"; // Loop through each value in array foreach ($array as $key => $value) { // If the key is a string, delimit it if (is_string($key)) { $key = str_replace('\'', '\\\'', str_replace('\\', '\\\\', $key)); $key = $stringdelim . $key . $stringdelim; } $val = var_export($value, true, $lvl+1); // Delimit value /*if (is_array($value)) { // We have an array, so do some recursion // Do some basic recursion while increasing the indent $recur_array = explode($newline, var_export($value, true)); $temp_array = array(); foreach ($recur_array as $recur_line) { $temp_array[] = $indent . $recur_line; } $recur_array = implode($newline, $temp_array); $value = $newline . $recur_array; } elseif (is_null($value)) { $value = 'NULL'; } else { $value = str_replace($find, $replace, $value); $value = $stringdelim . $value . $stringdelim; }*/ // Piece together the line for ($i = 0; $i < $lvl; $i++) $out .= $indent; $out .= $key . $doublearrow . $val . $lineend; } // End our string for ($i = 0; $i < $lvl; $i++) $out .= $indent; $out .= ")"; } // Decide method of output if ($return === true) { return $out; } else { echo $out; return; } } } ?>

Comments

 [2005-08-01 07:31 UTC] aidan
Could you provide an example in which var_export differs from the expected value? I've tested it with the problems you've described below and not found a single issue.
 [2005-08-06 20:49 UTC] aidan
No feedback was provided. The bug is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so and change the status of the bug back to "Open". Thank you.
 [2005-08-10 07:57 UTC] giunta dot gaetano at sea-aeroportimilano dot it
I think I got it wrong about nested arrays not being supported, but when running the following code snippet I get quite a few php warnings (php 4.0.4pl1+pear var_export) and different results from php 4.4.0 with built_in var_export <pre> <?php include('var_export.php'); var_export(true); var_export(false); var_export(null); $fp = fopen(getcwd().'/var_export.php', 'r'); var_export($fp); fclose($fp); var_export(array(1, array(2, array(3,4), array(5,array(6, array(7)))))); ?> </pre> PS: BTW: 6 days is quite a short notice for suspending a bug for missing feedback. 1 to 3 months is more likely a meaningful timespan. Or do the PEAR package maintainers expect to release a new version every month???
 [2005-08-10 18:20 UTC] aidan
Hi there, I would not have marked the bug as No Feedback so early if I believed the bug had merit. I tested it against the problems you described, - no support for nested arrays above 2 levels -> clearly wrong - breaks hard on NULLS, BOOLEANS, FLOATS, RESOURCES -> mostly wrong. It was breaking on anything that wasn't an array. It handled the above types perfectly if they were in an array. I think you will find people get a little defensive when you say things like "so broken it's a joke". Anyway... I'll make some modifications and commit to cvs when I get a chance. Thanks for your improved function.
 [2005-11-22 06:25 UTC] aidan
This is fixed in CVS now, I also added support for classes, though I'm not sure how well it will work under php4. If you want to give it a go (I've also updated the test file), that'd be great. Thanks for your patience.
 [2005-11-23 08:32 UTC] giunta dot gaetano at sea-aeroportimilano dot it
Close, but no cigar :) 1 - For object variables, members of type array are not properly indented. You should probably use for object members the same explode, indent, implode code used for array values. 2 - But there is a small catch in the "explode, indent, implode" method: try running var_export(array(array("a\nb"))) to see a couple of extra chars added to the string dump. This is (imho) not only a cosmetic bug, but a data misrepresentation bug, ie a little bit more important. Afaict the only solution would be to adopt the code I proposed, with the extra 3rd param added to represent the current indentation level, or use a global var for that and have the code not be reentrant anymore.
 [2005-11-23 08:33 UTC] giunta dot gaetano at sea-aeroportimilano dot it
Close, but no cigar :) 1 - For object variables, members of type array are not properly indented. You should probably use for object members the same explode, indent, implode code used for array values. 2 - But there is a small catch in the "explode, indent, implode" method: try running var_export(array(array("a\nb"))) to see a couple of extra chars added to the string dump. This is (imho) not only a cosmetic bug, but a data misrepresentation bug, ie a little bit more important. Afaict the only solution would be to adopt the code I proposed, with the extra 3rd param added to represent the current indentation level, or use a global var for that and have the code not be reentrant anymore. PS: code runs fine on PHP 441
 [2005-12-05 06:30 UTC] aidan
Dammit! I'll have another go.
 [2005-12-05 09:29 UTC] aidan
Okay, I've had another crack. The changes are in the CVS: http://cvs.php.net/pear/PHP_Compat/Compat/Function/var_export.php Give it a thrashing, I've tested it with as many wacky cases as I could and it came through, but it's more than possible I missed something.