【问题标题】:I want to define a variable with superglobal scope in php我想在 php 中定义一个具有超全局范围的变量
【发布时间】:2011-08-18 10:20:01
【问题描述】:

我想在 php 中定义一个全局范围内的变量。每个用户都应该可以访问该变量,因此它不应该依赖于会话。

我想做类似以下的事情:我有一个 php 脚本,该脚本通常需要大约 5 到 15 分钟才能执行,但在某些特殊情况下可能需要一个多小时。此脚本正在使用间隔 15 分钟的 cron 作业运行。该脚本也可以由任何用户手动运行。

现在可以同时运行任意数量的脚本。我想限制这个脚本数量。

所以,我想要一个变量来存储当前正在执行的脚本的数量。我不想使用数据库或文件来存储单个值。

提前致谢。

【问题讨论】:

  • 我不想使用数据库或文件,因为有一个缺点。假设我想运行最多 5 个实例,当前有 4 个实例正在运行,我将此值保存到 db。突然,我的服务器由于某种原因宕机了。当它再次启动时,db会显示有实例正在运行,但实际上不会有实例......
  • PHP 会话存储在纯文件中。除非您的会话在服务器重新启动时被清除,否则全局会话也会出现同样的问题。您还有许多其他边缘情况。如果进程在递减计数器之前就崩溃了怎么办?一旦 5 个实例在中途崩溃,您最终将陷入僵局。如果您对跟踪正在运行的进程数量感兴趣,您实际上需要能够查询以查看正在运行的进程数量。

标签: php variables scope cron


【解决方案1】:

将变量写入特定的内存地址并使用计数等信息读取/写入该地址可能会起作用。

一篇关于 IPC(进程间通信)的(旧)文章可能会对您有所帮助

http://zez.org/article/articleview/46/

出于兴趣,您为什么不想使用文件或数据库?

另一种解决方案(尽管在技术上很可能使用文件或数据库)是强制脚本使用特定的会话 ID。

<?php

$maximum = 1;

session_id(md5('myscript'));
session_start();

if( !isset( $_SESSION['count'] ) ) {
    $_SESSION['count'] = 1;
} else {
    if( $_SESSION['count'] >= $maximum ) {
        die( "too many processes running" );
    } else {
        $_SESSION['count']++;
    }
}

session_write_close();

// simulate running something
sleep(10);

session_id(md5('myscript'));
session_start();

$_SESSION['count']--;

session_write_close();

echo "<br />executed";

?>

请注意,在上面的示例中,对 session_write_close() 的调用很重要,因为脚本的执行将阻止计数器增加,直到它完成为止。然后当它关闭它时,它需要重新打开以减少计数器。

显然由于会话重新打开,脚本的任何输出都需要缓冲(请参阅http://www.php.net/ob_start)以防止标头已发送错误

【讨论】:

  • +1 共享会话是一个不错的技巧(当然,会话处理程序最终会使用文件或数据库,但我认为 OP 不会介意)。
  • 这是一个巧妙的技巧,但可能很危险,因为您可能会破坏用户的会话或发送引用“全局”会话的cookie。 PHP 会话只是保存到一个文件中(使用默认设置),如果您只想保存一个整数的状态,这是一个过于复杂的解决方案。
【解决方案2】:
  1. 检查是否达到限制
  2. 当用户访问脚本时,将他添加到数据库中
  3. 当用户存在(或脚本结束)时,将他从数据库中删除

没有文件或数据库的人无法将其保存在其他地方

【讨论】:

  • "我不想使用数据库或文件来存储单个值。" :)
  • 在这种情况下,答案是不可能
  • 我知道这是不可能的。我只是认为这可能是唯一答案
  • 值得一提的是,脚本可能会崩溃,因此迟早需要验证这些信息。
  • @Álvaro: 当然可以,但我认为 OP 知道这一点
【解决方案3】:

您的先决条件非常严格。内存不(或notnormally)在脚本之间共享,我们不能使用文件或数据库:这实际上没有公共空间可用于共享信息,因此您必须每次都计算信息。您最好的选择可能是检查正在运行的进程,确定哪些属于您的脚本并计算它们。您对 cron 的提及建议使用 Unix,这使事情变得更容易。 POSIX 扩展可能允许在这种程度上控制进程执行,并且作为最后一个资源,您始终可以从 PHP 运行 ps 命令。

【讨论】:

  • 也可以解决问题。但我喜欢“Ben Swinburne”用来在会话中存储值的方式。谢谢你的回答
【解决方案4】:

据我所知,如果没有数据库或文件,这是不可能的。相反,如果您有权访问服务器(root 访问权限),您可以使用ps 命令(如果运行 linux 操作系统)检查脚本是否已在运行,如果是,您可以查看它的实例数。

【讨论】:

  • 也可以解决问题。实际上,我正在考虑做这样的事情。但我喜欢“Ben Swinburne”用来存储价值的方式。感谢您的回答
猜你喜欢
  • 2012-07-17
  • 2016-09-05
  • 2013-05-26
  • 2012-01-19
  • 1970-01-01
  • 2015-11-24
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多