Jadual Kandungan
PHP debug_backtrace的胡思乱想,phpdebugbacktrace
简述
实战
实现魔术函数 
获取当前函数或方法的名称 
加载相对路径文件
管理文件调用权限
debug_backtrace的'BUG'
使用反射
总结
Rumah pembangunan bahagian belakang tutorial php PHP debug_backtrace的胡思乱想,phpdebugbacktrace_PHP教程

PHP debug_backtrace的胡思乱想,phpdebugbacktrace_PHP教程

Jul 12, 2016 am 08:51 AM
debug

PHP debug_backtrace的胡思乱想,phpdebugbacktrace

本文示例代码测试环境是Windows下的APMServ(PHP5.2.6)

 

简述

可能大家都知道,php中有一个函数叫debug_backtrace,它可以回溯跟踪函数的调用信息,可以说是一个调试利器。

好,来复习一下。

复制代码
<span>one();

</span><span>function</span><span> one() {
    two();
}

</span><span>function</span><span> two() {
    three();
}

</span><span>function</span><span> three() {
    </span><span>print_r</span>( <span>debug_backtrace</span><span>() );
}

</span><span>/*</span><span>
输出:
Array
(
    [0] => Array
        (
            [file] => D:\apmserv\www\htdocs\test\debug\index.php
            [line] => 10
            [function] => three
            [args] => Array
                (
                )

        )

    [1] => Array
        (
            [file] => D:\apmserv\www\htdocs\test\debug\index.php
            [line] => 6
            [function] => two
            [args] => Array
                (
                )

        )

    [2] => Array
        (
            [file] => D:\apmserv\www\htdocs\test\debug\index.php
            [line] => 3
            [function] => one
            [args] => Array
                (
                )

        )

)
</span><span>*/</span>
Salin selepas log masuk
复制代码

顺便提一下类似的函数:debug_print_backtrace,与之不同的是它会直接打印回溯信息。

回来看debug_backtrace,从名字来看用途很明确,是让开发者用来调试的。直到有一天我注意到它返回的file参数,file表示函数或者方法的调用脚本来源(在哪个脚本文件使用的)。忽然我想到,如果当前脚本知道调用来源,那是否可以根据这个来源的不同,来实现一些有趣的功能,比如文件权限管理、动态加载等。

实战

实现魔术函数

获取当前函数或方法的名称

尽管PHP中已经有了__FUNCTION____METHOD__魔术常量,但我还是想介绍一下用debug_backtrace获取当前函数或者方法名称的方法。

代码如下:

复制代码
<span>//</span><span>函数外部输出getFuncName的值</span>
<span>echo</span><span> getFuncName();

printFuncName();

</span><span>Object</span>::<span>printMethodName();

</span><span>//</span><span>调用了上面两个函数后,再次在外部输出getFuncName,看看是否有&lsquo;缓存&rsquo;之类的问题</span>
<span>echo</span><span> getFuncName();



</span><span>function</span><span> printFuncName() {
    </span><span>echo</span><span> getFuncName();
}

</span><span>class</span> <span>Object</span><span> {
    </span><span>static</span> <span>function</span><span> printMethodName() {
        </span><span>echo</span><span> getFuncName();
    }
}

</span><span>/*</span><span>*
 * 获取当前函数或者方法的名称
 * 函数名叫getFuncName,好吧,其实method也可以当做function,实在想不出好名字
 * 
 * @return string name
 </span><span>*/</span>
<span>function</span><span> getFuncName() {
    </span><span>$debug_backtrace</span> = <span>debug_backtrace</span><span>();
    </span><span>//</span><span>如果函数名是以下几个,表示载入了脚本,并在函数外部调用了getFuncName
    //这种情况应该返回空</span>
    <span>$ignore</span> = <span>array</span><span>(
        </span>'include',
        'include_once',
        'require',
        'require_once'<span>
    );
    </span><span>//</span><span>第一个backtrace就是当前函数getFuncName,再上一个(第二个)backtrace就是调用getFuncName的函数了</span>
    <span>$handle_func</span> = <span>$debug_backtrace</span>[1<span>];
    </span><span>if</span>( <span>isset</span>( <span>$handle_func</span>['function'] ) && !<span>in_array</span>( <span>$handle_func</span>['function'], <span>$ignore</span><span> ) ) {
        </span><span>return</span> <span>$handle_func</span>['function'<span>];
    }
    </span><span>return</span> <span>null</span><span>;
}


