php - 我应该如何将我的代码从开发转移到生产?

标签 php production-environment sdlc custom-code

我创建了一个 PHP 网络应用程序。

我有 3 个环境:DEV、TEST、PROD。

对我来说,将 PHP Web 应用程序代码从 DEV 迁移到 TEST 到 PROD 环境的好工具/商业实践是什么?

意识到我的 TEST 环境仍然只连接到我的 TEST 数据库;而我需要 PROD 环境来连接到我的 PROD 数据库。所以代码几乎相同,除了我需要更改我的 TEST 代码后,一旦移入 PROD 以连接到 PROD 数据库而不是 TEST 数据库。

我听说有人关闭 Apache 以致于它不允许新连接,一旦所有现有连接都空闲,它只会关闭 Web 服务器。

然后人们手动复制代码,然后手动更新 PHP 应用程序的配置文件,使其也指向 PROD 实例。

这看起来非常危险。

是否存在最佳实践?

最佳答案

1) 将配置与代码的其余部分分开。然后,其余代码应该能够在所有 3 个位置上运行而无需修改。一个典型的配置文件可能是:

<? 
$db = "main_db"; $db_user="web1"; $db_pass = "xyz123"; 
$site ="example.com"; 
$htroot = "/var/www/prod/htdocs" 
?>

对于测试环境:
<? 
$db = "test_db"; $db_user="web1"; $db_pass = "xyz123"; 
$site ="test.example.com"; 
$htroot = "/var/www/test/htdocs" 
?>

不要在代码库中包含带有密码的配置文件。代码库可能会通过不安全的连接复制或稍后存储在第三方代码托管服务器上(见下文)。而且您可能不希望所有代码备份磁盘上都有您的密码。

您还可以创建一个配置文件并根据代码运行的环境使用开关:
<? 
$site = $_SERVER["HTTP_HOST"];

if ($site == "example.com"; ) {
  $db = "main_db"; $db_user="web1"; $db_pass = "xyz123"; 
  $htroot = "/var/www/prod/htdocs";
}
if ($site == "test.example.com") { 
  $db = "test_db"; $db_user="web1"; $db_pass = "xyz123"; 
  $htroot = "/var/www/test/htdocs";
}
?>

但是现在您可能会想将其放回代码库中,如上所述,代码库的安全性较低。如果你不把它放在那里,你必须更新 3 个文件,或者每个服务器使用一个固定位置,并且你必须确保代码在每个服务器上找到文件。我个人更喜欢上面的每个站点一个文件的解决方案。

2)你已经有“版本”了。现在有一个版本在 prod 上运行。给它一个唯一的名称和编号,永远不会再改变。您可以在备份代码时使用该版本名称,当您引用版本或将其移动到某个位置时,您可以在版本之后命名将包含它的子目录。

你在不久的将来投入生产的版本是一个不同的版本,如果你再次进行更改,这也是一个不同的版本。

经验法则:在移动或导出代码、在位置之间交换或交换或升级时、在进行演示时、在每个功能或里程碑之后以及每次进行完整备份时增加版本号。

请注意,配置文件(3 个,一个用于 prod、test 和 dev)不是版本的一部分。所以你可以“移动版本”而不是配置文件。如果可以,请将配置文件与其余代码一起放在树的外部,这样您就不需要将它们分开并在以后移动版本时小心。您可以将配置“向上”移动一个目录并从如下文件访问它们:

"包括../config.php";

3) 如果你想使用版本控制系统,它们做得很好,但需要一些时间来适应它,如果你急于更新,现在可能不是开始使用它的合适时机。但我会在 future 推荐使用最新一代的分布式版本控制系统。分布式意味着您不需要设置服务器和更多优势。我会命名bazaar,如果需要通过ftp更新它可以做。请注意,版本控制系统可以非常快速地交换版本,因为只写入版本之间的差异。 Bazaar 有一个社区和文档,可以很容易地开始。还有Git,它拥有最新的商业托管站点:http://github.com .您可以在线查看代码并在版本之间进行比较,还有更多有用的功能,即使您是唯一的编码员,但在一个小组中它甚至更好。系统之间的选择并不容易。我不能推荐 CVS,它已经过时了。此外,SVN 不是最新一代的分布式版本控制系统,如果没有特定原因,我不建议使用它,并且它会用特殊的子目录污染您的所有子目录,这可能很烦人。对于习惯了它并且已经在其中编写代码的人来说,这很好,但对于初学者来说,我会说不要。

