我有一个配置文件表,我想按随机顺序列出配置文件,我已完成如下:
$this->paginate = array('User' => array('conditions'=>array('User.userstanding_id'=>'1'), 'order' => 'RAND()', 'limit' => '10'));
唯一缺少的功能是,我希望这些配置文件按顺序进行,以便在下一页上没有重复项,甚至一些配置文件在完成所有操作时根本无法查看页面。
我正在寻找的是一种方法,为查询找到一个随机起点,然后从该起点开始按顺序分页。也许每个会话?
答案 0 :(得分:2)
MySQL RAND()
function可以将整数作为参数用作种子,始终产生相同的结果:
为了证明这一点,这里有一个包含3个单列字符串记录的表:
mysql> select * from chartest;
+--------+
| string |
+--------+
| AA |
| AB |
| BB |
+--------+
3 rows in set (0.00 sec)
如果我在rand()
中使用1作为ORDER BY
的种子值,它将始终产生相同的结果排序:
mysql> select * from chartest order by rand(1);
+--------+
| string |
+--------+
| BB |
| AA |
| AB |
+--------+
3 rows in set (0.00 sec)
mysql> select * from chartest order by rand(1);
+--------+
| string |
+--------+
| BB |
| AA |
| AB |
+--------+
3 rows in set (0.00 sec)
如果我将种子更改为2,则排序会更改:
mysql> select * from chartest order by rand(2);
+--------+
| string |
+--------+
| AB |
| BB |
| AA |
+--------+
3 rows in set (0.00 sec)
您可以将用户的会话ID转换为整数并将其传递给此函数,以便对于该会话,结果将始终以相同的方式排序。
例如,如果会话ID是MD5哈希,为了避免必须处理这些值所代表的大(160位)整数,只需从字符串中删除字符(例如使用preg_replace ('/[^\d\s]/', '', $sessionid);
)。然后取前5个左右的数字并将其转换为(int)
以用作种子:
$seed = substr($numeric_id, 0, 5);
要在使用CakePHP时将参数传递给RAND()
函数,要确保将其视为整数而不是字符串,请尝试在$conditions
数组的order
中使用以下语法:
'order' => 'RAND(CAST('.$seed.' AS SIGNED))'
答案 1 :(得分:1)
我不是CakePHP的专家,但我想如果你在会话基础上播种RAND函数,那么paginate函数将使用会话种子值在页面之间工作。
e.g
在创建会话时分配种子,只需使用随机数生成器即可。
$this->paginate = array('User' => array('conditions'=>array('User.userstanding_id'=>'1'), 'order' => 'RAND('.$_SESSION['rndSeed'].')', 'limit' => '10'));