使print_r使用PHP_EOL

时间:2014-07-09 20:51:38

标签: php eol

我的PHP_EOL是“\ r \ n”,但是,当我对数组执行print_r时,每个新行都有一个“\ n” - 而不是“\ r \ n” - 放在它后面。< / p>

知道是否可以改变这种行为?

5 个答案:

答案 0 :(得分:4)

如果你查看print_r的源代码,你会发现:

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;
    }
}

最终你可以忽略问题zend_print_zval_r(var, 0 TSRMLS_CC);的问题。

如果你关注堆栈跟踪,你会发现:

ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC) /* {{{ */
{
    zend_print_zval_r_ex(zend_write, expr, indent TSRMLS_CC);
}

导致

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;

从现在开始,你可以继续找到相关的行 - 但由于已经有一个硬编码的"Array\n" - 我假设print_r实现的其余部分使用相同的硬编码\n linebreak-thing。

因此,要回答您的问题:您无法将其更改为使用\r\n。 使用提供的解决方法之一。

Sidenode:由于print_r主要用于调试,因此也可以完成这项工作:

echo "<pre>";
print_r($object);
echo "</pre>";

答案 1 :(得分:3)

print_r中使用第二个参数(设置true),阅读DOC: http://www.php.net/manual/en/function.print-r.php

请参阅: mixed print_r ( mixed $expression [, bool $return = false ] );

示例:

$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;

答案 2 :(得分:1)

就像本页其他地方所指出的那样,新行在PHP源代码中是硬编码的,所以你必须手动替换它们。

您可以像这样使用自己的print_r版本:

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;
}

每当您想要使用它时,只需使用

导入它
// 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");

然后,这将使用PHP_EOL作为换行符。请注意,它只会替换换行符,例如\n,但不是\r\n中可能包含的任何$expression。这是为了防止任何\r\n成为\r\r\n

这样做的好处是它可以作为原生函数的替代品。因此,只需添加use语句即可替换已使用本机print_r的任何代码。

答案 3 :(得分:0)

这可能不是最优雅的解决方案,但您可以使用缓冲区输出捕获print_r()输出,然后使用str_replace()\n的存在替换为PHP_EOL 。在这个例子中,我用x替换它以表明它正在工作......

ob_start();

$test_array = range('A', 'Z');
print_r($test_array);

$dump = ob_get_contents();
ob_end_clean();

正如dognose所指出的那样,从PHP 4.3开始,你可以将print_r()的结果返回到字符串中(更优雅):

$dump = print_r($test_array, true);

然后替换行结尾:

$dump = str_replace("\n", "x" . PHP_EOL, $dump);
echo $dump;

输出:

Arrayx
(x
    [0] => Ax
    [1] => Bx
    [2] => Cx
    [3] => Dx
    [4] => Ex
    [5] => Fx
    [6] => Gx
    ... etc
    [25] => Zx
)x

答案 4 :(得分:0)

问题Is it possible to change the behavior of PHP's print_r function被标记为与此重复的问题。我想回答更多如何改变print_r的行为。我的建议是使用另一个名称进行另一个功能,该功能由print_r自定义。我们只需要用print_r_pretty替换print_r函数...

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;
    }
  }

但行:

$out = str_replace("\n", "\r\n", $out);

可以用另一行替换,这样可以对print_r进行另一次更改:

$out = explode("\n", $out, 2)[1];