我一直在尝试使用PHP和客户端编程语言在在线表单上验证超过100万个随机生成的值(字符串(,但是我面临着一些挑战:
.PHP
链接到(可编辑的(PHP 代码:https://3v4l.org/AtTkO
PHP 代码:
<?php
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyz-_.';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
$unique = array();
for ($i = 0; $i < 9000000; $i++)
{
$u=$i+1;
$random = generateRandomString(5);
if(!in_array($random, $unique)){
echo $u.".m".$random."@[server]n";
$unique[] = $random;
gc_collect_cycles();
}else{
echo "duplicate detected";
$i--;
}
}
echo memory_get_peak_usage();
应该发生什么:
- 随机生成新的 5 个字符值
- 如果值已存在于数组中,则检查该值
- 价值被添加到数组中
- 所有随机生成的值都将导出到.txt文件中,以用于验证。(尚未在脚本中(
实际发生的情况:
我在执行时间中遇到了内存使用限制或服务器超时。
我尝试过什么
- 我尝试在 for 循环中使用
sleep(3)
。 - 将内存限制设置为 -1,将超时设置为 0。无限内存没有区别,在工作环境中太危险了。
- 在 for 循环中使用
gc_collect_cycles()
- 使用
echo memory_get_peak_usage();
->我真的不明白 我如何使用它进行调试。
我需要帮助:
- PHP 中的内存管理
- 在脚本中暂停将重置 PHP 执行计时器
客户端编程语言
这就是我完全不知道我应该走哪条路或应该使用哪种编程语言的地方。
我想要实现的目标
- 加载具有表单的网页
- 使用所有随机生成的字符串加载.txt
- 用第一个字符串填写表单
- 提交表格:
- 如果表单的肯定响应>将字符串保存在特殊.txt文件或数组中,请转到下一个值
- 如果来自表单的否定响应>从文件中删除字符串,请转到下一个值 | 或只转到下一个值
- 所有具有正响应的值都会被过滤掉,并在最后轻松访问。
我不知道我应该为这个函数使用哪种编程语言。我一直在考虑Javascript和Python,但我不确定如何将其与PHP相结合。如果能朝着正确的方向推动一下,我们将不胜感激。
我尝试用 PHP 实现这一点可能是完全错误的,如果是这样,请让我知道什么是更好和更容易的选择。 谢谢!
有趣的问题,首先,每当您想到这样的解决方案时,您需要考虑的第一件事就是它可以异步吗?如果您的答案是肯定的,那么您的实现可能会很简单,否则,您可能需要支付巨大的服务器成本或呈现随机缓存结果。
注意删除gc_collect_cycles
。它的作用与您想要的相反,您几乎不需要手动调用它。
话虽如此,我在您的情况下推荐的方法如下:
-
使用仅在客户端浏览器上打开一次的 websocket,然后将结果从服务器实时转发到浏览器。当然,这段代码本身可以通过javascript完全在客户端上运行,所以如果它不仅仅是一个PoC,你可以将php代码转换为javascript。
-
更改代码以生成项目或在生成的代码被确认为唯一代码后通过 websocket 转发结果。
但是,如果你真的只是按照PHP代码所说的去做,你可以完全在javascript中做到这一点,并节省你的服务器资源。有关替换generateRandomString
函数的示例代码,请参阅此答案。
假设您能够编辑 php.ini:
增加内存限制,如下所述: PHP 内存限制增加
有关"内存限制",请参见此处
对于"执行时间超时",添加:
set_time_limit(0);
在 PHP 文件的顶部。
你试过使用集合吗? https://www.php.net/manual/en/class.ds-set.php
每当你想要确保一个值不出现两次时,集合都非常有效。
检查集合中是否存在值,可以更快地循环数组上的所有条目。
我不是PHP专家,但它看起来像Ruby中的类似内容
require 'set'
CHARS = '0123456789abcdefghijklmnopqrstuvwxyz-_.'.split('');
unique = Set.new()
def generateRandomString(l = 10)
Array.new(l) { CHARS.sample }.join
end
while unique.length < 1_000_000
random_string = generateRandomString
if !unique.include?(random_string)
unique.add(random_string)
end
end
希望对您有所帮助