如何将值传递给正在运行的脚本?

时间:2014-01-08 05:06:14

标签: php sockets laravel download

我有一个PHP脚本(我使用Laravel开发),用于下载存储在webroot外部的文件。 我现在想要控制正在进行的下载的传输速度(例如,在while(fread())调用内部根据传递给正在运行的脚本的某个值执行usleep(),这样我就可以在外部实时更改传输速度)但我无法将值传递给正在运行的php脚本。

while($buffer = fread($fp, 2048)) {
    print $buffer;
    flush();
    $this->bytes_transferred += strlen($buffer);
            usleep($this->transfer_delay);
}

所以这是我的问题: - 如何传递可在while()循环内截获的值?

我可以想到一些理论上的解决方案,但它们都有问题:

理论解决方案#1 - 使控制器类具有类全局变量(如$ this-> transfer_delay)来控制速度

  • 注册一个事件监听器,它将以某种方式更改该全局变量的值,而while循环将简单地调用usleep($ this-> transfer_delay)

理论解决方案的问题#1 - 我试图使用事件但我的事件似乎没有运行。

此外,我怀疑事件是在不同的上下文中运行的,而不是在实例化它们的方法/类中。

理论解决方案#2 - 打开套接字并监听事件!

  • 在进入while循环之前,打开一个套接字并监听事件!

理论解决方案的问题#2 - 套接字要求您阻止等待新连接,因此我无法在等待新连接时传输文件

  • 也许我可以fork()处理接受新连接并处理它们的代码部分?但那时我将无法将值传递给父母,对吧? (或者我可以使用某种信号处理程序吗?)

理论解决方案#3 - 每次迭代循环时从数据库中提取事件

  • 让外部进程将值推送到db并在每次迭代时从DB读取while()循环

理论解决方案的问题#3 - 它让我觉得内心很脏:o)

  • 我不认为每秒多次点击数据库以获得“高速while()循环”中的值是一种好习惯。

理论解决方案#4 - 使用命名管道

  • 创建一个fifo文件,并在每次迭代时从中读取。

理论解决方案#4的问题 - 这在我看来似乎是最好的解决方案:o \

  • 老实说,我不能想到任何优于此的东西,但......我必须有别的东西吗?

关于如何完成我想要做的事情的任何想法?

2 个答案:

答案 0 :(得分:0)

您是否可以使用会话,然后让一个小的PHP脚本更改会话变量中的值。您将遇到锁定,其中您的while循环可能会被较小的PHP脚本中的文件锁阻塞,直到较小的PHP脚本释放其对会话文件的锁定。您可能正在关闭并快速打开会话以防止此类锁定明显减慢传输速度。

(这会阻止您从一个会话同时上传多个文件,但这通常不是问题。)

答案 1 :(得分:0)

我使用memcached解决了我的问题。 我不知道这个解决方案有多棒(因为我觉得每次发送缓冲区时读取memcached都是浪费资源,或者甚至做一个if条件,所以我每隔X秒只检查memcached的速度限制或send()s)但是......它有效!