Случайное число и строка: random_int
<?php
$dice = random_int(1, 6);
echo "Выпало: $dice\n";random_int(мин, макс) возвращает случайное целое число от мин до макс включительно. При каждом запуске результат свой. Числа получаются криптографически стойкими — их нельзя предсказать, поэтому random_int годится и для кодов подтверждения, и для игр.
В старом коде встречаются rand() и mt_rand(). Для простых задач они работают (с PHP 7.1 rand — то же самое, что mt_rand), но их результат можно предсказать. Для всего, что связано с безопасностью, — только random_int и random_bytes.
Случайный элемент и перемешивание
<?php
$cities = ['Минск', 'Брест', 'Гомель', 'Гродно', 'Витебск', 'Могилёв'];
$key = array_rand($cities);
echo $cities[$key] . "\n";
shuffle($cities);
echo implode(', ', $cities) . "\n";array_randвозвращает ключ случайного элемента, а не сам элемент.array_rand($cities, 3)вернёт массив из трёх ключей.shuffleперемешивает сам массив и нумерует элементы заново.
array_rand, shuffle и str_shuffle внутри используют предсказуемый генератор — для жеребьёвки с призами или паролей они не подходят.
Случайная строка: токен
Для ссылок подтверждения почты, сброса пароля и случайных имён файлов нужна непредсказуемая строка:
<?php
$token = bin2hex(random_bytes(16));
echo $token . "\n";random_bytes(16) даёт 16 случайных байтов, а bin2hex записывает их 32 знаками из цифр и букв a–f. Такой токен невозможно угадать перебором.
Случайный пароль
<?php
function makePassword(int $length = 12): string
{
$chars = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$max = strlen($chars) - 1;
$result = '';
for ($i = 0; $i < $length; $i++) {
$result .= $chars[random_int(0, $max)];
}
return $result;
}
echo makePassword() . "\n";Из набора убраны похожие знаки — l, o, I, O, 0, 1, — чтобы пароль было легко переписать с экрана. $chars[$n] берёт из строки знак с номером $n; так можно делать, потому что в наборе только латиница и цифры — по одному байту на знак.
Подводные камни
random_int(1, 10)включает и 1, и 10. Частая ошибка — ждать, что верхняя граница не входит, как в некоторых других языках.- Случайное число при каждом обновлении страницы новое. Если значение нужно сохранить (код подтверждения), положите его в сессию или базу.
- Генерировать уникальные номера заказов случайными числами не нужно: номера выдаёт сама база данных (
AUTO_INCREMENTв MySQL,INTEGER PRIMARY KEYв SQLite).