</span><span>//</span><span>输出:
//null
//printFuncName
//printMethodName
//null</span>
Salin selepas log masuk
复制代码

看上去没有问题,很好。

加载相对路径文件

如果在项目中要加载相对路径的文件,必需使用include或者require之类的原生方法,但现在有了debug_backtrace,我可以使用自定义函数去加载相对路径文件。

新建一个项目,目录结构如下:

我想在index.php中调用自定义函数,并使用相对路径去载入package/package.php,并且在package.php中使用同样的方法载入_inc_func.php

三个文件的代码如下(留意index.phppackage.php调用import函数的代码):

index.php:

复制代码
<?<span>php

import( </span>'./package/package.php'<span> );

</span><span>/*</span><span>*
 * 加载当前项目下的文件
 * 
 * @param string $path 相对文件路径
 </span><span>*/</span>
<span>function</span> import( <span>$path</span><span> ) {
    </span><span>//</span><span>获得backstrace列表</span>
    <span>$debug_backtrace</span> = <span>debug_backtrace</span><span>();
    </span><span>//</span><span>第一个backstrace就是调用import的来源脚本</span>
    <span>$source</span> = <span>$debug_backtrace</span>[0<span>];

    </span><span>//</span><span>得到调用源的目录路径,和文件路径结合,就可以算出完整路径</span>
    <span>$source_dir</span> = <span>dirname</span>( <span>$source</span>['file'<span>] );
    </span><span>require</span> <span>realpath</span>( <span>$source_dir</span> . '/' . <span>$path</span><span> );
}

</span>?>
Salin selepas log masuk
复制代码

package.php:

复制代码
<?<span>php

</span><span>echo</span> 'package'<span>;

import( </span>'./_inc_func.php'<span> );

</span>?>
Salin selepas log masuk
复制代码

_inc_func.php:

<?<span>php

</span><span>echo</span> '_inc_func'<span>;

</span>?>
Salin selepas log masuk

运行index.php

<span>//</span><span>输出:
//package
//_inc_func</span>
Salin selepas log masuk

可以看到,我成功了。

思考:这个方法我觉得非常强大,除了相对路径之外,可以根据这个思路引伸出相对包、相对模块之类的抽象特性,对于一些项目来说可以增强模块化的作用。

管理文件调用权限

我约定一个规范:文件名前带下划线的只能被当前目录的文件调用,也就是说这种文件属于当前目录‘私有’,其它目录的文件不允许载入它们。

这样做的目的很明确:为了降低代码耦合性。在项目中,很多时候一些文件只被用在特定的脚本中。但是经常发生的事情是:一些程序员发现这些脚本有自己需要用到的函数或者类,因此直接载入它来达到自己的目的。这样的做法很不好,原本这些脚本编写的目的仅仅为了辅助某些接口实现,它们并没有考虑到其它通用性。万一接口内部需要重构,同样需要改动这些特定的脚本文件,但是改动后一些看似与这个接口无关脚本却突然无法运行了。一经检查,却发现文件的引用错综复杂。

规范只是监督作用,不排除有人为了一己私欲而违反这个规范,或者无意中违反了。最好的方法是落实到代码中,让程序自动去检测这种情况。

新建一个项目,目录结构如下。

那么对于这个项目来说,_inc_func.php属于package目录的私有文件,只有package.php可以载入它,而index.php则没有这个权限。

package目录是一个包,package.php下提供了这个包的接口,同时_inc_func.phppackage.php需要用到的一些函数。index.php将会使用这个包的接口文件,也就是package.php

它们的代码如下

index.php:

