Take the State of PHP 2026 Survey →

Random Extension Improvement View as Markdown

Implemented (PHP 8.2)
Authors
Go Kudo g-kudo@colopl.co.jp zeriyoshi@gmail.com
Date
2022-06-16
Version
1.5.4
Source
wiki.php.net/rfc/random_extension_improvement

Votes

Make all implemented engines final? closed
Yes
18
No
1
19 voters
asgrim Yes 2022-07-05 07:26
bwoebi No 2022-07-07 23:30
colinodell Yes 2022-07-05 15:22
crell Yes 2022-07-03 16:45
galvao Yes 2022-07-05 14:02
ilutov Yes 2022-07-10 15:43
kalle Yes 2022-07-03 07:40
kguest Yes 2022-07-11 16:09
levim Yes 2022-07-06 15:17
nicolasgrekas Yes 2022-07-03 06:42
nikic Yes 2022-07-04 19:01
ocramius Yes 2022-07-03 05:49
pierrick Yes 2022-07-05 07:41
santiagolizardo Yes 2022-07-04 21:51
sergey Yes 2022-07-04 07:23
svpernova09 Yes 2022-07-12 16:10
theodorejb Yes 2022-07-03 13:07
timwolla Yes 2022-07-03 08:50
weierophinney Yes 2022-07-11 20:52
Remove the SerializableEngine interface? closed
Yes
18
No
0
18 voters
asgrim Yes 2022-07-05 07:26
bwoebi Yes 2022-07-07 23:31
crell Yes 2022-07-03 16:45
galvao Yes 2022-07-05 14:02
ilutov Yes 2022-07-10 15:44
kalle Yes 2022-07-03 07:40
kguest Yes 2022-07-11 16:10
levim Yes 2022-07-06 15:17
nicolasgrekas Yes 2022-07-03 06:42
nikic Yes 2022-07-04 19:01
ocramius Yes 2022-07-03 05:49
pierrick Yes 2022-07-05 07:41
santiagolizardo Yes 2022-07-04 21:51
sergey Yes 2022-07-04 07:23
svpernova09 Yes 2022-07-12 16:10
theodorejb Yes 2022-07-03 13:07
twosee Yes 2022-07-09 12:33
weierophinney Yes 2022-07-11 20:52
Remove the CombinedLCG class? closed
Yes
18
No
0
18 voters
asgrim Yes 2022-07-05 07:26
bwoebi Yes 2022-07-07 23:31
crell Yes 2022-07-03 16:46
galvao Yes 2022-07-05 14:03
ilutov Yes 2022-07-10 15:44
kalle Yes 2022-07-03 07:40
kguest Yes 2022-07-11 16:10
levim Yes 2022-07-06 15:18
nicolasgrekas Yes 2022-07-03 06:42
nikic Yes 2022-07-04 19:03
ocramius Yes 2022-07-03 05:49
pierrick Yes 2022-07-05 07:42
sergey Yes 2022-07-04 07:23
svpernova09 Yes 2022-07-12 16:10
theodorejb Yes 2022-07-03 13:07
timwolla Yes 2022-07-03 08:50
twosee Yes 2022-07-09 12:34
weierophinney Yes 2022-07-11 20:53
Add the pickArrayKeys() method to the Randomizer? closed
Yes
12
No
2
14 voters
bwoebi Yes 2022-07-07 23:31
crell Yes 2022-07-03 16:46
galvao No 2022-07-05 14:07
ilutov Yes 2022-07-10 15:44
kalle Yes 2022-07-03 07:40
kguest Yes 2022-07-11 16:11
nicolasgrekas Yes 2022-07-03 06:42
nikic Yes 2022-07-04 19:03
ocramius No 2022-07-03 05:49
sergey Yes 2022-07-04 07:23
svpernova09 Yes 2022-07-12 16:10
theodorejb Yes 2022-07-03 13:07
twosee Yes 2022-07-09 12:34
weierophinney Yes 2022-07-11 20:53
Rename Randomizer::shuffleString() to Randomizer::shuffleBytes()? closed
Yes
16
No
1
17 voters
asgrim Yes 2022-07-05 07:27
bwoebi No 2022-07-07 23:31
crell Yes 2022-07-03 16:46
galvao Yes 2022-07-05 14:03
ilutov Yes 2022-07-10 15:45
kalle Yes 2022-07-03 07:41
kguest Yes 2022-07-11 16:11
levim Yes 2022-07-06 15:18
nicolasgrekas Yes 2022-07-03 06:42
nikic Yes 2022-07-04 19:04
ocramius Yes 2022-07-03 05:50
pierrick Yes 2022-07-05 07:42
sergey Yes 2022-07-04 07:23
svpernova09 Yes 2022-07-12 16:10
theodorejb Yes 2022-07-03 13:07
twosee Yes 2022-07-09 12:35
weierophinney Yes 2022-07-11 20:53
Rename PCG64 and MersenneTwister? closed
Yes
14
No
1
15 voters
asgrim Yes 2022-07-05 07:27
bwoebi No 2022-07-07 23:32
crell Yes 2022-07-03 16:46
galvao Yes 2022-07-05 14:04
ilutov Yes 2022-07-10 15:45
kalle Yes 2022-07-03 07:41
kguest Yes 2022-07-11 16:10
nicolasgrekas Yes 2022-07-03 06:42
ocramius Yes 2022-07-03 05:50
pierrick Yes 2022-07-05 07:43
sergey Yes 2022-07-04 07:23
svpernova09 Yes 2022-07-12 16:10
theodorejb Yes 2022-07-03 13:08
timwolla Yes 2022-07-03 08:50
weierophinney Yes 2022-07-11 20:53
Add the Xoshiro256StarStar engine and class? closed
Yes
13
No
1
14 voters
bwoebi Yes 2022-07-07 23:32
crell Yes 2022-07-03 16:46
galvao Yes 2022-07-05 14:07
ilutov Yes 2022-07-10 15:46
kalle Yes 2022-07-03 07:42
kguest Yes 2022-07-11 16:10
nicolasgrekas Yes 2022-07-03 06:43
nikic Yes 2022-07-04 19:07
ocramius No 2022-07-03 05:51
sergey Yes 2022-07-04 07:23
svpernova09 Yes 2022-07-12 16:10
timwolla Yes 2022-07-03 08:51
twosee Yes 2022-07-09 12:36
weierophinney Yes 2022-07-11 20:54

