由于原始编码员擅离职守,我收到了用 php 编写的大量未记录的应用程序代码。我的任务是添加新功能,但如果不理解代码,我就无法做到这一点。我开始四处探索。老实说,源代码的数量让我不知所措。我发现:
- 它基于 MVC 架构、DB 持久性、模板化和框架编写得很好。 OOP
- 模块化,有基于URL的路由概念,基本模板
- 使用自定义编写的php框架,没有文档。并且没有源代码控制历史(哎呀!)
- 有超过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->shared & 在哪里? 这个->视图来自哪里?我检查了文件的其余部分,没有名为共享或视图的方法。很明显,它们来自使用 require_once() 包含的数百个类之一,但是是哪一个呢?我怎样才能找到答案?
- 我可以获得正在执行的所有函数或方法的列表吗?如果是,那么如何?
- 这个类 SiteController 覆盖了一个 Common 基类。但我无法找出这个Common类位于哪里。怎样说呢?
此外,请分享一些用于理解用 php 编写的现有代码的技术?
I have been handed over a large undocumented code of a application written in php as the original coder went AWOL. My task is to add new features but I can't do that without understanding the code.I started poking around. honestly, I am overwhelmed by the amount of source code. I have found:
- Its well written based upon MVC architecture, DB persistence, Templating & OOP
- modular, there is concept of URL based routing,basic templating
- Uses custom written php framework which has no documentation.And there no source control history(oops!)
- there over 500 files, with each file containing hundreds of line of code. And every file has 3-4 require_once statements which include tons of other files, so its kinda hard to tell which function/class/method is coming from where
Now I am looking for some techniques that I use to understand this code. for example, consider the following code snippet:
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();
}
I want to know
- where HomeView() & Home() are defined? Where does $this->shared & this->view come from? I checked the rest of the file, there is no method named shared or view. so obviously, they coming from one of hundreds of classes being included using require_once() But which one? how can I find out?
- Can I get a list of all the functions or methods that are being executed? If yes, then how?
- this class SiteController overrides a base Common class. But I unable to find out where is this Common class is located. How to tell?
Further, Please share some techniques that that be used to understand existing code written in php?
发布评论
评论(8)
首先,在这种情况下,我尝试获得应用程序的概述:某种全局概念:
一旦您有了全局观念,如果您有时间的话,可以使用 PHP 调试器来开始了解代码的工作原理。
关于这一点,Xdebug + Eclipse PDT 是一种可能性 - 但几乎全部现代 IDE 支持这一点。
它将允许您一步一步、一行一行地生成页面,了解调用的内容、何时、从哪里……
当然,您不会为整个应用程序这样做!
但是当您的应用程序使用框架时,应用程序的所有部分很可能以相同的方式工作 - 这意味着真正理解一个组件应该有助于更轻松地理解另一个组件。
作为了解什么调用什么、如何调用以及在何处调用的几个工具,您可能需要看看:
另请注意,应用程序不仅仅是代码:对数据库进行逆向工程以生成所有表的图表通常非常有用。
如果你幸运的话,你的数据库中有外键——这样你就可以在表之间建立链接;这将帮助您了解它们之间的关系。
First, in this kind of situation, I try to get an overview of the application : some kind of global idea of :
Once you have that global idea, a possibility to start understanding how the code works, if you have some time before you, is to use a PHP Debugger.
About that, Xdebug + Eclipse PDT is a possibility -- but pretty much all modern IDEs support that.
It'll allow you to go through the generation of a page step by step, line by line, understanding what is called, when, from where, ...
Of course, you will not do that for the whole application !
But as your application uses a Framework, there are high chances that all parts of the application work kind of the same way -- which means that really understanding one component should help understanding the other more easily.
As a couple of tools to understand what calls what and how and where, you might want to take a look at :
Also note that an application is not only code : it often find very useful to reverse-engineer the database, to generate a diagram of all tables.
If you are lucky, there are foreign keys in your database -- and you'll have links between tables, this way ; which will help you understand how they relate to each other.
你需要一个 IDE。我在 PHP 中使用 netbeans,效果非常好。这将允许您通过右键单击并选择“查找定义的位置”选项或类似的选项来找出 homeview/home 类的位置。
你可以获得一份清单。这称为堆栈。使用 IDE 设置像 xdebug 这样的调试器将允许您执行此操作。
You need an IDE. I use netbeans for PHP and it works great. This will allow you to find out where the homeview/home classes are by right clicking and selecting a "find where defined" option or something similar.
You can get a list. This is called the stack. Setting up a debugger like xdebug with the IDE will allow you to do this.
grep
是唯一让我在这样的代码中生存下来的东西grep
is the only thing makes me survive such codez希望有帮助,
斯普里诺724
Hope that helps,
spryno724
我会从以下开始:
Class Common
例如,get_included_files();
查看某个调用实际使用的内容I would start with:
Class Common
for exampleget_included_files();
to see what is actually used for a certain call您似乎意识到您无法阅读/消化每个文件,因此您必须专注于重要的文件。看起来您已经使用
SiteController
开始了该过程。希望在阅读需求和使用 IDE 之间,您可以追踪
Home()
和HomeView()
可能有一些关键的 XML 文件规定了从 URL 到控制器文件,因此您还想弄清楚它们是如何工作的。
我之前使用过一个记录不充分(但工作正常)的自定义框架,并且您的情况似乎非常相似。当我了解了主控制器并基本上了解了 URL 请求的处理方式后,我发现事情变得非常顺利。
You seem to realize that you can't read/digest every file, so you've got to focus on the important ones. Looks like you've started that process with
SiteController
.Hopefully between reading the requires and using your IDE you can chase down the
Home()
andHomeView()
There might be a few key XML files that dictate the mappings from URLs to controller files, so you'll want to figure out how they work also.
I've worked with a poorly documented (but decently working) custom framework before, and your situation seems pretty similar. I found things pretty smooth once I understood the main controller and basically formed an understanding for how URL requests were processed.
1) 您可以使用 grep 等搜索工具来查找代码,包括定义。但在大型代码库上,grep 速度很慢,并且会给出很多误报,因为它不了解 PHP 语言。
我们的搜索引擎是一个基于GUI的工具,可以索引您的源代码以实现极快的查找、索引通过语言元素(变量名、常量、关键字、字符串等)并允许制定遵循语言结构的查询(例如,它会忽略空格和注释,除非您说想要查看它们)。查询会在命中窗口中显示命中,然后单击将您带到发生命中的文件/行。通过一些额外的配置,您可以从代码窗口进入您最喜欢的编辑器。
2)有时您想知道特定功能在哪里,但您不知道要搜索什么。在这里,测试覆盖率工具确实可以提供帮助。简单地设置(工作)应用程序的测试覆盖率,并手动执行功能; “覆盖”的可能是您关心的代码。锻炼一些不属于特征的东西;所覆盖的不是您想要的代码。这比尝试运行调试器来查找感兴趣的代码要容易得多。我们的 PHP 测试覆盖率工具可以为您提供这种覆盖率,而不仅仅是向您显示覆盖的代码在 GUI 中,还可以执行“覆盖率减法”,以便您只能看到相关代码。
1) You can use a search tool such as grep to find code, including definitions. But on a big code base, grep is slow, and it gives a lot of false positives because it has no understanding of the PHP language.
Our Search Engine is a GUI-based tool that indexes your source code to achieve extremely fast lookup, indexing by the langauge elements (variable names, constants, keywords, strings, ..) and allowing to formulate queries that honor the langauge structure (e.g., it ignores whitespace and comments unless you say you want to see them). A query shows hits in a hit window, and a click takes you to the file/line in which the hit occurs. With some tiny bit of additional configuration, you can go from the code window into your favorite editor.
2) Sometimes you want to know where specific functionality exists, but you have no clue what to search for. Here a test coverage tool can really help. Simple set up test coverage for the (working) application, and exercise the functionality manually; what is "covered" is potentially the code you care about. Exercise something which is NOT the feature; what is covered is NOT the code you want. This is way easier than trying to run a debugger to find the code of interest. Our PHP Test Coverage tool can provide you this coverage, and not only show you the covered code in GUI, but also do that "coverage subtraction" so that you can see just the relevant code.
从应用程序的入口点(通常是index.php)开始,深入了解何时调用什么。
尝试一下 PHPstorm,它是一个具有出色代码分析功能的 IDE,可以转到任何类和变量的定义、显示继承层次结构、查找用法和许多其他有用的东西。
我还将插入我自己的工具:
http://raveren.github.io/kint/
它可以在零设置的情况下工作,对于掌握哪里发生的事情非常有用。使用
Kint::trace();
查看漂亮的执行回溯,使用d(get_define_vars());
查看当前上下文中定义的内容,最终您将到那里。屏幕截图:
(来源:github.io)
Start from the entry point of the application (usually index.php) and go deeper on what gets called when.
Give PHPstorm a go, it's an ide with excellent code analyzing features, can go to definition of any class and variable, show inheritance hierarchy, find usages and many other useful stuff.
I'll also plug my own tool:
http://raveren.github.io/kint/
It's works with zero set up and is extremely useful to get a grip on what's going on where. Use
Kint::trace();
to see a pretty execution backtrace andd(get_defined_vars());
to see what is defined in the current context and eventually you'll get there.Screenshot:
(source: github.io)