复制代码
<?<span>php

</span><span>header</span>("Content-type: text/html; charset=utf-8"<span>);

</span><span>//</span><span>定义项目根目录</span>
<span>define</span>( 'APP_PATH', <span>dirname</span>( <span>__FILE__</span><span> ) );

import( APP_PATH </span>. '/package/package.php'<span> );
</span><span>//</span><span>输出包的信息</span>
<span>Package_printInfo();

</span><span>/*</span><span>*
 * 加载当前项目下的文件
 * 
 * @param string $path 文件路径
 </span><span>*/</span>
<span>function</span> import( <span>$path</span><span> ) {
    
    </span><span>//</span><span>应该检查路径的合法性</span>
    <span>$real_path</span> = <span>realpath</span>( <span>$path</span><span> );
    </span><span>$in_app</span> = ( <span>stripos</span>( <span>$real_path</span>, APP_PATH ) === 0<span> );
    </span><span>if</span>( <span>empty</span>( <span>$real_path</span> ) || !<span>$in_app</span><span> ) {
        </span><span>throw</span> <span>new</span> <span>Exception</span>( '文件路径不存在或不被允许'<span> );
    }
    
    </span><span>include</span> <span>$real_path</span><span>;
}

</span>?>
Salin selepas log masuk
复制代码

_inc_func.php:

复制代码
<?<span>php

</span><span>function</span> _Package_PrintStr( <span>$string</span><span> ) {
    </span><span>echo</span> <span>$string</span><span>;
}

</span>?>
Salin selepas log masuk
复制代码

package.php:

复制代码
<?<span>php

</span><span>define</span>( 'PACKAGE_PATH', <span>dirname</span>( <span>__FILE__</span><span> ) );

</span><span>//</span><span>引入私有文件</span>
import( PACKAGE_PATH . '/_inc_func.php'<span> );

</span><span>function</span><span> Package_printInfo() {
    _Package_PrintStr( </span>'我是一个包。'<span> );
}

</span>?>
Salin selepas log masuk
复制代码

运行index.php:

<span>//</span><span>输出:
//我是一个包。</span>
Salin selepas log masuk

整个项目使用了import函数载入文件,并且代码看起来是正常的。但是我可以在index.php中载入package/_inc_func.php文件,并调用它的方法。

index.php中更改import( APP_PATH . '/package/package.php' );处的代码,并运行:

复制代码
import( APP_PATH . '/package/_inc_func.php'<span> );

_Package_PrintStr( </span>'我载入了/package/_inc_func.php脚本'<span> );

</span><span>//</span><span>输出:
//我载入了/package/_inc_func.php脚本</span>
Salin selepas log masuk
复制代码

那么,这时可以使用debug_backtrace检查载入_inc_func.php文件的路径来自哪里,我改动了index.php中的import函数,完整代码如下:

复制代码
<span>/*</span><span>*
 * 加载当前项目下的文件
 * 
 * @param string $path 文件路径
 </span><span>*/</span>