Discussions on the mailing list

[RFC] [VOTE] Random Extension 5.x
by Go Kudo · 19 messages
[RFC] [Under Discussion] Random Extension Improvement
by Go Kudo · 28 messages
[VOTE] Random Extension Improvement
by Go Kudo · 16 messages
Pre RFC - Additions to the randomizer
by Joshua Rüsweg via internals · 3 messages
[RFC] [Discussion] Persistent curl share handle improvement
by Eric Norris · 2 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:50 UTC

Introduction

Several issues with the "Random Extension 5.x" RFC were only raised after voting started (due to lack of proper discussion):

Engine implementations are not final

The Random Extension has classes that are natively implemented as RNG engines, but they are not marked as final. This allows classes to be created that inherit from native classes, but as stated in the previous RFC, user-implemented engines are inferior to native classes in terms of execution efficiency. This is true even for inheritance without method overrides, which often leads to confusion.

The extension already provides a Random\Engine interface with a single generate(): string method. Even if the native classes are made final, it is easy for the user to create an alternative class using delegates.

This is clearly an API design error, and the native implementations of the interface should be marked as final.

Random\SerializableEngine is not useful

This interface is a remnant from when the Serializable interface was still useful. This interface is no longer needed in PHP, as serializability is now determined by the existence of a magic method.

For this reason, remove Random\SerializableEngine.

This means that an Engine that implements SerializableEngine will no longer implement it. However, serializability is determined by the implementation of the magic method in current PHP, so it has no effect.

Random\Engine\CombinedLCG is low quality

