我在foo.php和bar.php中包含相同的“random.inc”。对于每一个,我想要可重现的“随机”结果。
所以在foo.php中,我总是想要一组数字和/或关键字。在bar.php另一个。哪个不应该在重新加载时改变。这就是我所说的内容伪随机。这就是我在网址上播种的原因。但是,对于单个数字以及每次重新加载的数组pickson,我仍会得到不同的结果。这是完整的php文件:
<?
header('Content-Type: text/plain');
$seed = crc32( $_SERVER['REQUEST_URI'] );
echo "phpversion: ".phpversion()."\nseed: $seed\n";
srand( $seed ); // (seed verified to be contant as expected)
// neither single values nor array pics turn out deterministic
echo ''.rand(0,100).' '.rand(0,100).' '.rand(0,100)."\n";
$values = array( '0'=>21,'1'=>89,'2'=>96,'3'=>47,'4'=>88 );
print_r( array_rand( $values, 3 ) );
?>
在PHP4.1的时代,已经(验证)可以像这样实现恒定的伪随机。 array_rand API documentation描述了自从4.2初始化自动发生的功能。也许这超越了任何明确的种子? (如果是这样,也许显式播种应该引发内部PHP标志,阻止自动播种?)。顺便说一句:mt_srand()和srand()同样不起作用。
我真的想让我的确定性 / 常量伪随机回来......
更新:以下解决方案(Windows和/或5.2版本的错误)
答案 0 :(得分:3)
适合我(PHP / 5.3.6):
<?php
$data = range(1, 100);
srand(1);
print_r(array_rand($data, 3));
...总是打印:
Array
(
[0] => 21
[1] => 89
[2] => 95
)
...在我的机器上。显然,exact numbers differ取决于确切的环境,但它们是reproducible。
答案 1 :(得分:2)
播种功能仍然可用,并且仍然可以使用;从PHP 4.2开始,它们会自动加载页面加载的时间;但你仍然可以调用它们将随机序列重置为一个已知的起点。
[编辑]我刚做了一个快速测试程序,以确保我没想到它!
mt_srand(50000);
print "rand="+mt_rand(0,10000);
使用PHP 5.2,这总是会导致打印相同的值(1749)。
[编辑] 正如@cwd所指出的那样,在这个问题的接受答案中,PHP 5.2的行为与Linux和Windows版本之间的随机数种子似乎存在差异。在Linux上的PHP 5.2中,上述技术似乎不起作用。
幸运的是,这个bug似乎已在PHP 5.3中得到修复,因此解决此问题的方法就是升级。 (不再支持PHP 5.2,因此无论如何都要升级)
答案 2 :(得分:2)
伙计们,你们都是对的! (对不起,我现在自己回答)
所有人都猜测,如果这是与操作系统相关的错误和/或PHP错误,修复于5.3.0。
鉴于随机恒定播种工作之前,我猜他们在5.3中修复了4.2中自动特征增强附带的错误。无论如何,Thanx再次,至少现在已经清晰了。
答案 3 :(得分:1)
$r = abs(crc32($URL))%20; // a number between 0 and 19, based on URL
答案 4 :(得分:1)
在PHP 5.2.17中,可能在所有版本的PHP 5.2上,(不确定Windows),我们失去了基于种子生成随机数的能力,因为PHP改变了用于随机数的算法。
rand和mt_rand被“破坏”不仅因为它们不会给出一个随机数,而且它们也不会给出相同的随机数序列 - 即使使用种子也是如此!
起初,PHP开发人员试图争辩说这是“应该”工作的方式,但是我们可以猜测他们对这个问题感到非常悲痛,他们已经恢复了与PHP 5.3一起工作的方式。
请参阅php mt_rand page和bug tracker以了解此问题。