关于:“通过每分钟限制 30 次查找来降低遭受完全暴力破解攻击的可能性。”
并非如此 - 攻击者可以发出 100 个请求。每个请求可能需要 2 秒,但这并不会阻止完成的请求数量。您需要阻止每 2 秒处理超过一个请求,而不是在每次执行时延迟 2 秒。
(PHP 4, PHP 5, PHP 7, PHP 8)
sleep — 延迟执行
seconds
暂停时间,以秒为单位(必须大于或等于0
)。
成功时返回零。
如果调用被信号中断,sleep() 返回非零值。在 Windows 上,此值将始终为192
(Windows API 中WAIT_IO_COMPLETION
常量的值)。在其他平台上,返回值将是剩余的睡眠秒数。
如果指定的seconds
秒数为负数,此函数将抛出ValueError。
版本 | 描述 |
---|---|
8.0.0 | 该函数在seconds 为负数时抛出ValueError;之前,会发出E_WARNING 警告,并且函数返回false 。 |
示例 #1 sleep() 示例
<?php
// 当前时间
echo date('h:i:s') . "\n";
// 睡眠 10 秒
sleep(10);
// 醒来!
echo date('h:i:s') . "\n";
?>
此示例将输出(10 秒后)
05:31:23 05:31:33
关于:“通过每分钟限制 30 次查找来降低遭受完全暴力破解攻击的可能性。”
并非如此 - 攻击者可以发出 100 个请求。每个请求可能需要 2 秒,但这并不会阻止完成的请求数量。您需要阻止每 2 秒处理超过一个请求,而不是在每次执行时延迟 2 秒。
注意:`set_time_limit()` 函数和配置指令 `max_execution_time` 仅影响脚本本身的执行时间。在脚本执行之外发生的任何活动所花费的时间,例如使用 `system()` 的系统调用、`sleep()` 函数、数据库查询等,在确定脚本运行的最大时间时不会包含在内。
为了避免使用在并非所有操作系统上都工作的 `usleep` 函数,下面是一个应该具有相同行为的函数
function wait(int $millisecond = 0) {
if (0 !== $millisecond) {
$seconds = (int) ($millisecond / 1000);
$nanoSeconds = ($millisecond % 1000) * 1000000;
time_nanosleep($seconds, $nanoSeconds);
}
}
您应该将 `sleep` 放入通过和失败分支中,因为攻击者可以检查响应是否缓慢并将其用作指示器 - 从而减少延迟时间。但是,在两个分支中延迟都消除了这种可能性。
也许很明显,但这是我使用小数秒来延迟脚本执行的函数(例如模拟 `sleep(1.5)`)
<?php
/**
* 延迟脚本执行给定的时间。
* @param mixed $time 暂停脚本执行的时间。可以用整数或小数表示。
* @example msleep(1.5); // 延迟 1.5 秒
* @example msleep(.1); // 延迟 100 毫秒
*/
function msleep($time)
{
usleep($time * 1000000);
}
?>
Diego Andrade 的 `msleep` 函数与 php7 的 `strict_types` 不兼容,将 `usleep` 参数强制转换为 int,它将成为:
usleep((int)($time * 1000000));
将 `sleep()` 用于延迟输出效果不是一个好主意,因为
1)您必须在休眠之前刷新() 输出
2)根据您的设置,刷新() 不会一直作用到浏览器,因为 Web 服务器可能会应用其自身的缓冲,或者浏览器可能不会呈现它认为不完整的输出
例如,Netscape 只会显示完整的行,并且在到达 </table> 标记之前不会显示表格部分
因此,如果您必须等待事件并且不想消耗太多周期,请使用 `sleep`,但不要将其用于愚蠢的延迟输出效果!
如果您在 `sleep()` 和 `usleep()` 没有按您预期的那样响应时遇到问题,请查看 `session_write_close()`
正如匿名在评论中提到的那样;
如果ajax函数没有调用session_write_close(),那么你的外层页面将会看起来卡住,在新标签页中打开其他页面也会停滞。
根据我的测试,调用sleep(0); 会进行“线程自旋”。
最好在文档中明确说明这一点,因为它很有用。 你可以在不增加CPU线程负载的情况下实现最小的等待。
我编写了一个使用浮点数休眠的简单方法,它也允许你使用毫秒(通过分数秒)。
<?php
function sleepFloatSecs($secs) {
$intSecs = intval($secs);
$microSecs = ($secs - $intSecs) * 1000000;
if($intSecs > 0) {
sleep($intSecs);
}
if($microSecs > 0) {
usleep($microSecs);
}
}
?>
在我的机器上测试,它运行完美。
<?php
$x = [0.100,0.250,0.5,1.0,1.5,2.0,2.5];
foreach($x as $secs) {
$t = microtime(true);
sleepFloatSecs($secs);
$t = microtime(true) - $t;
echo "$secs \t => \t $t\n";
}
?>
输出
<?php
0.1 => 0.10017800331116
0.25 => 0.25016593933105
0.5 => 0.50015211105347
1 => 1.0001430511475
1.5 => 1.5003218650818
2 => 2.000167131424
2.5 => 2.5002470016479
?>
带毫秒参数的休眠方法
public static function ms_sleep($milliseconds = 0) {
if($milliseconds > 0) {
$test = $milliseconds / 1000;
$seconds = floor($test);
$micro = round(($test - $seconds) * 1000000);
if($seconds > 0) sleep($seconds);
if($micro > 0) usleep($micro);
}
}
使用sleep以不同间隔运行一组函数的示例。这不是多线程的替代品,但它可以帮助那些想要做一些简单操作的人。你不需要使用eval()。它只是一个例子。这与运行标准的1秒sleep循环不同,因为休眠时间更长不会消耗那么多CPU。
<?php
// 当前时间
echo date('h:i:s') . "\n";
// 一些示例函数
function function_a() { echo 'function_a called @ ' . date('h:i:s') . PHP_EOL; }
function function_b() { echo 'function_b called @ ' . date('h:i:s') . PHP_EOL; }
function function_c() { echo 'function_c called @ ' . date('h:i:s') . PHP_EOL; }
// 添加一些计时器(以秒为单位)和函数调用
$sleeptimers = array();
$sleeptimers['5'][0]['func'] = 'function_a();';
$sleeptimers['10'][0]['func'] = 'function_b();';
$sleeptimers['15'][0]['func'] = 'function_c();';
// 处理计时器
while(true) {
$currenttime = time();
reset($sleeptimers);
$mintime = key($sleeptimers);
foreach($sleeptimers as $SleepTime => $Jobs) {
foreach($Jobs as $JobIndex => $JobDetail) {
if(!isset($JobDetail['lastrun'])) {
$sleeptimers[$SleepTime][$JobIndex]['lastrun'] = time();
if($SleepTime < $mintime) $mintime = $SleepTime;
} elseif(($currenttime - $JobDetail['lastrun']) >= $SleepTime) {
eval($JobDetail['func']);
$lastrun = time();
$sleeptimers[$SleepTime][$JobIndex]['lastrun'] = $lastrun;
$mysleeptime = $SleepTime - ($currenttime - $lastrun);
if($mysleeptime < 0) $mysleeptime = 0;
if(($currenttime - $JobDetail['lastrun']) < $mintime) $mintime = $mysleeptime; // 计算函数运行的时间
echo 'Sleep time for function ' . $JobDetail['func'] . ' = ' . $mysleeptime . PHP_EOL;
}
}
}
echo 'Sleeping for ' . $mintime . ' seconds' . PHP_EOL;
sleep($mintime);
}
?>