The newly added Random\Engine\CombinedLCG is only for use with PHP's lcg_value() function. However, this algorithm is very classical and the quality of the output random numbers is at the lowest level.

In order to preserve the implementation of the lcg_value() function, the internal implementation is retained, but the implementation as a class is being dropped to prevent users from unintentionally using it.

There is no equivalent of array_rand()

array_rand() uses RNG internally, but there is no alternative method in Randomizer. As per the previous RFC, this was the intent, but upon further investigation, array_rand() is used by many packages and should probably be drop-in replaceable.

So add a method Randomizer::pickArrayKeys(array $array, int $num): array.

It may look incompatible with array_rand(array $array, int $num = 1): int|string|array, but you can get completely consistent results by doing the following:

$array = ['foo', 'bar', 'baz'];
 
// Before:
mt_srand(1234, MT_RAND_PHP);
$single = array_rand($array); // (int) 0
$multiple = array_rand($array, 2); // (array) [1, 2]
 
// After:
$engine = new Random\Engine\Mt19937(1234, MT_RAND_PHP);
$randomizer = new Random\Randomizer($engine);
$single = $randomizer->pickArrayKeys($array, 1)[0]; // (int) 0
 // or: [$single] = $randomizer->pickArrayKeys($array, 1);
$multiple = $randomizer->pickArrayKeys($array, 2); // (array) [1, 2]

"string" means a binary

In PHP, “string” means a binary. This is often a problem when using multibyte characters. For example, str_shuffle() on a Japanese (UTF-8) string will give messed up results.

Therefore, it may be better to change the alternative method of str_shuffle(), Randomizer::shuffleString(), to Randomizer::shuffleBytes(). This is a more appropriate name.

Engine classnames are not precise

To clearly identify the implemented algorithm, the PCG64 and MersenneTwister engines should be renamed to their canonical upstream name:

  • Random\Engine\PCG64 → Random\Engine\PcgOneseq128XslRr64
  • Random\Engine\MersenneTwister → Random\Engine\Mt19937

PCG is not so famous

PCG is a very good algorithm, boasting great randomness and performance. However, I think its name recognition is in some ways inferior to Vigna's RNG, which started with Xorshift.

Therefore, I reimplement Xoshiro256**, which was previously mentioned as a candidate, and create the class Random\Engine\Xoshiro256StarStar. This will avoid the problem of using the old MT19937 since it is not familiar with PCG.

Proposal

For each of these issues, we will create a ballot option and make a decision.

Engine implementations are not final

Vote: Make all implemented engines final? — Yes: 18 · No: 1 (closed)

Random\SerializableEngine is not useful

Vote: Remove the SerializableEngine interface? — Yes: 18 · No: 0 (closed)

Random\Engine\CombinedLCG is low quality

Vote: Remove the CombinedLCG class? — Yes: 18 · No: 0 (closed)

There is no equivalent of array_rand()

Vote: Add the pickArrayKeys() method to the Randomizer? — Yes: 12 · No: 2 (closed)

"string" means a binary

Vote: Rename Randomizer::shuffleString() to Randomizer::shuffleBytes()? — Yes: 16 · No: 1 (closed)

Engine classnames are not precise

Vote: Rename PCG64 and MersenneTwister? — Yes: 14 · No: 1 (closed)

PCG is not so famous

Vote: Add the Xoshiro256StarStar engine and class? — Yes: 13 · No: 1 (closed)

Backward Incompatible Changes

The following names have been reserved and will no longer be available:

  • Random\Engine\Mt19937
  • Random\Engine\PcgOneseq128XslRr64
  • Random\Engine\Xoshiro256StarStar

The following class names will be made available again:

  • Random\Engine\CombinedLCG
  • Random\Engine\MersenneTwister
  • Random\Engine\PCG64
  • Random\SerializableEngine

Proposed PHP Version(s)

8.2

RFC Impact

To SAPIs

none

To Existing Extensions

none

To Opcache

none

New Constants

none

php.ini Defaults

none

Patches and Tests

References