making print_r use PHP_EOL

北城余情 提交于 2019-12-01 20:33:41

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;

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.

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
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!