Reputation: 1503
I need to generate a random string of length 4(Valid string is 1ABC, A12D...
). String must contains atleast 1 number and remaining can be [A-Z].
protected function generate(int $length = 4): array
{
$randomString = '';
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
for ($i = 0; $i < $length; $i++) {
$index = random_int(0, strlen($characters) - 1);
$randomString .= $characters[$index];
}
$uppercase = preg_match('@[A-Z]@', $randomString);
$number = preg_match('@[\d]@', $randomString);
if (!$uppercase || !$number) {
$this->generate();
}
return $randdomString;
}
echo substr(str_shuffle('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'),1, 4);
Most of the time, it is giving me correct answer but some cases, it return me only alphabet values (This is the recent result I get XFJG
)
Can anybody please help ?
Upvotes: 0
Views: 210
Reputation: 163372
The OR ||
will return true if one of both conditions is true, so if there is no number it will pass the if clause.
You could check if both conditions are true instead:
if ($number && $uppercase) {
// do something with $values
}
Running this again $func();
inside the if clause, will run the function again generating a new string and returns $randomString;
from the function.
If you want to return the tested string, you can return the already tested $values
EDIT
If you don't want to return only chars A-Z or only digits, you can update the pattern to match only digit or only chars A-Z using ^\d+$
and ^[A-Z]+$
If one if the conditions is true, then do a recursive call.
protected function generate(int $length = 4): string
{
$randomString = '';
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
for ($i = 0; $i < $length; $i++) {
$index = random_int(0, strlen($characters) - 1);
$randomString .= $characters[$index];
}
$uppercase = preg_match('@^[A-Z]+$@', $randomString);
$number = preg_match('@^\d+$@', $randomString);
if ($uppercase || $number) {
$randomString = $this->generate();
}
return $randomString;
}
See a PHP demo.
Upvotes: 2