代码之家  ›  专栏  ›  技术社区  ›  gerdemb

继承了一个PHP噩梦,从哪里开始?[关闭]

  •  40
  • gerdemb  · 技术社区  · 16 年前

    我继承了一个PHP项目,结果却是一场噩梦。以下是要点:

    1. 原来的开发商都走了
    2. 代码没有版本控制
    3. 每个文件中有多个包含到包含其他文件的其他文件的文件,等等。
    4. 在这个项目中,有很多开发人员都有自己的工作方式。例如,JavaScript框架层出不穷,有些数据库查询使用SQL,有些则使用XML接口,有些则调用数据库中的过程函数。

    其次,是否有某种类型的分析可以跟踪服务器上实际使用的文件?我想删除实际上没有包含的内容的重命名副本。更妙的是,有没有一种方法可以判断文件的哪些部分没有被执行?有很多复制的函数和垃圾,我怀疑它们也没有被使用。同样地,对于include,有什么关于清理混乱的提示吗?

    27 回复  |  直到 14 年前
        1
  •  56
  •   Scott Bevington    16 年前
    1. 先把文件拿进来 版本控制原样。 在完成之前,不要超过1。
    2. 清理文件
        2
  •  30
  •   bradheintz    16 年前

    我做到了。我同情你。如果您的护照不是最新的,或者由于某些其他原因,您无法避免这样做,下面是我将如何处理它:

    之后,我会从数据库开始。确保所有内容都相对规范化,列都有明确的名称,等等。

    接下来执行PHP代码。如果代码真的是那么多的拼凑,我会继续并适合它的框架。观察 CakePHP Symfony -他们用Rails的方式分离关注点,这就产生了一个问题:“这段代码应该放在哪里?”很容易回答。这不是一个小任务,但一旦你做到了,你可能比拥有一个构造合理的应用程序的一半要好。此外,一个好的Web框架的内置测试设施使得重构变得更容易——在改变之前,编写一个测试来覆盖现有的功能,并且您将知道在更改之后是否有任何损坏。

    一旦对数据库进行了排序,并在模型中包含了模型代码,在控制器中包含了控制器代码,那么您就可以担心表示层的问题,比如在单个JS/AJAX库中进行标准化,清理CSS等等。

    至于开发环境:您绝对应该设置一个本地开发环境。有一些WAMP包,或者你可以安装到Linux box/VM(我建议 VirtualBox

    至于调试/分析工具,我知道Symfony提供了一组非常灵活的工具,包括一个JS小工具栏,它出现在您的页面上(仅在调试模式下),其中包含日志和分析信息。

        3
  •  17
  •   Dan Esparza    14 年前

    好吧,第一件事。我一直处于你所处的状况,这很糟糕。我认为您希望启动并运行一个开发环境是正确的。

    开发环境

    为了一个 LAMP 堆栈安装程序 ,我建议您使用以下方法之一:

    灯组上的进一步读数:

    O'Reilly's OnLamp site

    PHP集成开发环境

    Article on IBM's Developer site 比较几个IDE

    为了 源代码管理 ,您可以使用TeamFoundationServer、SVN或Git——只需使用一些您知道的东西。我建议你先把所有的东西都放在源代码管理中(对于任何你可能需要的紧急维护),然后计划进行一次大的检修。

    检修

    您提到,您甚至不知道要使用哪些文件,而且它们使用文件命名约定作为伪版本控制。在开发环境启动并运行之后,您可能希望开始在那里进行彻底检查。有几件事可以帮助你:

    • 你的应用客户/用户
    • 一个好的日志框架

    你的客户/用户很重要 ,因为听起来你是项目的新手,他们会知道应用程序应该如何表现得比你更好(很可能)。

    仔细记笔记很重要 ,因为您将从头开始重新编写任何需求/设计/最终用户文档。如果你要这么做的话,你需要了解它的内部结构。如果你想了解这个系统的任何信息,你需要自己写下来(或者你现在正在阅读预先制作好的文档,而不是读取堆栈溢出);-)

    最后, 因为你需要修理东西,而你不能修理那些你不知道已经坏掉的东西。日志框架使您可以看到应用程序中没有任何明显UI的部分。将它插入应用程序的各个部分,然后查看日志,可以很好地了解代码何时执行以及以何种顺序执行。

    你需要专注于捕捉(纸上的)应用程序应该如何工作,然后慢慢删除不必要的文件,同时尽量不破坏任何东西。注意日志以帮助调试。确保你的顾客没有尖叫什么东西坏了。确保你的笔记与记录的内容和你的客户所说的一致。

    重新检查一切回到源代码管理 . 希望到目前为止,您已经得到了一个更新的、更理智的、更好的目录结构。

    . 即使这仅仅意味着在每个部署之后都有一个基本的单元测试框架并进行一些基本的冒烟测试,但总比什么都没有要好。理想情况下,您应该有一个测试工程师或一个知识渊博、值得信赖的客户,他们可以在每次部署后花时间进行测试。

    部署流程到位 如果你有一个以上的开发人员。控制对生产环境的更改应该是您的首要任务。(你最不想做的就是再经历一遍,对吧?)您应该有一个在环境边界之间移动的清晰而简单的过程(例如Dev->Test-then Test->Production)。

        4
  •  16
  •   grom    16 年前

    grep -r "index2.php" *
    

    您还可以使用PHP解析器帮助您进行清理。下面是一个示例脚本,用于打印已声明的函数和函数调用:

    #!/usr/bin/php
    <?php
    class Token {
        public $type;
        public $contents;
    
        public function __construct($rawToken) {
            if (is_array($rawToken)) {
                $this->type = $rawToken[0];
                $this->contents = $rawToken[1];
            } else {
                $this->type = -1;
                $this->contents = $rawToken;
            }
        }
    }
    
    $file = $argv[1];
    $code = file_get_contents($file);
    
    $rawTokens = token_get_all($code);
    $tokens = array();
    foreach ($rawTokens as $rawToken) {
        $tokens[] = new Token($rawToken);
    }
    
    function skipWhitespace(&$tokens, &$i) {
        global $lineNo;
        $i++;
        $token = $tokens[$i];
        while ($token->type == T_WHITESPACE) {
            $lineNo += substr($token->contents, "\n");
            $i++;
            $token = $tokens[$i];
        }
    }
    
    function nextToken(&$j) {
        global $tokens, $i;
        $j = $i;
        do {
            $j++;
            $token = $tokens[$j];
        } while ($token->type == T_WHITESPACE);
        return $token;
    }
    
    for ($i = 0, $n = count($tokens); $i < $n; $i++) {
        $token = $tokens[$i];
        if ($token->type == T_FUNCTION) {
            skipWhitespace($tokens, $i);
            $functionName = $tokens[$i]->contents;
            echo 'Function: ' . $functionName . "\n";
        } elseif ($token->type == T_STRING) {
            skipWhitespace($tokens, $i);
            $nextToken = $tokens[$i];
            if ($nextToken->contents == '(') {
                echo 'Call: ' . $token->contents . "\n";
            }
        }
    }
    
        5
  •  10
  •   Harper Shelby damiankolasa    16 年前
    1. 设置开发服务器(如Greg Hewgill提到,VirtualBox和 虚拟PC是 这个)。

    2. 放置当前站点文件 以及PHP配置!)进入之内 版本控制。

    3. 找出正在使用的文件- 通过删除所有fooN.php 文件,看看它是否仍然有效。

    4. 祈祷…很多(好吧,这不是 需要,但听起来你会 需要它)。

        6
  •  10
  •   dkretz    16 年前

    我给了它三个尝试重构方法的开始。就像骑摩托车爬山一样,每次都能跑10%的路程。所以我采取了另一种方法,结果效果好多了。

    1. 我以用户身份登录,
    2. 我把html保存到静态文件中,
    3. 注意程序操作和明显的业务规则。

    我这样做了整整三天,然后做了笔记,与利益相关者进行了长时间的交谈。

    在对一些第一步达成一致后,我使用良好的一致性设计和抽象,正确地重新实现了所有的html UI。滚了以后,我一天可以做几次屏幕。

    结果证明,这是艰苦工作的结束(也是利益相关者感知到的项目风险的结束)

    结果发现,第一批工作人员被自己的意大利面条绑得太紧了,实际上工作内容相对较少,所以复制的范围比所有人怀疑的要小。

        7
  •  7
  •   Dexygen    9 年前

    您可以考虑的一件事是在开发环境中安装PHP“xdebug”扩展,将其设置为跟踪所有函数调用,然后尽可能完整地(可能通过自动化UI测试)运行整个应用程序。然后,您将能够分析/解析xdebug跟踪文件,以找到应用程序使用的所有文件/函数。

        8
  •  6
  •   Community CDub    8 年前

    这方面的其他人有很好的建议。我也遇到过这种情况。也许每个人在他们的职业生涯中都会有一次走进一个看起来像是被龙卷风袭击的项目。

    我要补充的一个建议是,在你做任何其他人描述的清理工作之前,你需要得到管理层的认可。

    • 描述创建开发和测试环境所需的任何新硬件或软件,并对其定价。
    • 估计清理工作的时间表。需要多长时间才能将代码置于源代码管理之下?了解数据库需要多长时间?理解PHP和javascript代码需要多长时间?
    • 向你的经理展示这一点,并用对其底线有利的措辞表达目标。E、 g.一旦一切都清理干净,进行更改或推出新功能将更快,调试错误将更可预测,增加新员工将更容易。

    当然,你需要继续与当前的混乱工作,因为它是一个现场网站。管理实时站点是首要任务,因此清理工作必须是后台任务。那就意味着要花更长的时间。我清理一个中等规模项目作为背景任务的经验通常需要6到12个月。由于网站将在这段时间内继续发展,您完成的一些清理任务可能需要修改或重新完成。确保你的经理也理解这一切。

    如果经理对你清理这一烂摊子的计划犹豫不决,或者不重视清理,那么至少你会知道为什么所有其他开发人员都离开了这家公司!

    关于如何进行,我有一些具体的建议:

    • Joel Test 作为基准。你的清理计划应该能创造一个工作环境,在Joel考试中取得好成绩。
    • What are the best ways to understand an unfamiliar database? "
    • 在网站上启用日志记录,以便您可以分析实际调用的PHP页面。至少可以告诉您index2.php、index3.php、index4.php等中哪些是真正过时的。
    • get_included_files() 返回当前请求期间包含的所有文件的数组。通过记录这些信息,您可以发现哪些PHP文件正在使用,即使它们没有显示在web服务器日志中。
    • 您确实需要一个与生产服务器匹配的测试和开发环境。在Windows上测试并在Linux上部署是不好的。在开发过程中使用MySQL 5.0和在生产中使用MySQL 4.0是不好的。你也许可以摆脱硬件平台更谦虚(虽然兼容)。
        9
  •  5
  •   ChrisLively    16 年前

    我会:

    1. 坐下来深呼吸;
    2. 决定你是否真的想去那里工作;
    3. 如果是的话,我会卷起我的烂摊子,一次挑一个烂摊子干,然后开始工作。

    我知道我们不能一次只做一件事,但是,你可以把你的工作限制在一次解决一个问题,同时处理日常工作。

        10
  •  5
  •   lo_fye    16 年前

    通过将此项放在页面底部,可以看到所有包含/必需文件的列表:

    <?php var_dump(get_included_files()); ?>
    
        11
  •  4
  •   dreftymac    9 年前

    考虑重新编写并使用旧站点作为功能规范

    提到 据我所见,这是另一种选择: 放弃代码,将站点本身的功能作为新的功能集规范使用 (也就是说,这个项目的第一个)然后根据这些特性,用一个已经建立的框架(比如Symfony、Laravel或Drupal)重新构建站点。

    是的,有些人会因为邪恶的话语而畏缩不前 重写 ... 但是在那里 当这实际上是一个更好的方法时,你暗示了一些原因:

    • 你自己对PHP开发还很陌生
    • 你最好开始做点什么 清洁的 而不是你继承的那些垃圾代码
    • 归根结底, 大多数用户根本不在乎源代码 ,如果他们觉得这样“管用”,如果你试图告诉他们一些可怕的错误,他们可能会觉得你疯了

    当然,在这个位置上的每个人以前都必须使用这样的代码,但是有时候足够了,最好是扔掉意大利面,从一个新盘子开始。

    如果你读 Joel's article 关于为什么重写不好,你会发现他引用的情况几乎都不适用于你。

        12
  •  3
  •   Jason Plank Maksim Kondratyuk    13 年前
    1. 版本控制。

    2. 处理安全问题。确保站点不受sql注入和电子邮件注入的影响。至少,您可以搜索数据库调用并将调用添加到 mysql_real_escape_string() (如果它使用的是MySQL数据库的话)。。。当你更好地理解代码之后,你可以做一个真正的修复。对于电子邮件注入。。。编写一个过滤函数,过滤掉垃圾邮件发送者代码,并确保电子邮件中使用的所有表单字段都被过滤掉。(是的,它添加了更多的spagetti代码,但是需要一段时间才能准备好对代码进行重大重构。)

    3. 之后,我建议进行增量升级。你是新来的,代码是乱七八糟的,所以需要一段时间才能完全理解。。。并充分了解领域。所以,只需做一点工作,修复需要修复的内容,添加需要添加的内容。当你这样做的时候,你正在学习如何将系统组合在一起。一旦你知道代码是如何组织的(或不是组织的)好一点,你就可以开始计划一个主要的系统重构/重写。希望您可以一个组件一个组件地完成它,这样您总是有一个新的里程碑即将到来。

        13
  •  2
  •   Greg Hewgill    16 年前

    我要做的第一件事是使用某种虚拟机建立一个测试环境。VirtualBox或Virtual PC都是不错的选择。这样你就可以开始改变事情,而不用担心破坏生产环境。不管这看起来需要多少工作(使用数据库和web服务器以及其他一切),最终还是值得的。其中一个巨大的好处是,如果您发现需要帮助,可以复制VM并将其交给其他人。

        14
  •  2
  •   Kevin Tighe    16 年前

    你肯定需要一个开发环境。如果你不想在windows上运行这个站点,你可以获取一些Linux发行版的VMWare映像。

        15
  •  2
  •   Aistina    16 年前

    如有必要,若要找出是否使用了某些类,则可以将get_声明的类与get_定义的变量和gettype结合使用,以查看正在实例化哪些类型。

    至于第4和第5期,这些问题可能有点难解决,但这应该让你有希望开始。

        16
  •  2
  •   ManiacZX    16 年前

    我想你所有的5点都符合我继承的一些经典的ASP项目,还有一个PHP项目。。。

    我完全同意其他人关于尽快在源代码管理中使用它并在测试环境中使用VMWare、VirtualBox等的观点。

    至于如何使用数据库方面的内容,我建议您看看 ApexSQL Clean . 我在一个有几百个ASP文件、200多个表和大约400个存储过程的项目中使用了这个。我能够识别出20个左右未使用的表和大约25%的存储过程。使用ApexSQL Clean,您可以将所有php文件以及表、视图和存储过程添加到依赖项检查中。抓紧30天的试用期看看吧,这会节省你很多时间。

    对于网站上使用的文件,我有上个月的web服务器日志,并对它们进行搜索,查找我不确定的内容。我也很喜欢Aistina在访问文件时修改其日志的建议的变体。可能让它转到您设置的数据库中的一个表,即文件名和访问计数,并且每次加载该文件时,它都会增加该计数。过一段时间后,你可以查看计数并确定可以进行的操作。

        17
  •  2
  •   Vilx-    16 年前

    以下是一些想法:

    • 尝试 grep
    • 或者,列出所有文件名并搜索所有文件。你可以做一个像这样的依赖关系图。
        18
  •  2
  •   BenAlabaster    16 年前

    这真是一团糟。但是,开始有创意的去哪里切断这东西的一些触角:

    1. 设置本地开发服务器。找一个WAMP,LAMP或MAMP包让你开始,因为你是新手。
    2. 找到入口点(index.php等)。检查服务器访问日志以查看这些日志。
    3. 卷起袖子看一些正则表达式black magic,并在所有文件上转储include/require树。但请注意任何include($filename)动态include。如果您有任何这些,您将需要在$filename上进行一些登录,以找出可能包含的内容,尽管围绕它的代码应该会给您提供线索。如果运气好的话,你可以用这种方法剔除所有未使用的文件。
    4. 使用更多的regex black magic检查代码库中其他地方引用的函数和方法。可能有一个IDE可以帮助您解决这个问题。尝试NETBeBeS(我用它来帮助我重构一个C++项目,所以在这里可能会有帮助)。
    5. 正如其他人回答的那样,“如果有必要的话,如果使用了一些类,而没有使用一些类,您可以将get_declared_classes与get_defined_vars和gettype结合使用,以查看哪些类型正在被实例化。”您也可以编写一些代码来在代码基中查找所有新语句。
    6. 等等。。。想想你怎么能把这个怪物砍倒。尽量重新组织代码。
        19
  •  2
  •   staticsan    16 年前

    不想重复别人说过的话:

    1. 获取正在运行的prod环境的副本。它可以是一个虚拟机,也可以是另一个真实的机器。但你必须成为上帝。如果prod数据库位于另一个框中,则还需要开发版本。
    2. 把它全部投入到版本控制中。在另一个盒子上。至少每周备份一次。
    3. 确保您知道分支在版本控制应用程序中是如何工作的。你可能需要它。
    4. 创建将代码从版本控制发布到prod服务器的说明。可发布更改的最小单位应该是整个代码基。

    为了使结构更有意义,你必须在它旁边创建一个新的结构。新的DB处理程序通常是一个很好的开始,它包含在每个页面都应该加载的通用include文件中。这里的目标是创建一个最小的include结构,以后可以展开它,而不需要告诉每个页面加载其他文件。

    现在您需要开始将功能移到新的include文件。您需要一种同时打开多个文件的方法,例如多文件编辑器、screen+vi(或emacs)。从在不同地方重复的实用程序函数和代码块开始。尽量不要分散注意力,马上去修理很多东西。随着其他问题得到解决,某些类型的问题将不得不转移位置。你稍后再来找他们。

    不需要添加第三方框架。添加这样的内容会很快导致完全重写。在这一点上,这将是一个完整的工作,而不仅仅是驯服它的包括结构。所以先解决这个问题。

    当您移动功能时,需要让文件使用新的包含文件。为您执行此操作的前几个文件将在一段时间内跟踪冲突。这会让人感到沮丧和毫无意义,但这可能是最困难的部分。几份文件之后,事情会变得容易些。有时您可以将六个页面迁移到新的include文件中,方法是将一打include替换为一个。该操作的另一面是,将有文件您可以删除。

    如果你坚持这样做,你最终会发现所有的include文件都是你写过的,你会看到整个include布局。到那时,进行更具侵略性的更改(比如加入第三方框架)将变得容易得多。

        20
  •  2
  •   PartialOrder    16 年前
    1. 在修订控制下。

    2. 决定命名约定和文件/目录结构。

    3. 如果您还没有建立一个单独的开发/测试环境

    然后。。。

    1. 不幸的是,您将需要筛选所有这些1、2、3文件,并确定哪些文件正在使用,哪些可以处理。没有其他办法,除了一个野蛮的力量磨通过,一个文件。

    2. 即使我有一个RCS,我仍然经常把我认为是未使用的脚本移到一个隐藏的位置,比如说,陵墓,然后让RCS忽略那个位置。很高兴能在不返回回购的情况下在本地浏览一下。

    3. 尽可能地分离HTML和PHP . 我再怎么强调也不为过!如果在每个文件中都这样做了,就可以了。只要有单独的PHP和HTML块。当然,HTML中到处都会出现echo,但是尝试将所有的测试、开关和其他东西从HTML块移到PHP块中。光是这一点 巨大的

    4. 如果代码主要是过程性的——我假设在您的情况下是这样——那么在进行任何认真的重构或重构到类之前,最好先进行一些清理。

    5. 找到可以逻辑组合的文件/脚本时,请执行此操作。(我见过一些项目——可能和你的项目没什么两样——幸存的文件总数大约是我们开始时的1/4)。

    一旦你走到了这一步,你就可以开始一个适当的重构或者重构到类中。

    好机会!

        21
  •  2
  •   Jason Plank Maksim Kondratyuk    13 年前

    以下是对我帮助最大的事情:

    • 确定哪些是系统的关键文件。你会找到他们,因为你的大部分工作都会在他们身上完成
    • 只处理少量更改的文件
    • 在对产品版本进行彻底测试之前,不要将任何内容放在产品版本中,然后准备将旧版本放回
    • if($_POST['your_registered_user_name']{
         //Your live code being tested, which will be visible only to you when you are logged in
      }
      

      其他用户将无法感受到这些变化。当我无法替换本地计算机上的系统状态时,这种技术对我帮助很大

    • 编写测试,并对所编写的所有代码遵循严格的工程指导原则

        22
  •  1
  •   lo_fye    16 年前

    只是 我自己也经历过。

    如果你真的想解决这个问题,你需要朋友。 在你建议如何改变他们几个月(几年)来一直在做的事情之前,你需要你的同事的尊重.

    首先,尽快将代码置于版本控制之下。如果这对你来说不是件容易的事,至少要开始每天备份,即使这意味着只需压缩文件并用日期命名zip文件。如果没有人知道版本控制,那就在CVS或SVN上买一本实用的程序员手册,自己设置。这些书一天就能看完,而且你可以很快地起床跑步。如果没有人想使用版本控制,你可以自己使用它。。。然后当某人丢失一个文件时,你可以用回购协议的副本来保存这一天。其他人迟早会看到版本控制的智慧。

    第三,当你浏览代码时,要做大量的笔记。写下所有困扰你的代码。把你的想法写在纸上。你可以在第一个月后再组织。

    第四,安装一个代码分析器(比如xdebug)。这将告诉您在每个页面上调用了哪些文件和函数,以及每段代码运行需要多长时间。您可以使用它来找出includes问题,并找到慢的代码位。先优化这些。

    尽可能多地修订本文件。 我再强调也不为过。

    确保你的听众知道你这样做是为了公司的利益,而不仅仅是为了你的个人喜好。

    亲自把它交给你的老板。 安排时间讨论。

    他们可能会因为你写了它而解雇你。如果他们这样做了,你最好没有他们,因为他们不想改善,你的职业生涯将停滞不前。

    很可能他们会想实现你的一些建议,这比什么都不做要好。至少,这有助于缓解你的担忧。

    至于测试,在Apache中设置另一个“虚拟主机”(Windows&Linux都支持)。虚拟主机允许您在一台服务器上运行多个站点。大多数大型站点至少有3个虚拟主机(或实际服务器):dev.domain.com(用于日常开发)、staging.domain.com(用于QA人员在发布之前进行测试)和www.domain.com(您的生产服务器)。您还应该使用不同的登录密码设置数据库的开发、登台和生产版本,以免意外混淆它们。

    祝你好运!

        23
  •  1
  •   KevBurnsJr KevBurnsJr    16 年前

    我也推荐一个好的 代码搜索工具 .

    搜查探员 http://www.mythicsoft.com/agentransack/Page.aspx?page=download

    如果不查密码我会瞎飞的。

        24
  •  1
  •   Martin Kočička    14 年前
    1. 为所有代码编写单元测试
    2. 开始使用一些框架(我建议使用symfony/nette)
    3. 开始重构php代码
        25
  •  0
  •   Valien    16 年前

    试着在网站上得到详细的统计信息,找出入口和出口点在哪里。这是一个很好的方法,可以找出哪些文件被点击到最上面(然后查看这些文件,看看哪些文件被删除了)。

        26
  •  0
  •   John MacIntyre    16 年前

    照哈珀·谢尔比说的做。。。

    但是,我还要补充一点,如果你没有得到管理层的支持来清理这个问题,你可能会接受这样一个事实:这可能是有原因的。... 只是说。;-)

        27
  •  0
  •   bobbyh    16 年前

    除了其他人说的好东西之外,为了第一次了解哪些文件正在被积极使用,您可以在您的开发服务器(甚至是生产服务器,这不会破坏任何东西)上安装APC或eaccelerator之类的操作码缓存。然后,单击dev服务器上的web应用(或让用户在生产服务器上执行)。

    现在查看缓存管理页中缓存文件的列表。如果一个文件没有被你的操作码缓存列出,很有可能它没有被任何东西加载。

    这并不是一个完整的解决方案,但是如果每个目录都有10个index.php文件(例如index.php、index2.php等),那么至少你会知道你的应用程序正在使用哪一个。