mt_srand

Seeds the Mersenne Twister generator so mt_rand() produces a repeatable sequence.

Signature
mt_srand(?int $seed = null, int $mode = MT_RAND_MT19937): void
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$seedoptional?int= nullFills 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.
$modeoptionalint= MT_RAND_MT19937Which 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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().

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.