making print_r use PHP_EOL

前端 未结 5 837
逝去的感伤
逝去的感伤 2021-01-13 23:42

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

相关标签:
5条回答
  • 2021-01-14 00:24

    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];
    
    0 讨论(0)
  • 2021-01-14 00:29

    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>";
    
    0 讨论(0)
  • 2021-01-14 00:31

    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.

    0 讨论(0)
  • 2021-01-14 00:38

    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;
    
    0 讨论(0)
  • 2021-01-14 00:39

    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
    
    0 讨论(0)
提交回复
热议问题