Debugging in PHP

Indice dei contenuti

add a note add a note

User Contributed Notes 12 notes

up
193
netyou
8 years ago
I find it very useful to print out to the browsers console instead of just var_dumping:

function console_log( $data ){
  echo '<script>';
  echo 'console.log('. json_encode( $data ) .')';
  echo '</script>';
}

Usage:
$myvar = array(1,2,3);
console_log( $myvar ); // [1,2,3]
up
15
metron19 at yandex dot ru
4 years ago
A good example of data output to the console via <script> tags, I myself used this first, but he broke the captcha job, because <script> tags were inserted into the base64 code of the captcha picture. Then I began to display logs in the headers with such a function (it may help someone else, in a similar situation):

<?php

function header_log($data){
 
$bt = debug_backtrace();
 
$caller = array_shift($bt);
 
$line = $caller['line'];
 
$file = array_pop(explode('/', $caller['file']));
 
header('log_'.$file.'_'.$caller['line'].': '.json_encode($data));
}

?>

Usage:
$myvar = array(1,2,3);
header_log( $myvar ); // in headers we see: log_filename_rownumber: [1,2,3]
up
8
shananpk95 at gmail dot com
4 years ago
I am using two ways to debug code

one is print the data and die the function in specific point.

     print_r($data);die;

second one is writing log file in specific point in code.

function write_log($log_msg)
{
    $log_filename = "logs";
    if (!file_exists($log_filename))
    {
        mkdir($log_filename, 0777, true);
    }
    $log_file_data = $log_filename.'/debug.log';
  file_put_contents($log_file_data, $log_msg . "\n", FILE_APPEND);
   
}

write_log("Writing Log");
$a = array(
        array('id' => '1','date' => '09-04-2018','length' => '10'),
        array('id' => '2','date' => '09-04-2018','length' => '20'),
        array('id' => '1','date' => '10-04-2018','length' => '11')
    );
write_log(print_r($a,1));
up
13
Anonymous
6 years ago
I would like to add http://phpdebugbar.com/ which is also a handy tool for debugging/profiling data. and you could use it whenever framework you are using. :-)
up
1
Fonstw
4 years ago
For me, just outputting variables only works when I know a method should be broken.

