laravel 核心代码调试起来,还是挺麻烦的,循环太多了。当从某个路由进去之后,进入到核心内部,断点打印的可能根据不是你认为的执行过程。为此,我想到了条件打印,跟用 ide debug 设置条件一样的思想。不过还是觉得打印更加直观一些吧。
代码很简单,一看就懂,不过多介绍了。
<?php
class debuger {
protected $conditions = [];
protected $file = '';
public function __construct($value1 = true, $value2 = true)
{
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, );
$this->file = str_replace(__DIR__ . DIRECTORY_SEPARATOR, '', $trace[1]['file']) .':'. $trace[1]['line'];
$this->log = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'debug.txt';
if(!isset($_ENV['debug_next_step'])){
$_ENV['debug_next_step'] = 0;
}
if(func_num_args() == 1){
$this->if($value1);
}else{
$this->eq($value1, $value2);
}
}
public function dump(mixed ...$values)
{
ob_start();
dump(...$values);
echo preg_replace('/\/\/\s+helpers.php:\d+/', "// $this->file", ob_get_clean());
return $this;
}
public function stop(mixed ...$values)
{
$this->dump(...$values);
exit(1);
}
public function dd(mixed ...$values)
{
if($this->allIsTrue()){
dd(...$values);
}
}
public function du(mixed ...$values)
{
if(!$this->allIsTrue()) return $this;
$this->dump(...$values);
return $this;
}
public function if(mixed $value = true)
{
$this->conditions[] = boolval($value);
return $this;
}
public function var(mixed ...$values)
{
if($this->allIsTrue()){
var_dump(...$values);
}
return $this;
}
public function eq($value1 = true, $value2 = true, $strict = false)
{
if($strict){
$this->conditions[] = $value1 === $value2;
}else{
$this->conditions[] = $value1 == $value2;
}
return $this;
}
public function empty($value = false)
{
$this->conditions[] = empty($value);
return $this;
}
public function full($value = true)
{
$this->conditions[] = !empty($value);
return $this;
}
public function compare($value1, $symbol, $value2 = null)
{
if(func_num_args() == 2){
$value2 = $symbol;
$symbol = '=';
}
$this->conditions[] = eval("$value1 $symbol $value2");
return $this;
}
public function true($value, $strict = false)
{
if($strict){
$this->conditions[] = $value === true;
}else{
$this->conditions[] = $value == true;
}
return $this;
}
public function false($value, $strict = false)
{
if($strict){
$this->conditions[] = $value === false;
}else{
$this->conditions[] = $value == false;
}
return $this;
}
public function null($value = null)
{
$this->conditions[] = is_null($value);
return $this;
}
protected function allIsTrue()
{
return count($this->conditions) == count(array_filter($this->conditions));
}
public function exec($callback = null, ...$args)
{
if($this->allIsTrue()){
if(is_callable($callback)){
call_user_func($callback, ...$args);
}else{
$this->dd('$callback is not callable');
}
}
return $this;
}
public function dir($value)
{
$this->conditions[] = is_dir($value);
return $this;
}
public function next(int $value = 0)
{
if($this->allIsTrue()){
$_ENV['debug_next_step'] = $value;
}
return $this;
}
public function prev(int $value = 0)
{
$this->conditions[] = $value == $_ENV['debug_next_step'];
return $this;
}
public function here(string $value = '== debug here ==')
{
dd($value);
}
public function return($value, $default = null)
{
return $this->allIsTrue()? $value : $default;
}
public function trace()
{
if($this->allIsTrue()){
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$trace = array_reverse($trace);
$html = '<table style="border-collapse:collapse;width: 100%;" >';
foreach($trace as $key => $item){
!isset($item['class']) && $item['class'] = '';
!isset($item['type']) && $item['type'] = '';
!isset($item['function']) && $item['function'] = '';
$item['file'] = str_replace([__DIR__ . '/', 'vendor/', 'laravel/framework/src/', 'laravel/', '/'], ['', '', '', '', '\\'], $item['file']);
$html .= "<tr><td style='border:1px solid #DDD;padding:4px;'>$key</td><td style='border:1px solid #DDD;padding:4px;'><td style='border:1px solid #DDD;padding:4px 30px 4px 4px;width:0px;'>{$item['file']}:{$item['line']}</td><td style='border:1px solid #DDD;padding:4px;'>{$item['class']}{$item['type']}{$item['function']}()</td></tr>";
}
$html .= '</table>';
echo $html;
}
return $this;
}
public function exit()
{
if($this->allIsTrue()) exit(1);
}
public static function unicode($string)
{
return preg_replace_callback('/\\\\u([0-9a-f]{4})/i', function($match) {
return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
}, $string);
}
public function format(mixed ...$args)
{
$cli = PHP_SAPI == 'cli' ? true : false;
$content = $cli ? $this->file . PHP_EOL : '<pre style="margin-bottom:5px;background:#f3f3f4;padding:5px;border:1px solid #DDD;">文件: ' . $this->file . PHP_EOL . '<hr/>';
foreach($args as $key => $data) {
$append = [];
if(is_bool($data)) {
$content .= ($data ? '(bool) true' : '(bool) false') . PHP_EOL;
}else if(is_null($data)) {
$content .= '(null) null' . PHP_EOL;
}else if($data === '') {
$content .= '""' . PHP_EOL;
}else if(is_array($data)){
$content .= print_r($data, true);
}else if(is_scalar($data) && !function_exists($data) && !class_exists($data, false)){
$content .= self::unicode($data) . PHP_EOL;
}
if(is_string($data) && function_exists($data)){
$object = new \ReflectionFunction($data);
$content .= print_r(['Type' => 'Function', 'Name' => $data, 'Namespace' => $object->getNamespaceName(), 'File' => $object->getFilename()], true);
}
if(is_object($data) || (is_string($data) && class_exists($data, false))) {
$message = '';
if(is_object($data)) {
if($data instanceof \Exception) {
$file = $data->getFile() . ':' . $data->getLine();
$message = $data->getMessage() . ' (' . $data->getCode() . ')';
}else if($data instanceof \think\Model || (is_array($data) && current($data) instanceof \think\Model)){
$append['Collect'] = collection($data)->toArray();
}else if(method_exists($data, 'toArray')) {
$append['ToArray'] = $data->toArray();
}else if(method_exists($data, '__toString')) {
$append['ToString'] = $data->__toString();
}
$name = get_class($data);
$fields = get_object_vars($data);
}else {
$name = $data;
$fields = get_class_vars($data);
}
$methods = get_class_methods($data);
$object = new \ReflectionClass($data);
if(!isset($file)) {
$file = $object->getFilename();
}
$content .= print_r(array('Type' => (is_object($data)? 'Object' : 'Class'), (is_object($data)? 'Class' : 'Name') => $name, 'Namespace' => $object->getNamespaceName(), 'Exception' => $message, 'File' => $file, 'Attribute ' => $fields, 'Data' => $append, 'Method' => $methods), true);
}
if(array_key_exists($key + 1, $args)) {
$content .= $cli ? PHP_EOL . '----------------------------------------------------------------------------------' . PHP_EOL : '<hr/>';
}
}
$content .= $cli ? PHP_EOL : '</pre>';
return $content;
}
}
// ================================================================================================
// 为了方便,定义一个函数,之所以叫 ifif 是为了搜索时好找
function ifif($value1 = true, $value2 = true)
{
if(func_num_args() == 0){
return new \debuger();
}else if(func_num_args() == 1){
return new \debuger($value1);
}else{
return new \debuger($value1, $value2);
}
}
标签:function,return,打印输出,conditions,value,php,data,public,调试 From: https://www.cnblogs.com/zbseoag/p/17526758.html