Backend Development

Learn About PHP 8.2 Random and Randomizer class

Learn About PHP 8.2 Random and Randomizer class

PHP 8.2 comes with a new high level extension “random” for random number generation along with Random\Randomizer class.

 

 

The new “random” extension in PHP 8.2 can be used for random number generation. The new extension is already bundled in PHP 8.2 and there is no compile-time or runtime configuration to disable it.

This new extension comes in the form of OOP namespaced classes based instead of the php procedural functions like rand(), mt_rand(), srand().

For the existing PHP functions that generate random numbers like rand(), mt_rand(), srand(), random_bytes(), random_int(), etc. All these functions is moved to new new Random extension in PHP 8.2 and later and it will be available under the global namespace so it will not impact old applications written in PHP < 8.2.

 

\Random namespace

The new functionality in the “random” extension added under new namespace \Random and all new classes located under this namespace. 

Some of the classes included under the \Random namespace:

 

The most important class on these classes is the Random\Randomizer class and includes many methods for random number generation.

Random\Randomizer synopsis

final class Random\Randomizer {
    /* Properties */
    public readonly Random\Engine $engine;
    
    /* Methods */
    public __construct(?Random\Engine $engine = null)
    public getBytes(int $length): string
    public getInt(int $min, int $max): int
    public nextInt(): int
    public pickArrayKeys(array $array, int $num): array
    public __serialize(): array
    public shuffleArray(array $array): array
    public shuffleBytes(string $bytes): string
    public __unserialize(array $data): void
}

The Random\Randomizer constructor accepts an instance of Random\Engine. The engine parameter used to specify the default engine for randomness generation. If this parameter is omitted it will use Random\Engine\Secure by default.

Generating uniformly random integer:

$r = new Random\Randomizer(); 

echo $r->getInt(1, 200);

Generating positive integer:

$r = new Random\Randomizer(); 

echo $r->nextInt();

Generating random bytes:

$r = new Random\Randomizer();

echo bin2hex($r->getBytes(8));  // 573edfde759116a6

Get a permutation of array:

$r = new Random\Randomizer();

$countries = ['usa' => 'united states', 'uk' => 'england', 'fr' => 'france'];

var_dump($r->shuffleArray($countries));

// output
array(3) {
  [0]=>
  string(6) "france"
  [1]=>
  string(13) "united states"
  [2]=>
  string(7) "england"
}

Note the shuffleArray() will not preserve the array keys. The input array will not be modified. 

Get bit-wise permutation of string:

$r = new Random\Randomizer();

echo $r->shuffleBytes("Hello World!");

Select random array keys:

$r = new Random\Randomizer();

$countries = ['usa' => 'united states', 'uk' => 'england', 'fr' => 'france'];

var_dump($r->pickArrayKeys($countries, 2));

// output
array(2) {
  [0]=>
  string(3) "usa"
  [1]=>
  string(2) "fr"
}

The pickArrayKeys($array, $num) method return random array keys of the input $array and $num where $num is the number of keys to return from the input array. The $num parameter must be between 1 and number of elements of array. 

If num is less than 1 or greater than the number of elements in array, a ValueError will be thrown.

Fatal error: Uncaught ValueError: Random\Randomizer::pickArrayKeys(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) in ....

You can use this to pick random array values while preserving keys:

$countries = ['usa' => 'united states', 'uk' => 'england', 'fr' => 'france'];

$randomKeys = $r->pickArrayKeys($countries, 2);

$randomValues = [];

foreach ($randomKeys as $value) {
    $randomValues[$value] = $countries[$value];
}


var_dump($randomKeys, $randomValues);

 

 

Random\Engine interface

The Random\Engine interface specifies the algorithm used while performing the random generation and provides low-level source of randomness by returning random bytes that are consumed by high-level Apis to perform the random generation functionality.

As you saw in the Random\Randomizer class constructor which accepts an instance of Random\Engine interface. When the engine is null it will use Random\Engine\Secure by default.

Keep in mind that each engine or algorithm return different results that suit your use case. Some algorithms fast but generate low-quality randomness while others are slow but generate better randomness. 

Random\Engine synopsis

interface Random\Engine {
    /* Methods */
    public generate(): string
}

The interface just contains one method generate() which generate allow any class implementing this interface to implement it’s own logic for randomness generation.

Available engines that extend Random\Engine:

 

Example Using Mt19937 engine:

$r = new Random\Randomizer(new Random\Engine\Mt19937());

echo $r->getInt(1, 100);

Example Using PcgOneseq128XslRr64 engine:

$r = new Random\Randomizer(new Random\Engine\PcgOneseq128XslRr64());

 

0 0 votes
Article Rating

What's your reaction?

Excited
0
Happy
0
Not Sure
0
Confused
0

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments