mt_srand
Seeds the Mersenne Twister generator so mt_rand() produces a repeatable sequence.
mt_srand(?int $seed = null, int $mode = MT_RAND_MT19937): void- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$seedoptional | ?int= null | Fills the generator state from a linear congruential generator seeded with this value, interpreted as an unsigned 32-bit integer. If omitted or null, a random 32-bit seed is used. |
$modeoptional | int= MT_RAND_MT19937 | Which algorithm implementation to use. MT_RAND_MT19937 is the correct Mt19937 implementation; MT_RAND_PHP selects the broken pre-7.1 variant and is deprecated as of PHP 8.3.0. |
Return value
voidNo value is returned.
Errors
Nothing. Passing MT_RAND_PHP emits a deprecation notice as of PHP 8.3.0.
Changelog
- PHP 8.3.0$seed is now nullable, and passing MT_RAND_PHP as $mode is deprecated.
- PHP 7.1.0srand() became an alias of mt_srand(), and mt_rand() switched to the fixed, correct Mersenne Twister algorithm.
Since PHP 4.2.0 the generator seeds itself automatically on first use, so you almost never need to call mt_srand() for normal randomness.
Example
When to use it
- Seed with a fixed value so a test suite generates the same random fixtures every run
- Reproduce a reported bug that depends on a specific random sequence
- Generate deterministic demo or benchmark data from a recorded seed
Frequently asked questions
Do I still need to call mt_srand()?
No. PHP has seeded the random number generator automatically since 4.2.0, so calling mt_srand() for ordinary randomness adds nothing and seeding it with time() makes the output easier to predict. Call it only when you deliberately want a repeatable sequence.
How do I get the same random numbers every time?
Call mt_srand() with a fixed integer before your first mt_rand() call. Every subsequent mt_rand(), shuffle() and array_rand() call in that process replays the same sequence.
What is the difference between mt_srand() and srand()?
None since PHP 7.1 - srand() is an alias of mt_srand() and both seed the same global Mersenne Twister state.
More examples
Seeding affects shuffle() and array_rand() too
shuffle() draws from the same global Mersenne Twister state, so re-seeding replays its result exactly. This is why calling mt_srand() from library code can surprise unrelated parts of an application.
<?php
$deck = range(1, 8);
mt_srand(7);
$a = $deck; shuffle($a);
mt_srand(7);
$b = $deck; shuffle($b);
print_r($a);
var_dump($a === $b); // bool(true)Isolated seeded randomness with Random\Randomizer
Two Randomizer objects seeded identically produce identical sequences, but each carries its own state. Nothing here disturbs the global generator that mt_rand() uses, which is the key advantage over mt_srand().
<?php
$r1 = new Random\Randomizer(new Random\Engine\Mt19937(2024));
$r2 = new Random\Randomizer(new Random\Engine\Mt19937(2024));
$a = [$r1->getInt(1, 50), $r1->getInt(1, 50)];
$b = [$r2->getInt(1, 50), $r2->getInt(1, 50)];
print_r($a);
var_dump($a === $b); // bool(true)
mt_srand(99); // global state untouched by the objects above
echo mt_rand(1, 50), "\n";Re-seeding is not needed for ordinary randomness
The first call works without any seeding because PHP 4.2.0 and later seed automatically. The final line makes the security limit concrete: fewer than 4.3 billion sequences exist, which is why seeded mt_rand() output must never be used as a token.
<?php
// PHP seeds itself on first use - this is already random
echo mt_rand(1, 1000), "\n";
// Passing null re-seeds from a random 32-bit value (PHP 8.3+)
mt_srand(null);
echo mt_rand(1, 1000), "\n";
// Only 2^32 distinct sequences exist, whatever seed you pass
echo number_format(2 ** 32), " possible sequences\n";
Discussion