【问题标题】:PHP // Include file from another server if the standard-include server is downPHP // 如果标准包含服务器关闭,则包含来自另一台服务器的文件
【发布时间】:2016-12-15 06:49:27
【问题描述】:

我有很多网站,我在其中使用了很多包含。我包含的那些文件位于外部包含服务器上。我的问题是:我想让这些文件变得多余,所以如果包含服务器出现故障,它们会从我的第二个包含服务器中获取。 在每个网站上手动执行此操作将花费太长时间,所以我想知道是否有办法例如在服务器端执行此操作(因此,如果服务器关闭,它会转发到另一台服务器)。

以下是我通常如何包含文件的示例:

<?php

    $url = 'http://myincludeserver.com/folder/fileiwanttoinclude.php';

    function get_data($url) 
    {
      $ch = curl_init($url);
      $timeout = 5;
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $_REQUEST);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
      $data = curl_exec($ch);
      curl_close($ch);

      return $data;
    }

    $returned_content = get_data($url);

    if(!empty($returned_content))
    {
      echo $returned_content;
    }
    else 
    {
      include('includes/local_error_message.php');  
    };

  ?>

感谢阅读!

【问题讨论】:

  • 只检查包含是否成功,如果不包含另一个。
  • 使用 Jquery-ajax 并使用 $.ajax({ //... success: function(data, textStatus, xhr) { console.log(xhr.status); }, complete: function(xhr, textStatus) { console.log(xhr.status); } }); 获取响应代码,然后您就知道服务器是否出现故障
  • 感谢您的回答,但这是最简单的部分!如果我这样做,我必须在我使用的每个包含上都这样做(比如 1000+)。我正在寻找一种方法来做到这一点,这样我就不必编辑每个网站上的每个文件
  • @jogoe 你是说get_data 函数被复制了1000+次吗?
  • 您并没有真正通过不安全的 http 连接传输您想要包含/执行的 代码,对吗?老实说,这是使用来自不同位置的代码的可怕方式,通过网络加载文件的开销非常高,而且也很危险。使用 NFS 来托管公共文件,看在上帝的份上,不要为此使用互联网!

标签: php function server include forward


【解决方案1】:

简答:

你很可能想要重构你的代码。

更长的答案:

如果您真的想在服务器级别执行此操作,那么您正在考虑实施“故障转移”。您可以阅读wikipedia 文章或howto guide 以获得更深入的解释。简单来说,您基本上需要 3 个 Web 服务器:

  1. 您的包含服务器
  2. 备份服务器
  3. 监控/主服务器

听起来您已经掌握了这三个方面,但理想情况下,第 3 项将是通过第三方提供的服务,以提供额外的冗余来处理 DNS(在传播 DNS 更新时仍可能会出现停机时间)。当然,这引入了几个陷阱,可能最终还是会导致你重构。例如,您可能会遇到load balancing 挑战;您的应用程序现在需要考虑服务器之间的共享资源,例如写入磁盘、会话或数据库的任何内容。 HAProxy 之类的工具可以提供帮助。

更简单的选择,特别是如果与包含关联的域对用户隐藏,则重构并简单地将项目符号 3 替换为类似于您的 get_data 函数的脚本:

function ping($domain) {
    $ch = curl_init($domain);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($ch);
    curl_close($ch);
    return $response ? true : false;
}

$server1 = 'http://example.com';
$server2 = 'http://google.com';

if (ping($server1)) {
    return $server1;
} else {
    return $server2;
}
exit;

这将要求您更新所有文件,但好消息是您可以通过遍历所有 PHP 文件并通过 regex 或使用 tokenizer 替换代码来自动化该过程。您如何实现此选项完全取决于您的实际代码以及每个站点之间的任何差异。

这里唯一需要注意的是,它可能会使服务器的命中率翻倍,因此最好以设置环境或全局变量的方式使用它,然后通过 cron 定期执行它.

希望对你有帮助。

【讨论】:

  • 感谢您调查我的问题并提出这些好主意!我要研究一下,试试看!
猜你喜欢
  • 1970-01-01
  • 2018-04-11
  • 2018-08-08
  • 1970-01-01
  • 2011-02-14
  • 2011-06-30
  • 2014-03-23
  • 2010-11-18
  • 1970-01-01
相关资源
最近更新 更多