<span>function</span> import( <span>$path</span><span> ) {
    
    </span><span>//</span><span>首先应该检查路径的合法性</span>
    <span>$real_path</span> = <span>realpath</span>( <span>$path</span><span> );
    </span><span>$in_app</span> = ( <span>stripos</span>( <span>$real_path</span>, APP_PATH ) === 0<span> );
    </span><span>if</span>( <span>empty</span>( <span>$real_path</span> ) || !<span>$in_app</span><span> ) {
        </span><span>throw</span> <span>new</span> <span>Exception</span>( '文件路径不存在或不被允许'<span> );
    }
    
    </span><span>$path_info</span> = <span>pathinfo</span>( <span>$real_path</span><span> );
    </span><span>//</span><span>判断文件是否属于私有</span>
    <span>$is_private</span> = ( <span>substr</span>( <span>$path_info</span>['basename'], 0, 1 ) === '_'<span> );
    </span><span>if</span>( <span>$is_private</span><span> ) {
        </span><span>//</span><span>获得backstrace列表</span>
        <span>$debug_backtrace</span> = <span>debug_backtrace</span><span>();
        </span><span>//</span><span>第一个backstrace就是调用import的来源脚本</span>
        <span>$source</span> = <span>$debug_backtrace</span>[0<span>];
        
        </span><span>//</span><span>得到调用源路径,用它来和目标路径进行比较</span>
        <span>$source_dir</span> = <span>dirname</span>( <span>$source</span>['file'<span>] );
        </span><span>$target_dir</span> = <span>$path_info</span>['dirname'<span>];
        </span><span>//</span><span>不在同一目录下时抛出异常</span>
        <span>if</span>( <span>$source_dir</span> !== <span>$target_dir</span><span> ) {
            </span><span>$relative_source_file</span> = <span>str_replace</span>( APP_PATH, '', <span>$source</span>['file'<span>] );
            </span><span>$relative_target_file</span> = <span>str_replace</span>( APP_PATH, '', <span>$real_path</span><span> );
            </span><span>$error</span> = <span>$relative_target_file</span> . '文件属于私有文件,' . <span>$relative_source_file</span> . '不能载入它。'<span>;
            </span><span>throw</span> <span>new</span> <span>Exception</span>( <span>$error</span><span> );
        }
    }
    
    </span><span>include</span> <span>$real_path</span><span>;
}</span>
Salin selepas log masuk
复制代码

这时再运行index.php,将产生一个致命错误:

<span>//</span><span>输出:
//致命错误:/package/_inc_func.php文件属于私有文件,/index.php不能载入它。</span>
Salin selepas log masuk

而载入package.php则没有问题,这里不进行演示。

可以看到,我当初的想法成功了。尽管这样,在载入package.php后,其实在index.php中仍然还可以调用_inc_func.php的函数(package.php载入了它)。因为除了匿名函数,其它函数是全局可见的,包括类。不过这样或多或少可以让程序员警觉起来。关键还是看程序员本身,再好的规范和约束也抵挡不住烂程序员,他们总是会比你‘聪明’。

debug_backtrace的'BUG'

如果使用call_user_func或者call_user_func_array调用其它函数,它们调用的函数里面使用debug_backtrace,将获取不到路径的信息。

例:

复制代码
<span>call_user_func</span>('import'<span>);

</span><span>function</span><span> import() {
    </span><span>print_r</span>( <span>debug_backtrace</span><span>() );
}


</span><span>/*</span><span>
输出:
Array
(
    [0] => Array
        (
            [function] => import
            [args] => Array
                (
                )

        )

    [1] => Array
        (
            [file] => F:\www\test\test\index.php
            [line] => 3
            [function] => call_user_func
            [args] => Array
                (
                    [0] => import
                )

        )

)
</span><span>*/</span>
Salin selepas log masuk
复制代码

注意输出的第一个backtrace,它的调用源路径file没有了,这样一来我之前的几个例子将会产生问题。当然可能你注意到第二个backtrace,如果第一个没有就往回找。但经过实践是不可行的,之前我就碰到这种情况,同样会有问题,但是现在无法找回那时的代码了,如果你发现,请将问题告诉我。就目前来说,最好不要使用这种方法,我有一个更好的解决办法,就是使用PHP的反射API。

使用反射

使用反射API可以知道函数很详细的信息,当然包括它声明的文件和所处行数

复制代码
<span>call_user_func</span>('import'<span>);

</span><span>function</span><span> import() {
    </span><span>$debug_backtrace</span> = <span>debug_backtrace</span><span>();
    </span><span>$backtrace</span> = <span>$debug_backtrace</span>[0<span>];
    </span><span>if</span>( !<span>isset</span>( <span>$backtrace</span>['file'<span>] ) ) {
        </span><span>//</span><span>使用反射API获取函数声明的文件和行数</span>
        <span>$reflection_function</span> = <span>new</span> ReflectionFunction( <span>$backtrace</span>['function'<span>] );
        </span><span>$backtrace</span>['file'] = <span>$reflection_function</span>-><span>getFileName();
        </span><span>$backtrace</span>['line'] = <span>$reflection_function</span>-><span>getStartLine();
    }
    </span><span>print_r</span>(<span>$backtrace</span><span>);
}

