【问题标题】:How to change different configuration settings between environments in PHP?如何在 PHP 中更改环境之间的不同配置设置?
【发布时间】:2014-12-22 10:04:38
【问题描述】:

我有一些我通过 AJAX 调用调用的 php 文件。他们都有一个指向我的 config.php 的 URL。现在我遇到的问题是,当我在我的服务器上部署新版本时,我总是必须手动更改该配置文件的 URL。

本地路径:

define('__ROOT__', $_SERVER["DOCUMENT_ROOT"].'/mywebsite');

服务器路径:

define('__ROOT__', $_SERVER["DOCUMENT_ROOT"].'/../dev.my-website.tld/Modules/');

我想跟踪所有这些 PHP 文件的变化。我正在寻找自动更改此路径的解决方案。

例如 这是我目前的工作流程:

本地环境:

  • (路径版本 A)
  • 修改代码
  • git add、git commit、git merge、git push 到我的服务器

服务器:

  • git reset --hard
  • 将路径更改为版本 B

【问题讨论】:

  • 好问题。我已经删除了关于 Gulp 的额外问题,因为它是这个问题的一个附录(我们在这里一次更喜欢一个)而且它相当笼统。我怀疑你会发现你不需要它,但如果你想在部署过程中使用它,它可能值得自己提出问题。

标签: php git gulp


【解决方案1】:

您正在尝试在开发和实时之间运行不同的代码库,不建议这样做——它们应该是相同的。我解决这个问题的方法是使用环境变量来指定应该加载几个配置文件中的哪一个。

在我的 Apache vhost 中,我执行以下操作:

SetEnv ENVIRONMENT_NAME local

然后我使用一个函数来读取环境名称:

function getEnvironmentName()
{
    $envKeyName = 'ENVIRONMENT_NAME';
    $envName = isset($_SERVER[$envKeyName]) ? $_SERVER[$envKeyName] : null;
    if (!$envName)
    {
        throw new \Exception('No environment name found, cannot proceed');
    }

    return $envName;
}

然后可以在配置文件中使用该环境名称到include,或者从一个以环境为键的数组中检索值。

我经常将特定于环境的设置保存在名为 configs/ 的文件夹中,但您可以将它们存储在应用中任何有意义的位置。所以例如你可以有这个文件:

// This is /configs/local.php

return array(
    'path' => '/mywebsite',
    // As many key-values as you want
);

然后你可以这样做(假设你的前端控制器在你的项目中是一个层次,例如在/web/index.php中):

$root = dirname(__DIR__);
$config = include($root . '/configs/' . getEnvironmentName() . '.php');

然后,您将可以访问 $config 中相应的每个环境设置。

【讨论】:

  • 但要访问此函数,您还需要指定“functions.php”的路径。或者你是否在每个 php 文件中都包含这个 php 代码?如果我说得对,我会定义两个环境变量。然后使用此功能返回“本地”或“服务器”。之后,我启动另一个根据环境变量设置路径的函数。环境变量可以在.htaccess中设置吗?编辑:或者如果我只是在 htaccess 中定义根路径,可能会更简单
  • 我添加了一个如何访问配置文件的示例。要加载库,您可以使用__DIR__,这是您的前端控制器(index.php)出现的目录。如果需要,有几种方法可以从那里向上移动树,具体取决于前端控制器在项目中的位置。
  • (因此,要回答您的问题,答案是否定的——您只需要一个 env var。您可以通过读取调用的 PHP 脚本的位置来加载库并从那里计算出完整的路径名)。
  • 当我有这样的结构时,DIR 的行为如何:maindirectory/myapp/moduleA/some-php.php 以及 maindirectory/myapp/moduleA/SubModuleA1/some- php.php 和我的配置在这里: maindirectory/myapp.config.php 我想我还需要一个 ROOT_ENV 变量来从绝对路径获取它? Document_Root 指向我的应用程序之前的 XAMPP 一个文件夹。 /Applications/XAMPP/xamppfiles/htdocs/ 在服务器上的另一个文件夹上,我首先必须返回 1 个文件夹,然后进入该文件夹。 /var/www/virtual/myname/html >> /var/www/virtual/myname/mywebsite.tld/
  • __DIR__ 魔术常量指的是 PHP 文件正在执行的目录。因此,如果您的用户请求了/path/to/maindirectory/myapp/moduleA/some-php.php,则 dir 值为 /path/to/maindirectory/myapp/moduleA(叶名和斜杠被剥离)。不过,您的评论问题相当令人困惑-您是否要上移一级以上的目录?
【解决方案2】:

实现此目的的纯 git 方法是 filters。过滤器非常酷,但经常被忽视。将过滤器视为您可以完全控制的 git 关键字扩展方式。

您的文件的签入版本例如如下所示:

define('__ROOT__', 'MUST_BE_REPLACED_BY_SMUDGE');

然后设置两个过滤器:

  • 在您的本地计算机上,您将设置一个 smudge 过滤器来替换
    'MUST_BE_REPLACED_BY_SMUDGE'

    $_SERVER["DOCUMENT_ROOT"].'/mywebsite'

  • 在您的服务器上,您将设置一个 smudge 过滤器来替换
    'MUST_BE_REPLACED_BY_SMUDGE'

    $_SERVER["DOCUMENT_ROOT"].'/../dev.my-website.tld/Modules/'

  • 在两台机器上,clean 过滤器会将行恢复为
    define('__ROOT__', 'MUST_BE_REPLACED_BY_SMUDGE');

有关过滤器的更多信息,请参阅this answerGit Book

【讨论】:

  • 您会签入初始文件(您的第一个 sn-p),然后将其添加到 .gitignore 吗?一旦它在本地完成扩展,您需要确保不会意外签入扩展版本。
  • @halfer:您将使用占位符签入版本。 clean 过滤器的工作是确保签入带有占位符的版本,smudge 过滤器的工作是引入每个位置的更改。并且 .gitignore 不包含要修改的文件。这是一个定期签入的文件。
  • 对,我不明白——好像我需要把它添加到我的阅读列表中! +1 为一个有趣的贡献,即使我不认为代码修改是一个合适的解决方案。
  • git status 不会显示已在本地环境中修改过的污迹文件吗?如果是这样,是否存在意外签入的风险?)
  • @halfer: 拿 the git book: git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Keyword-Expansion
猜你喜欢
  • 1970-01-01
  • 2014-02-01
  • 2019-01-10
  • 1970-01-01
  • 2022-10-25
  • 2015-06-02
  • 2018-10-25
  • 2018-09-21
  • 2016-04-27
相关资源
最近更新 更多