lcg_value
Returns a pseudo-random float between 0 and 1 from a combined linear congruential generator.
lcg_value(): float- Added in PHP 4.0
- Deprecated since PHP 8.4.0
Return value
floatA pseudo-random float in the open range (0, 1) — never exactly 0 and never exactly 1.
Changelog
- PHP 8.4.0The function is deprecated. Every call emits an E_DEPRECATED notice; use Random\Randomizer::getFloat() instead.
The direct replacement is Random\Randomizer::getFloat(), available since PHP 8.3.
Example
When to use it
- Reading legacy code that predates the Random extension and deciding what to replace it with
- Migrating an old probability check such as if (lcg_value() < 0.1) to Randomizer::getFloat()
- Adding non-critical jitter to a sampling rate in a script that still targets PHP 8.3
Frequently asked questions
Is lcg_value deprecated in PHP 8.5?
Yes — it was deprecated in PHP 8.4 and still emits an E_DEPRECATED notice on 8.5. It has not been removed yet, but you should migrate to Random\Randomizer::getFloat().
What should I use instead of lcg_value?
Use Random\Randomizer::getFloat($min, $max, Random\IntervalBoundary::ClosedOpen), available since PHP 8.3, for a correctly distributed float in an interval you control. For a simple percentage check, mt_rand(1, 100) is simpler and has no float rounding issues.
Can I use lcg_value for security tokens?
No. It is a pair of linear congruential generators whose state can be recovered from a handful of outputs, so its values are guessable. Use random_bytes() or random_int() for anything that must be unpredictable.
More examples
Migrating a probability check
This is the modern form of the classic if (lcg_value() < 0.25) log sampler. The printed rate lands close to 0.250 on every run, showing the replacement keeps the same behaviour without the deprecation notice.
<?php
$randomizer = new Random\Randomizer();
$sampleRate = 0.25;
$hits = 0;
for ($i = 0; $i < 10000; $i++) {
if ($randomizer->getFloat(0, 1, Random\IntervalBoundary::ClosedOpen) < $sampleRate) {
$hits++;
}
}
echo "sampled: $hits of 10000\n";
printf("rate: %.3f (target %.2f)\n", $hits / 10000, $sampleRate);Why the open interval matters
Across 5000 draws the values crowd towards both ends but never touch them, and the last line prints false. Code written as if (lcg_value() == 0) or a loop waiting for an exact boundary will never fire.
<?php
$sawZero = false;
$min = 1.0;
$max = 0.0;
for ($i = 0; $i < 5000; $i++) {
$v = @lcg_value();
if ($v === 0.0) { $sawZero = true; }
$min = min($min, $v);
$max = max($max, $v);
}
printf("lowest seen: %.8f\n", $min);
printf("highest seen: %.8f\n", $max);
echo 'exact 0.0 ever returned: ', var_export($sawZero, true), "\n";
Discussion