在咱們開發項目的過程當中,不可避免的會使用一些開軟程序,由於使用開源程序能夠縮短咱們的開發週期,下降研發成本。php
可是在使用過程當中,不免會碰到各類坑,這個時候,就要求程序員擁有分析開源項目的能力,由於並不是是全部開源項目都會擁有一個穩定的維護團隊和健全的文檔(畢竟開源項目不多有盈利的)。git
在進行 PHP 研發過程當中,咱們可使用如下5中方式來進行代碼分析:程序員
爲何要把看文檔排在第一位?github
當咱們第一次拿到開源程序的代碼時,不少人會第一反應去看它的源代碼,可是若是說咱們要了解它的編程思想,就看編程思想而言是看文檔,仍是看代碼要容易呢?ajax
若是在不瞭解開源代碼的功能就去了解代碼的話,其實很難可以弄懂他的編程思想。thinkphp
有時候開源程序沒有提供文檔,咱們可使用 PHPDocumentor 將註釋提取成文檔。編程
PHPDocumentor: http://www.phpdoc.org/
使用 Xdebug 調試代碼api
咱們可使用 Xdebug 聯合 IDE 經過斷點調試放慢代碼執行流程,當程序執行到用戶指定的斷點後,能夠到該位置停頓,而後輸出在該變量中的值,能夠一步一步的分析代碼,若是碰到難懂的代碼就能夠經過這種形式來進行調試代碼。數組
Xdebug: https://xdebug.org
PHP自帶函數瀏覽器
打出調用棧:
debug_backtrace(); debug_print_backtrace();
若是咱們本身去看執行流程,就要跟着函數一步一步的走,但是若是使用調用棧,就能夠清晰明瞭的看清。
<?php namespace app\index\controller; class Index { public function index() { dump(debug_backtrace());exit; } }
咱們能夠經過這兩個函數查看 ThinkPHP 是如何調用控制器的,在這裏,我使用的 ThinkPHP5.0,在這裏咱們須要從下往上看。
array(7) { [0] => array(5) { ["function"] => string(5) "index" ["class"] => string(26) "app\index\controller\Index" ["object"] => object(app\index\controller\Index)#3 (0) { } ["type"] => string(2) "->" ["args"] => array(0) { } } [1] => array(7) { ["file"] => string(70) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/App.php" ["line"] => int(343) ["function"] => string(10) "invokeArgs" ["class"] => string(16) "ReflectionMethod" ["object"] => object(ReflectionMethod)#4 (2) { ["name"] => string(5) "index" ["class"] => string(26) "app\index\controller\Index" } ["type"] => string(2) "->" ["args"] => array(2) { [0] => object(app\index\controller\Index)#3 (0) { } [1] => array(0) { } } } //.....省略 }
咱們能夠來分析一下 ThinkPHP5.0的調用步驟:ß
debug_backtrace 顯示的是詳細信息,若是想要簡單的查看調用,可使用debug_print_backtrace
函數直接打印輸出堆棧的調用信息。
這樣咱們就能夠分析出,ThinkPHP 的執行流程,也就四五分鐘的時間。
當咱們須要輸出變量的時候,咱們應該使用 var_dump(),由於var_dump 能夠直觀的看出數組的結構。
當咱們在在向日志文件輸出數組的時候,咱們可使用 var_export()
進行輸出。
<?php $a = array (1, 2, array ("a", "b", "c")); var_export ($a); /* 輸出: array ( 0 => 1, 1 => 2, 2 => array ( 0 => 'a', 1 => 'b', 2 => 'c', ), ) */
另外咱們能夠經過 get_included_files來獲取當前腳本文件都加載了哪些文件。
array(23) { [0] => string(56) "/Users/maksim/Downloads/thinkphp_5.0.20/public/index.php" [1] => string(58) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/start.php" [2] => string(57) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/base.php" [3] => string(73) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/Loader.php" [4] => string(75) "/Users/maksim/Downloads/thinkphp_5.0.20/vendor/composer/autoload_static.php" [5] => string(72) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/Error.php" [6] => string(73) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/Config.php" [7] => string(63) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/convention.php" [8] => string(70) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/App.php" [9] => string(74) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/Request.php" [10] => string(62) "/Users/maksim/Downloads/thinkphp_5.0.20/application/config.php" [11] => string(64) "/Users/maksim/Downloads/thinkphp_5.0.20/application/database.php" [12] => string(67) "/Users/maksim/Downloads/thinkphp_5.0.20/application/extra/queue.php" [13] => string(71) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/Hook.php" [14] => string(60) "/Users/maksim/Downloads/thinkphp_5.0.20/application/tags.php" [15] => string(62) "/Users/maksim/Downloads/thinkphp_5.0.20/application/common.php" [16] => string(70) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/Env.php" [17] => string(59) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/helper.php" [18] => string(71) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/Lang.php" [19] => string(63) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/lang/zh-cn.php" [20] => string(61) "/Users/maksim/Downloads/thinkphp_5.0.20/application/route.php" [21] => string(72) "/Users/maksim/Downloads/thinkphp_5.0.20/thinkphp/library/think/Route.php" [22] => string(78) "/Users/maksim/Downloads/thinkphp_5.0.20/application/index/controller/Index.php" }
上面都是用PHP 自帶的函數來作代碼分析,下面來說解一下利用 SocketLog 來分析源代碼。
SocketLog 能夠把咱們的一些日誌打到瀏覽器的調試工具上面。
好比說 SQL 語句,點開後能夠查看調用棧,經過這些信息,咱們就能夠快速定位咱們想要修改的代碼。其實 SocketLog 還能夠作微信調試。
詳細的使用方法能夠經過 github 進行查看:
https://github.com/luofei614/...
咱們能夠經過一些思惟導圖的工具來幫助咱們分析業務邏輯。
咱們還能夠經過 UML 圖形來整理類之間的關係,咱們能夠看 《大象UML 》來了解 UML 建模。