</span><span>/*</span><span>
输出:
Array
(
    [function] => import
    [args] => Array
        (
        )

    [file] => F:\www\test\test\index.php
    [line] => 5
) 
</span><span>*/</span>
Salin selepas log masuk
复制代码

 

可以看到通过使用反射接口ReflectionMethod的方法file又回来了。

类方法的反射接口是ReflectionMethod,获取声明方法同样是getFileName

 

 

总结

在一个项目中,我通常不会直接使用include或者require载入脚本。我喜欢把它们封装到一个函数里,需要载入脚本的时候调用这个函数。这样可以在函数里做一些判断,比如说是否引入过这个文件,或者增加一些调用规则等,维护起来比较方便。

幸好有了这样的习惯,所以我可以马上把debug_backtrace的一些想法应用到整个项目中。

总体来说debug_backtrace有很好的灵活性,只要稍加利用,可以实现一些有趣的功能。但同时我发现它并不是很好控制,因为每次调用任何一个方法或函数,都有可能改变它的值。如果要使用它来做一些逻辑处理(比如说我本文提到的一些想法),需要一个拥有良好规范准则的系统,至少在加载文件方面吧。

 

 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1131136.htmlTechArticlePHP debug_backtrace的胡思乱想,phpdebugbacktrace 本文示例代码测试环境是Windows下的APMServ(PHP5.2.6) 简述 可能大家都知道,php中有一个函数叫 d...
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk menyelesaikan masalah penyahpepijatan tidak sah apabila menetapkan titik putus dalam projek SpringBoot Bagaimana untuk menyelesaikan masalah penyahpepijatan tidak sah apabila menetapkan titik putus dalam projek SpringBoot May 11, 2023 am 10:49 AM

Saya baru dalam projek springboot (1) Saya mendapati bahawa penyahpepijatan titik putus tidak berkesan. Saya sangat tertekan dan mencari penyelesaian dalam talian. Apa yang saya lihat hanyalah beberapa penyelesaian yang sangat rumit, yang dikatakan sebagai penyahpepijatan jauh, tetapi juga memerlukan slogan pembukaan tambahan. Ini berbeza daripada projek tradisional, jadi saya rasa ia tidak perlu. Jadi selepas beberapa penerokaan, saya mendapati bahawa terdapat cara yang lebih mudah Langkah-langkahnya adalah seperti berikut: Tambahkan konfigurasi dalam bahagian pemalam fail pom: false dan ia akan menjadi ok; bahawa fail web.xml tiada, kerana projek web tradisional memerlukan fail web.xml, tetapi projek SpringBoot tidak memerlukan fail web.xml.

Bawa anda untuk nyahpepijat projek Nestjs dalam VSCode (tutorial) Bawa anda untuk nyahpepijat projek Nestjs dalam VSCode (tutorial) Apr 24, 2023 pm 05:53 PM

Rakan-rakan yang telah menggunakan Vscode untuk menulis projek seperti Node semua tahu bahawa jika kami ingin menyelesaikan masalah, kami kebanyakannya mencetaknya melalui console.log untuk melihat di mana masalahnya Jika masalah yang terlibat lebih kompleks, kami akan memilih Melalui Vscode ...

Cara menggunakan sambungan jauh IDEA Debug dalam springboot Cara menggunakan sambungan jauh IDEA Debug dalam springboot May 10, 2023 pm 11:55 PM

1. Mula-mula buat Demo sedia untuk penyahpepijatan jauh Beri perhatian kepada konfigurasi projek binaan 4.0.0org.springframework.bootspring-boot-starter-parent2.1.4.RELEASEcom.remote.testremote_test0.0.1-SNAPSHOTremote_testDemoprojectforSpringBoot1.8org.springframework. bootspring-boot- starterorg.springframework.bootspring-bo

