【问题标题】:PHP FastCGI Simple CounterPHP FastCGI 简单计数器
【发布时间】:2014-06-12 22:11:00
【问题描述】:

我无法在 FCGI 模式下理解和运行简单的 PHP 脚本。我正在学习 Perl 和 PHP,我得到了下面的 Perl 版本的 FastCGI 示例,可以按预期工作。

Perl FastCGI 计数器:

#!/usr/bin/perl

use FCGI;

$count = 0;

while (FCGI::accept() >= 0) {

    print("Content-type: text/html\r\n\r\n",
          "<title>FastCGI Hello! (Perl)</title>\n",
          "<h1>FastCGI Hello! (Perl)</h1>\n",
          "Request number ", $++count,
          " running on host <i>$ENV('SERVER_NAME')</i>");

}

在 PHP 中搜索类似内容时发现谈论“fastcgi_finish_request”,但不知道如何 为了在 PHP 中完成反例,这是我尝试过的:

<?php
header("content-type: text/html");
$counter++;
echo "Counter: $counter ";
//http://www.php.net/manual/en/intro.fpm.php
fastcgi_finish_request(); //If you remove this line, then you will see that the browser has to wait 5 seconds
sleep(5);
?>

【问题讨论】:

  • 简短回答:你不能使用 PHP,它不允许你像 Perl 那样访问 FCGI 状态。您必须以原子方式在请求之间存储$count,例如通过数据库查询更新 + 1,同时提前获取结果并执行 $count + 1 仅出于显示原因。

标签: php perl fastcgi mod-fcgid


【解决方案1】:

老实说,使用 Perl 也不应该这样做。

相反,我建议使用CGI::Session 来跟踪会话信息:

#!/usr/bin/perl

use strict;
use warnings;

use CGI;
use CGI::Carp qw(fatalsToBrowser);
use CGI::Session;

my $q = CGI->new;
my $session = CGI::Session->new($q) or die CGI->Session->errstr;
print $session->header();

# Page View Count
my $count = 1 + ($session->param('count') // 0);
$session->param('count' => $count);

# HTML
print qq{<html>
<head><title>Hello! (Perl)</title></head>
<body>
<h1>Hello! (Perl)</h1>
<p>Request number $count running on host <i>$ENV{SERVER_NAME}</i></p>
</body>
</html>};

或者,如果您真的想使用准系统,您可以保留一个本地文件,如下所示:I still don't get locking. I just want to increment the number in the file. How can I do this?

【讨论】:

  • 我的目标是了解 PHP 在 FCGI 模式下的工作逻辑,这在我看来似乎完全不同,而不是构建一个计数器。
  • 罗杰,我承认这更像是对 PHP 的探索。我只是想指出在 perl 中保存状态的方法也不是真正的方法,所以试图匹配它会有点误导。祝你好运
【解决方案2】:

PHP 和 HTTP 是无状态的。 所有数据仅与当前正在进行的请求相关。 如果需要保存状态,可以考虑将数据存储到 cookie、session、cache 或 db 中。

所以这个“计数器”示例的实现对于 PERL 和 PHP 会有所不同。

您对fastcgi_finish_request 的使用不会带来您期望的PERL 功能。 考虑一个长时间运行的计算,在中间输出数据。 您可以使用 fastcgi_finish_request 来做到这一点,然后将数据推送到浏览器,而长时间运行的任务会继续运行。

FASTCGI+PHP 一起打开。 通常连接会打开,直到 PHP 完成,然后 FASTCGI 将被关闭。 除非您达到 PHP 的执行超时(执行超时)或 fastcgi 超时(连接超时)。 fastcgi_finish_request 处理这种情况,即在 PHP 完成执行之前关闭与浏览器的 fascgi 连接。

PHP 的简单命中计数器示例

<?php
$hit_count = @file_get_contents('count.txt'); // read count from file
$hit_count++; // increment hit count by 1

echo $hit_count; //  display

@file_put_contents('count.txt', $hit_count); // store the new hit count
?>

【讨论】:

    【解决方案3】:

    Perl 不是 PHP。这并不意味着您不能经常在两者之间交换事物和端口代码,但是当涉及到运行时环境时,您不能仅仅交换更大的差异。

    FCGI 已经处于请求/协议级别,在 PHP 运行时完全抽象,因此您对 PHP 的控制不如使用 Perl 和 use FCGI;

    因此,您不能只移植该代码。

    旁边的fastcgi_finish_request 与Perl 代码完全无关。你一定是把它弄糊涂了,或者纯粹靠运气把它扔进去试一试。然而,在这个反例上下文中它并不是真的有用。

    【讨论】:

    • 我理解 Perl 在第一次请求时 Apache/mod_fcgid 将加载脚本并将其保存在内存中以供下一个请求使用。这在 PHP 中是如何工作的,是否一旦我调用 php 脚本,它就会编译一次并保留在内存中,以便从脚本正常的第一行开始的下一个请求。在脚本中使用 php 函数 fastcgi_finish_request 有什么好处,我的 php 脚本中是否需要它来为 FCGI 做好准备。
    • FCGI 的工作方式与它的协议/工作方式相同。然而,使用 Perl,我可以像使用 PHP 一样对其进行编程,这是我使用的一个功能。 PHP SAPI 确实去掉了许多在 Perl 中完全可用的细节,因为 Perl 中的“SAPI”只是完全用 Perl 编写的。 fastcgi_finish_request 执行 PHP 手册页上记录的操作。如果你不明白那里写了什么,那么你很可能不需要它。简而言之,它允许您在脚本完成之前向浏览器发送响应。
    • 我开始明白fastcgi_finish_request 会立即将输出发送到浏览器,但我的问题是,php 脚本会结束还是会留在已编译的内存中,为下一个请求做好准备。我的意思是我需要做些什么才能使常规 php 脚本作为 FCGI 脚本运行。我是否需要在 apache 服务器本身上配置一些东西来区分常规 php 脚本和 fcgi php 脚本。
    • @daliaessam:PHP 不共享任何内容,即使在 FCGI 中也是如此。部分运行时保留在内存中,但不是您的脚本。
    • 如果我的 php 脚本没有在请求中保持在内存中编译,那么使用 FCGI 有什么好处?据我了解,在 FCGI 模式下,脚本应该编译一次并保留在内存中,为下一个请求做好准备。
    猜你喜欢
    • 2011-04-15
    • 2014-02-22
    • 2015-01-28
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 2011-07-31
    • 1970-01-01
    相关资源
    最近更新 更多