My PHP_EOL is \"\\r\\n\", however, when I do print_r
on an array each new line has a \"\\n\" - not a \"\\r\\n\" - placed after it.
Any idea if it\'s pos
Question Is it possible to change the behavior of PHP's print_r function was marked was duplicated of this one . I'd like to answer more how is possible change the behavior of print_r. My propose is do another function with another name that do the print_r customized . And we just need replace print_r functions with print_r_pretty ...
function print_r_pretty($in, $saveToString = false) {
$out = print_r($in, true);
$out = str_replace("\n", "\r\n", $out);
switch ($saveToString) {
case true: return $out;
default: echo $out;
}
}
But line :
$out = str_replace("\n", "\r\n", $out);
can be replaced by another line that do another changes to print_r like this :
$out = explode("\n", $out, 2)[1];
If you look the source code of print_r
you'll find:
PHP_FUNCTION(print_r)
{
zval *var;
zend_bool do_return = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &do_return) == FAILURE) {
RETURN_FALSE;
}
if (do_return) {
php_output_start_default(TSRMLS_C);
}
zend_print_zval_r(var, 0 TSRMLS_CC);
if (do_return) {
php_output_get_contents(return_value TSRMLS_CC);
php_output_discard(TSRMLS_C);
} else {
RETURN_TRUE;
}
}
ultimately you can ignore the stuff arround zend_print_zval_r(var, 0 TSRMLS_CC);
for your question.
If you follow the stacktrace, you'll find:
ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC) /* {{{ */
{
zend_print_zval_r_ex(zend_write, expr, indent TSRMLS_CC);
}
which leads to
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC) /* {{{ */
{
switch (Z_TYPE_P(expr)) {
case IS_ARRAY:
ZEND_PUTS_EX("Array\n");
if (++Z_ARRVAL_P(expr)->nApplyCount>1) {
ZEND_PUTS_EX(" *RECURSION*");
Z_ARRVAL_P(expr)->nApplyCount--;
return;
}
print_hash(write_func, Z_ARRVAL_P(expr), indent, 0 TSRMLS_CC);
Z_ARRVAL_P(expr)->nApplyCount--;
break;
From this point on, you could continue to find the relevant line - but since there is already a hardcoded "Array\n"
- i'll assume the rest of the print_r
implementation uses the same hardcoded \n
linebreak-thing.
So, to answer your question: You cannot change it to use \r\n
.
Use one of the provided workarounds.
Sidenode: Since print_r
is mainly used for debugging, this will do the job as well:
echo "<pre>";
print_r($object);
echo "</pre>";
Like pointed out elsewhere on this page, the newlines are hardcoded in the PHP source, so you have to replace them manually.
You could use your own version of print_r
like this:
namespace My;
function print_r($expression, $return = false)
{
$out = \print_r($expression, true);
$out = \preg_replace("#(?<!\r)\n#", PHP_EOL, $out);
if ($return) {
return $out;
}
echo $out;
return true;
}
Whenever you want to use it, you just import it with
// aliasing a function (PHP 5.6+)
use My\print_r as print_r;
print_r("A string with \r\n is not replaced");
print_r("A string with \n is replaced");
This will then use PHP_EOL
for newlines. Note that it will only substitute newlines, e.g. \n
, but not any \r\n
you might have in the $expression
. This is to prevent any \r\n
to become \r\r\n
.
The benefit of doing it this way is that it will work as a drop-in replacement of the native function. So any code that already uses the native print_r
can be replaced simply by adding the use statement.
Use second param in print_r
(set true
), read DOC:
http://www.php.net/manual/en/function.print-r.php
See:
mixed print_r ( mixed $expression [, bool $return = false ] )
;
Example:
$eol = chr(10); //Break line in like unix
$weol = chr(13) . $eol; //Break line with "carriage return" (required by some text editors)
$data = print_r(array(...), true);
$data = str_replace(eol, weol, $data);
echo $data;
This may not be the most elegant solution, but you could capture the print_r()
output using buffer output, then use str_replace()
to replace existences of \n
with your PHP_EOL
. In this example I've replaced it with x
to show that it's working...
ob_start();
$test_array = range('A', 'Z');
print_r($test_array);
$dump = ob_get_contents();
ob_end_clean();
As pointed out by dognose, since PHP 4.3 you can return the result of print_r()
into a string (more elegant):
$dump = print_r($test_array, true);
Then replace line endings:
$dump = str_replace("\n", "x" . PHP_EOL, $dump);
echo $dump;
Output:
Arrayx
(x
[0] => Ax
[1] => Bx
[2] => Cx
[3] => Dx
[4] => Ex
[5] => Fx
[6] => Gx
... etc
[25] => Zx
)x