0

I'm currently struggling with a PHP issue : I'd like to use the str_starts_with function (AFAIK available from PHP 8.0) to check if a given phone number actually starts with a phone code (all the phone codes are defined in an array).

According to documentation, it seems the str_starts_with function doesn't support arrays as parameter, that's why I'm trying to find another way to solve my problem.

I used the foreach loop to check all the codes one-by-one, and see if the given phone number actually starts with one of the codes contained in the array. But it seems that combining foreach, array and str_starts_with is not always possible.

The greatest advantage of the str_starts_with function is that it can handle codes of various lengths : for example, there are phone codes with one digit (+1 : Canada, U. S. A., and many other), two digits (+33 : France), three digits (+353 : Ireland).

Here is what I tried :

$tel = '+33601020304';

$tel = preg_replace('/[^0-9]/', '', $tel); //33601020304

$tel = ltrim($tel, '0'); //33601020304

$tel_array = array('32' => 'Belgique', '33' => 'France', '34' => 'Espagne', '41' => 'Suisse', '44' => 'Royaume-Uni', '49' => 'Allemagne');

foreach($tel_array as $pays => $code)
{
   str_starts_with($tel, $pays);
   echo $pays.'_'.$code.'<br />';
}

If the number starts with one of the codes from the array, I'd like to return the country where the number comes from (name of the country also contained in the array). Else, I would like to return an error.

Instead of that, for the moment, I get this :

32_Belgique 33_France 34_Espagne 41_Suisse 44_Royaume-Uni 49_Allemagne

How could I get and display the country to which the number is assigned, and display an error else ?

  • 1
    Related: [How to get the country code from mobile number using php](https://stackoverflow.com/q/23488156/2943403) – mickmackusa May 31 '23 at 21:36
  • More efficiently than looping over your array, you can fallback to smaller prefix checks with the null coalescing operator. This way you need to make more than 3 checks. `echo $tel_array[substr($tel, 0, 3)] ?? $tel_array[substr($tel, 0, 2)] ?? $tel_array[substr($tel, 0, 1)] ?? 'Prefix not found';` – mickmackusa Jun 02 '23 at 06:40
  • Also relevant and helpful: [What regular expression will match valid international phone numbers?](https://stackoverflow.com/q/2113908/2943403) – mickmackusa Jun 02 '23 at 06:47

2 Answers2

1

If you organise your list of codes with the longest codes first, this will ensure that you take the longest possible match first.

So using the examples from your question...

$tel_array = [
    // 3 digit
    '353' => 'Ireland',
    // 2 digit
    '32' => 'Belgique', '33' => 'France',
    '34' => 'Espagne', '41' => 'Suisse', '44' => 'Royaume-Uni',
    '49' => 'Allemagne',
    // 1 digit
    '1' => 'USA',
];

Then loop through them and once you find a match (str_starts_with returns true), the echo out the match and stop looking...

foreach ($tel_array as $pays => $code) {
    if (str_starts_with($tel, $pays)) {
        echo $pays . '_' . $code . '<br />';
        break;
    }
}
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
  • Of course, my point is that you cannot rely on this. If the number that follows the USA code (`1`) is then found in a longer code, then this approach breaks down. Does your lookup array have a `35`? what if the first number to occur after that prefix is a `3`? You'll get Ireland. This not a well-defined task or it is vulnerable to breakage. – mickmackusa Jun 01 '23 at 23:21
  • @mickmackusa you have to understand the context of the question and this was my point before. There is no country code 35 and there never will be -there cannot be another country code starting with 1. This is how the system works and why you have to think outside of what OP says. The system won't break because how do you think it works? – Nigel Ren Jun 02 '23 at 06:19
  • It's also frustrating that you close a question as a duplicate when the duplicate doesn't explain the issue, just the basic facts about what the function does. – Nigel Ren Jun 02 '23 at 06:21
  • No other phone number will start with `1` that is not a US number? It's true that I didn't bother learning all of the phone region prefixes. There is nothing wrong with the canonical that I offered. It shows the OP how the function is used in a condition. A good sanity check is: "Would the asker have even asked the question if they read the dupe target first?" The real answer to that in this case is: "No, they wouldn't have needed to ask the question." – mickmackusa Jun 02 '23 at 06:32
  • After reviewing https://countrycode.org/, I see that after the asker sanitises the non-digits, there will be conflict on phone numbers that start with `1-` and `44-`. – mickmackusa Jun 02 '23 at 06:51
0

str_starts_with returns a bool. You need to use this in an if statement. So if str_starts_with, then echo the string.

Stijn Leenknegt
  • 1,317
  • 4
  • 12
  • 22