Cara menggunakan Nocalhost dan membolehkan penyahpepijatan dalam Python Cara menggunakan Nocalhost dan membolehkan penyahpepijatan dalam Python May 14, 2023 pm 03:16 PM

Nocalhost ialah alat pembangun yang menyokong penyahpepijatan dan penggunaan aplikasi Kubernetes. Menggunakan Nocalhost untuk pembangunan Python memerlukan melengkapkan langkah berikut: Pasang Nocalhost CLI. Ia boleh dipasang melalui pakej pemasangan yang disediakan oleh laman web rasmi Nocalhost. Konfigurasikan kluster Kubernetes dan pasang pemalam Nocalhost. Anda boleh merujuk kepada panduan yang disediakan dalam dokumentasi rasmi Nocalhost. Pasang penterjemah Python dan penyahpepijat pada komputer tempatan, seperti pdb Python sendiri atau pudb perpustakaan pihak ketiga, ipdb, dsb. Buat projek Python dan tambahkan pernyataan panggilan debugger pada kod,

Cara berkesan menangani masalah limpahan Cara berkesan menangani masalah limpahan Jan 27, 2024 am 09:39 AM

Cara Menangani Masalah Limpahan Dengan Betul Limpahan ialah masalah pengaturcaraan komputer biasa, terutamanya apabila berurusan dengan nombor atau tatasusunan. Limpahan berlaku apabila kami cuba menyimpan nilai yang melebihi julat jenis data yang dibenarkan. Kunci untuk menyelesaikan masalah ini terletak pada pengendalian dan pengesahan sempadan data dengan betul. Beberapa masalah limpahan biasa dan penyelesaian yang sepadan akan diperkenalkan di bawah. Limpahan integer Limpahan integer bermakna semasa pengiraan, hasilnya melebihi julat perwakilan jenis integer. Sebagai contoh, dalam 32-bit integer yang ditandatangani taipkan masuk

UCIe 2.0: Memajukan ekosistem chiplet terbuka dengan pembungkusan 3D dan kebolehurusan UCIe 2.0: Memajukan ekosistem chiplet terbuka dengan pembungkusan 3D dan kebolehurusan Aug 08, 2024 pm 12:51 PM

Konsortium Universal Chiplet Interconnect Express (UCIe) telah mengumumkan pengeluaran spesifikasi UCIe 2.0, seterusnya memajukan ekosistem chiplet terbuka. Spesifikasi terkini memperkenalkan beberapa peningkatan utama. Pertama, ia menambah sokongan f

Apakah kaedah penyahpepijatan dalam Python? Apakah kaedah penyahpepijatan dalam Python? Apr 29, 2023 pm 09:01 PM

Kod ujian yang digunakan dalam artikel ini: fromtorchvisionimporttransformsfromtorchvision.datasetsimportFashionMNISTimportosos.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"#Dataset preparation train_data=FashionMNIST(root="./data/FashionMNIST",train=True,transform=transform=transforms

Bagaimana untuk menyahpepijat kod dalam PHP Bagaimana untuk menyahpepijat kod dalam PHP May 23, 2023 pm 05:40 PM

Apabila membangunkan aplikasi PHP, anda sering menghadapi situasi di mana anda perlu menyahpepijat kod. Penyahpepijatan ialah langkah yang perlu untuk menyelesaikan masalah program, mencari ralat dalam kod anda dan meningkatkan prestasi program. Dalam PHP, penyahpepijatan dilakukan menggunakan penyahpepijat. Artikel ini akan memperkenalkan cara menggunakan penyahpepijat untuk menyahpepijat kod dalam PHP. 1. Konfigurasikan persekitaran penyahpepijatan Sebelum memulakan penyahpepijatan, anda perlu mengkonfigurasi persekitaran penyahpepijatan. Tujuan mengkonfigurasi persekitaran penyahpepijatan adalah untuk membolehkan penyahpepijat berjalan untuk membantu anda menyahpepijat kod anda. Terdapat dua jenis utama penyahpepijat PHP: XDebug dan ZendDebug

See all articles