了解大型PHP代码,使用什么技术?

时间:2011-04-06 21:22:34

标签: php reverse-engineering static-analysis

我已经移交了一个用PHP编写的应用程序的大型未记录代码,原始编码器就是AWOL。我的任务是添加新功能,但如果不了解代码,我就无法做到这一点。我开始探索。老实说,我对源代码的数量感到不知所措。我找到了:

  • 它基于MVC架构,数据库持久性,模板和编写而编写得很好。 OOP
  • 模块化,有基于URL的路由概念,基本模板
  • 使用没有文档的自定义编写的php框架。没有源代码控制历史记录(oops!)
  • 有超过500个文件,每个文件包含数百行代码。并且每个文件都有3-4个require_once语句,其中包含大量其他文件,因此很难分辨出哪个函数/类/方法来自哪里

现在我正在寻找一些我用来理解这段代码的技巧。例如,请考虑以下代码段:

class SiteController extends Common {

private $shared;
private $view;


protected function init(){


    $this->loadShared();
    $this->loadView();


}

private function loadShared(){
    $this->shared = new Home();
}

private function loadView(){
    $this->view = new HomeView();
}

我想知道

  • 其中 HomeView()& Home()是否已定义? $ this->共享& this-> view 来自哪里?我检查了文件的其余部分,没有名为shared或view的方法。很明显,他们来自使用require_once()包含的数百个类中的一个但是哪一个?我该如何找到?
  • 我可以获取正在执行的所有函数或方法的列表吗?如果是,那怎么样?
  • 此类 SiteController 会覆盖基本 Common 类。但是我无法找到这个 Common 类的位置。怎么说?

此外,请分享一些用于理解用PHP编写的现有代码的技术?

8 个答案:

答案 0 :(得分:9)

首先,在这种情况下,我试图获得概述应用程序:某种全球性的想法:

  • 应用(不是代码!)做什么
  • 代码是如何全局组织的:模型,模板,控制器......在哪里......
  • 每种类型的组件的结构 - 一旦你知道Model类如何工作,其他组件通常会以相同的方式工作。


一旦你有了这个全球性的想法,如果你有一些时间,开始理解代码如何工作的可能性是使用PHP调试器。
关于这一点,Xdebug + Eclipse PDT是一种可能性 - 但几乎所有现代IDE都支持它。

它允许您逐步,逐行地完成页面的生成,理解所谓的内容,何时,何地,...

当然,你不会为整个应用程序做到这一点!
但是,当您的应用程序使用框架时,很有可能应用程序的所有部分以相同的方式工作 - 这意味着真正理解一个组件应该有助于更容易地理解另一个组件。


作为一些工具来理解什么叫做什么,怎么做,在哪里,你可能想看看:

  • inclued扩展名(引用)允许您在运行时跟踪并转储文件包含和类继承的层次结构
  • Xdebug + KCacheGrind将允许您生成调用图; XHProf应该做同样的事情。
  • 使用您的IDE Eclipse PDTZend StudiophpStormnetbeans,...),按住Ctrl键并点击一个班级/方法应该带你到它的声明。


另请注意,应用程序不仅仅是代码:它经常发现对数据库进行反向工程非常有用,可以生成所有表的图表。

如果幸运的话,你的数据库中有外键 - 你可以通过这种方式在表之间建立链接;这将有助于您了解它们之间的相互关系。

答案 1 :(得分:2)

您需要一个IDE。我使用netbeans for PHP,效果很好。这将允许您通过右键单击并选择“查找定义的”选项或类似内容来查找homeview / home类的位置。

你可以得到一份清单。这称为堆栈。使用IDE设置xdebug之类的调试器将允许您执行此操作。

答案 2 :(得分:2)

grep是唯一能让我在这样的代码中存活的东西

答案 3 :(得分:1)

  • 查看脚本内部,您可以在其中找到PHP导入主脚本的其他包含或必需页面的代码段。这些脚本应该定义那些正在实例化的类。
  • 抱歉,不确定您是否可以找到已执行的功能/方法。我知道你可以找到它们是否存在,你可以找到它们的生成输出......但不确定它们是否已被执行。
  • 重要的是要注意 SiteController 不会覆盖 Common 类,但它会扩展或构建在它之上,就像建筑物的构建方式一样在一个基础上。 Common 类是基础。再次,检查包含和必需的脚本,以查看 Common 的定义位置。

希望有所帮助,
spryno724

答案 4 :(得分:1)

我会从:

开始
  • 在某些点抛出异常以查看发起呼叫的堆栈跟踪。
  • grep for Class Common例如
  • 创建目录列表以了解软件的组织
  • 使用get_included_files();查看实际用于某个电话的内容
  • 开始记录我发现的内容
  • 开始使用IDE,如NetBeans,Eclipse或Zend Studio
  • 使用这种"php: determining class hierarchy of an object at runtime"方法
  • 来确定类层次结构

答案 5 :(得分:1)

您似乎意识到您无法读取/消化每个文件,因此您必须专注于重要文件。您似乎已使用SiteController启动了该过程。

希望在阅读要求和使用IDE之间,您可以追逐Home()HomeView()

可能有一些关键的XML文件指示从URL到控制器文件的映射,因此您还需要弄清楚它们是如何工作的。

我之前使用的是一个记录不完整(但工作正常)的自定义框架,你的情况看起来非常相似。一旦我理解了主控制器,我发现事情非常顺利,并且基本上形成了对如何处理URL请求的理解。

答案 6 :(得分:1)

从应用程序的入口点(通常是index.php)开始,深入了解何时调用。

给PHPstorm一个go,它是一个具有优秀代码分析功能的ide,可以定义任何类和变量,显示继承层次结构,查找用法和许多其他有用的东西。

我还会插入自己的工具:

http://raveren.github.io/kint/

它的设置为零,对于掌握正在发生的事情非常有用。使用Kint::trace();查看漂亮的执行回溯和d(get_defined_vars());以查看当前上下文中定义的内容,最终您将到达目的地。

截图:

Kint screenshot

答案 7 :(得分:1)

1)您可以使用grep等搜索工具查找代码,包括定义。但是在一个很大的代码库上,grep很慢,并且它会产生很多误报,因为它不了解PHP语言。

我们的Search Engine是一个基于GUI的工具,可以对您的源代码编制索引,以实现极快的查找,通过语言元素(变量名,常量,关键字,字符串......)进行索引,并允许制定查询尊重语言结构(例如,它忽略了空白和评论,除非你说你想看到它们)。查询显示命中窗口中的命中,单击会将您带到命中发生的文件/行。通过一些额外的配置,您可以从代码窗口进入您喜欢的编辑器。

2)有时您想知道特定功能的存在位置,但您不知道要搜索的内容。在这里,测试覆盖率工具可以提供帮助。简单设置(工作)应用程序的测试覆盖率,并手动执行功能;什么是“覆盖”可能是你关心的代码。锻炼不是特征的东西;涵盖的不是您想要的代码。这比尝试运行调试器以查找感兴趣的代码更容易。我们的PHP Test Coverage工具可以为您提供此覆盖范围,不仅可以向您显示GUI中的覆盖代码,还可以执行“覆盖减法”,以便您只看到相关代码。