88

What would be the most elegant way to get a random boolean true/false in PHP?

I can think of:

$value = (bool)rand(0,1);

But does casting an integer to boolean bring any disadvantages?

Or is this an "official" way to do this?

gherkins
  • 14,603
  • 6
  • 44
  • 70

4 Answers4

162

If you don't wish to have a boolean cast (not that there's anything wrong with that) you can easily make it a boolean like this:

$value = rand(0,1) == 1;

Basically, if the random value is 1, yield true, otherwise false. Of course, a value of 0 or 1 already acts as a boolean value; so this:

if (rand(0, 1)) { ... }

Is a perfectly valid condition and will work as expected.

Alternatively, you can use mt_rand() for the random number generation (it's an improvement over rand()). You could even go as far as openssl_random_pseudo_bytes() with this code:

$value = ord(openssl_random_pseudo_bytes(1)) >= 0x80;

Update

In PHP 7.0 you will be able to use random_int(), which generates cryptographically secure pseudo-random integers:

$value = (bool)random_int(0, 1);
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • I know this is a bit old, but why not use a type-safe comparison (`===`) vs the casting one (`==`) on your first code example? – NerdOfCode May 14 '21 at 13:57
  • 1
    @NerdOfCode `rand(0, 1)` always returns an integer value, so you don't strictly need a type-safe comparison; things would be different if there's a chance that the function returns values of other types, e.g. `false` or `null` which would get typecast to `0`. – Ja͢ck May 17 '21 at 11:51
8

I use a simply

rand(0,1) < 0.5
gherkins
  • 14,603
  • 6
  • 44
  • 70
  • 3
    This is also useful to fine tune the randomness and make random bools that aren't just evenly random 50% of the time, such as `rand(0, 1) < 0.25`. – neave Mar 18 '18 at 20:08
  • 5
    I think that would need to be `rand(0, 100) < 25` to be effective @neave – aland Jun 13 '18 at 12:45
  • 3
    It's worth noting that strictly speaking this method is slightly biased towards `false` as `true` = 0 - 0.499999 and `false` = 0.5 - 1.0 (0.000001 more). – Andrew Oct 16 '18 at 14:39
8

Just for completeness, if you want to use it in an if condition, there is no need to cast, since 0 is considered false and mt_rand produces random integers in the range:

if (mt_rand(0,1)) { // 0 = false, 1 = true
  // whatever
}

Note: mt_rand is 4x faster than rand

The mt_rand() function is a drop-in replacement for the older rand(). It uses a random number generator with known characteristics using the "Mersenne Twister", which will produce random numbers four times faster than what the average libc rand() provides. (Source: https://www.php.net/manual/en/function.mt-rand.php)

jpenna
  • 8,426
  • 5
  • 28
  • 36
0

php stan recomended

1 === random_int(0, 1)
des1roer
  • 220
  • 1
  • 14
  • It depends on what you need, performance wise I think it takes more to use `random_int()` over `rand()`, more on this in https://stackoverflow.com/questions/44228718/php-rand-vs-random-int – phaberest May 13 '20 at 12:32
  • How is PHPStan related to the given question? – Nico Haase May 13 '20 at 13:38