在分布式和开源版本控制系统中还有 Mercurial 和 Darcs。 Mercurial 还有一个很棒的商业站点,用于协作和在线代码查看 (http://bitbucket.org)。

4)只要不使用版本控制系统,使用符号链接(symbolic link)怎么样?

您可以在服务器 src/versions/的某处有一个目录,并将命名版本放在那里,每个版本都放在自己的子目录中。您只会添加版本(因为存在的版本不会更改,如果更改它就会成为新版本)

您可以使用 src/versions/v001/src/versions/v002/src/versions/v003/或您使用的任何命名方案。

现在诀窍来了:/var/www/prod/htdocs 是 src/versions/v001/的符号链接(symbolic link)

当您升级到 v002 时,您只需执行以下操作:
  • 关闭 Apache
  • 删除旧的符号链接(symbolic link)/var/www/prod/htdocs(此时 apache webroot 消失了!)
  • 创建新的符号链接(symbolic link)/var/www/prod/htdocs 作为指向 src/versions/v002
  • 的链接
  • 启动apache

  • 您还可以为此编写带有参数的脚本并像这样调用它:
    upgrade-web prod 002
    

    这使得间隙更短。

    有时你不得不做一个“回退”,当你发现新版本在生产中出现错误时,你不得不返回。这很容易(因为您没有删除旧目录,您只需停止 apache,删除符号链接(symbolic link)并将其重新创建到以前的位置,在本例中为 src/versions/v001 )

    如果 test 和 dev 在同一台服务器上,您当然也可以符号链接(symbolic link)相同的目录,因此不会有任何用于移动或复制的目录。

    5)如果您在没有符号链接(symbolic link)的情况下手动进行,为什么不移动而不是复制?

    (当文件不在同一台服务器上时,您可以将它们复制到附近的某个地方,然后开始迁移,这样您就不必停止服务器那么长时间)

    如果项目的根级别有多个目录,您可以一次移动一个。确保不要移动配置文件。或者找到一些策略让他们获得返回。工作流程是:
  • 停止 apache
  • 移走根级别上的所有当前 prod 目录和文件,但配置文件除外
  • 将所有新的 prod 目录和文件移至根级别,但配置文件除外
  • 启动apache

  • 6) 尝试找到您完美的个人文件和目录布局以及完美的工作流程。这可能需要一些时间和一些思考,但它是值得的。在一张纸上做,直到找到最佳解决方案。这可能意味着您必须重构您的代码并更改服务器配置文件,但在 future 进行管理和升级时,您的生活会更轻松。根据我的经验:这一步不要等太久。您的布局应该使升级变得容易和安全。升级并不是什么特别的事情,它是例行公事,应该是安全和简单的。

    7)如果你命名你的服务器和工作站环境(我猜服务器的操作系统是linux,但它是托管服务器还是根服务器,你有ftp访问权限或shell(ssh)访问,还是sftp?你在哪里开发,在 Windows 机器上,还是 Mac 上?)然后人们可以命名工具来进行复制和移动。同样有趣的是:测试和开发服务器是同一台机器,如果不是,它们是如何连接的,或者它们不是?如果没有,您将进行 3 向传输(将其复制到本地工作站,然后再复制到服务器)。

    8) 考虑文件权限。如果您移动文件或复制它们,文件权限可能会更改,如果应用程序依赖于其中的某些文件,则应该有一种方法可以检查并可能会更改。示例:某些应用程序需要可写的目录,用于放置上传的文件或 session 文件或模板缓存。出于安全考虑,其他应用程序不允许某些文件可写。

    关于php - 我应该如何将我的代码从开发转移到生产?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1664204/

    相关文章:

    css - Rails 应用程序未在 application.css 中获取样式

    c++ - Visual Studio 中的安全开发生命周期检查选项是什么?

    analysis - SDLC 和软件过程

    .net - 处理具有多个版本的软件的发布管理的最佳方法是什么?

    javascript - jQuery:$.ajax() 重定向到其 URL 表单操作参数,而不是对表单操作执行 AJAX 请求

    php - 使用 AJAX 和 PHP 进行身份验证

    php - 插入查询无法正常工作

    c# - 为什么我的 PHP SHA256 哈希不等同于 C# SHA256Managed 哈希

    .net - 如何实现.NET Deployment Nirvana?

    ios - 从沙箱切换后,推送通知在生产环境中不起作用