I use Xdebug in PHP Storm (available on other IDE's and editors as well)
It allows me to use line breaks and fully inspect anything that's set and how their values are changed and allows me to call single method even at (paused) runtime to see what behaviour the method really gives at any given point, which gives me a much better insight on how my code works and how to get it to work like it should.

I wholeheartedly recomend anyone to try a fuller-fledged debugger like that!
up
9
online _ use _ only == hotmail.com
18 years ago
I still find that printing out variable values at problem points in the code is one of the easiest ways for me to debug.  If you're interested in knowing the full contents of an object/array/scalar, then use

var_dump($var).
up
3
eric at derewonko dot com
6 years ago
None of the given examples here do fit my needs.
When I debug, I want to see clearly what's going on and where is the debug data. Also it has to accommodate with the current styles and not fall behind or get mixed with other text etc.
This snippet will give you real debug notices in a flashy table:
- complete backtrace of calls on the left with line numbers
- arguments content on the right, with the variable name and coloring per variable type

<?php
function wtf(){
 
error_reporting(E_ALL);
 
$args = func_get_args();
 
$backtrace = debug_backtrace();
 
$file = file($backtrace[0]['file']);
 
$src  = $file[$backtrace[0]['line']-1];  // select debug($varname) line where it has been called
 
$pat  = '#(.*)'.__FUNCTION__.' *?\( *?\$(.*) *?\)(.*)#i'// search pattern for wtf(parameter)
 
$arguments  = trim(preg_replace($pat, '$2', $src));  // extract arguments pattern
 
$args_arr = array_map('trim', explode(',', $arguments));

  print
'<style>
  div.debug {visible; clear: both; display: table; width: 100%; font-family: Courier,monospace; border: medium solid red; background-color: yellow; border-spacing: 5px; z-index: 999;}
  div.debug > div {display: unset; margin: 5px; border-spacing: 5px; padding: 5px;}
  div.debug .cell {display: inline-flex; padding: 5px; white-space: pre-wrap;}
  div.debug .left-cell {float: left; background-color: Violet;}
  div.debug .array {color: RebeccaPurple; background-color: Violet;}
  div.debug .object pre {color: DodgerBlue; background-color: PowderBlue;}
  div.debug .variable pre {color: RebeccaPurple; background-color: LightGoldenRodYellow;}
  div.debug pre {white-space: pre-wrap;}
  </style>'
.PHP_EOL;
  print
'<div class="debug">'.PHP_EOL;
  foreach (
$args as $key => $arg) {
    print
'<div><div class="left-cell cell"><b>';
   
array_walk(debug_backtrace(),create_function('$a,$b','print "{$a[\'function\']}()(".basename($a[\'file\']).":{$a[\'line\']})<br> ";'));
    print
'</b></div>'.PHP_EOL;
    if (
is_array($arg)) {
      print
'<div class="cell array"><b>'.$args_arr[$key].' = </b>';
     
print_r(htmlspecialchars(print_r($arg)), ENT_COMPAT, 'UTF-8');
      print
'</div>'.PHP_EOL;
    } elseif (
is_object($arg)) {
      print
'<div class="cell object"><pre><b>'.$args_arr[$key].' = </b>';
     
print_r(htmlspecialchars(print_r(var_dump($arg))), ENT_COMPAT, 'UTF-8');
      print
'</pre></div>'.PHP_EOL;
    } else {
      print
'<div class="cell variable"><pre><b>'.$args_arr[$key].' = </b>&gt;';
     
print_r(htmlspecialchars($arg, ENT_COMPAT, 'UTF-8').'&lt;');
      print
'</pre></div>'.PHP_EOL;
    }
    print
'</div>'.PHP_EOL;
  }
  print
'</div>'.PHP_EOL;
}
?>

Usage: wtf($arg1, $arg2,..);
That's it!
up
-5
rajendra at skydevelopers dot net
5 years ago
I also use a method to print complete data from www.skydevelopers.net company:

function dd($data) {
    echo '<pre>';
    print_r($data);
    exit;
}

well this is also very beneficial
up
-21
skatebiker at gmail dot com
9 years ago
p_r() is a function for logging variable values.

In this example the function p_r() does only log when the URL parameter d=<nonzero> is set. Reset it by d=0.
When  the parameter is a valid filename (relative to the script's path) it will be logged to that file rather than to the browser.

[code]
@session_start();
// debug
if (isset($_GET['d']))
{
  $_SESSION['d'] = $_GET['d'];
}

if (@$_SESSION['d']) {

function p_r($exp)
{
  $res = "";
  $trace = debug_backtrace();
  $level = 0;
  $e = error_reporting(E_ALL&~E_NOTICE);
  $file = strrpos($trace[$level]['file'], "/");
  $file = substr($trace[$level]['file'],$file+1);
  $line = date("H:i:s"). " " . $file . ' ' . $trace[$level]['line'] . ' ' . $trace[$level+1]['function'] . "()";
  $e = error_reporting($e);
  if (!is_string($exp)) $exp = var_export($exp,1);
  if (substr($_SESSION["d"],-4)==".log") {
    file_put_contents ($_SESSION["d"],$line . ": ". $exp . "\n",  FILE_APPEND);
  } else {
    $res = $line . "\n<pre>".htmlentities($exp). "</pre>\n";
    echo $res;
  }
  return $res;
}

    // refresh to prevent timeout
  $a = $_SESSION['d'];
  $_SESSION['d'] = $a;
  error_reporting (E_ALL);

} else {
  function  p_r() {}
}  // end if debug

[/code]
up
-2
Anonymous
3 years ago
I often rely on a Slack channel open that is solely dedicated to debug output in whatever project I'm working on. Then I use a PHP function called debug($obj) that takes $obj and uses the Slack API to post a message with that value to that channel. It's helped me immensely and hopefully it would help others too.
up
-10
tekintian at gmail dot com
4 years ago
<?php
/**
* 测试打印方法
* @FileName: test_helper.php
* @Author: TekinTian
* @QQ: 3316872019
* @Email: tekintian@gmail.com
* @Supported: http://dev.yunnan.ws/
* @Date:   2017-01-23 11:45:26
* @Last Modified 2019-03-04
*/

if (!function_exists('dd')) {
   
/**
     * 测试打印函数
     * @param  [type] $arr [description]
     * @return [type]      [description]
     */
   
function dd($arr) {
        if (
is_array($arr)) {
            echo
"<pre>";
           
print_r($arr);
            echo
"</pre>";
        } else if (
is_object($arr)) {
            echo
"<pre>";
           
print_r($arr);
            echo
"</pre>";

        } else {
            echo
$arr;
        }
        die;
    }
}

if (!
function_exists('pp')) {
   
/**
     * 格式化输出
     * @param  [type] $arr [description]
     * @return [type]      [description]
     */
   
function pp($arr) {
        if (
is_array($arr)) {
            echo
"<pre>";
           
print_r($arr);
            echo
"</pre>";
        } else if (
is_object($arr)) {
            echo
"<pre>";
           
print_r($arr);
            echo
"</pre>";

        } else {
            echo
$arr;
        }
        die;
    }
}

if (!
function_exists('pr')) {
   
/**
     * 打印不中断
     */
   
function pr($arr) {
        if (
is_array($arr)) {
            echo
"<pre>";
           
print_r($arr);
            echo
"</pre>";
        } else if (
is_object($arr)) {
            echo
"<pre>";
           
print_r($arr);
            echo
"</pre>";

        } else {
            echo
$arr;
        }
    }
}

if (!
function_exists('vd')) {
   
/**
     * 测试打印函数
     * @param  [type] $arr [description]
     * @return [type]      [description]
     */
   
function vd($arr) {
        echo
"<pre>";
       
var_dump($arr);
        echo
"</pre>";
        die;
    }
}

if (!
function_exists('vv')) {
    function
vv($arr) {
        echo
"<pre>";
       
var_dump($arr);
        echo
"</pre>";
    }
}

if (!
function_exists('console_log')) {
   
/**
     * console.log控制台调试函数
     * @param  [type] $data [要在控制台输出的数据 支持数组、对象和字符串]
     * @return [type]       [description]
     */
   
function console_log($data) {
        if (
is_array($data) || is_object($data)) {
            echo (
"<script>console.log('" . json_encode($data) . "');</script>");
        } else {
            echo (
"<script>console.log('" . $data . "');</script>");
        }
    }
}

/**
* 浏览器友好的变量输出,便于调试时候使用
*
* @param     mixed   $var       要输出查看的内容
* @param     bool    $echo      是否直接输出
* @param     string  $label     加上说明标签,如果有,这显示"标签名:"这种形式
* @param     bool    $strict    是否严格过滤
* @return    string
*/
if (!function_exists('dump')) {
    function
dump($var, $echo = true, $label = null, $strict = true) {
       
$label = ($label === null) ? '' : rtrim($label) . ' ';
        if (!
$strict) {
            if (
ini_get('html_errors')) {
               
$output = print_r($var, true);
               
$output = "<pre>" . $label . htmlspecialchars($output, ENT_QUOTES) . "</pre>";
            } else {
               
$output = $label . " : " . print_r($var, true);
            }
        } else {
           
ob_start();
           
var_dump($var);
           
$output = ob_get_clean();
            if (!
extension_loaded('xdebug')) {
               
$output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output);
               
$output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            }
        }
        if (
$echo) {
            echo (
$output);
            return
null;
        } else {
            return
$output;
        }

    }
}
up
-20
Bladimir
6 years ago
Following example above using variable-lenght arguments to support similar Web API's console.log implementation

<?php
function console_log( ...$messages ){
 
$msgs = '';
  foreach (
$messages as $msg) {
   
$msgs .= json_encode($msg);
  }

  echo
'<script>';
  echo
'console.log('. json_encode($msgs) .')';
  echo
'</script>';
}

?>
To Top