PEAR is discontinued

This is a static archive preserving historical releases and metadata. No new packages or updates will be published. For updates to existing packages, or to publish new packages, please use Composer and Packagist.

Home » PHP » PHP_Compat » Bug #4851

var_export severely broken! (new implementation attached)

Details

Submitted2005-07-18 12:47 UTC
Fromgiunta dot gaetano at sea-aeroportimilano dot it
Assignedaidan
StatusClosed
PackagePHP_Compat
PHP Version4.0.4
OSirrelevant
Roadmaps1.6.0a1

Comments

[2005-07-18 12: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;
}
}
}
?>

[2005-08-10 12: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-11-23 13: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 13: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