Wrote function, takes 2 parameters: $phone - can be either a string or an array of strings $patter - a template under which strings will be changed

The essence of the function, to bring the format of the lines (phone numbers) in the format specified in the pattern ( $pattern )

 # Pattern format "# (###) ###-##-##" function PhoneFormat($phone, $pattern = "# (###) ###-##-##") { if(is_array($phone)) { foreach ($phone as &$item) { $item = PhoneFormat($item, $pattern); } return $phone; } else { $phone = preg_replace("/[^0-9]/", "", $phone); if(substr_count($pattern, "#") != strlen($phone)) return false; for($i = 0, $k = 0; $i < strlen($pattern); $i++) { if($pattern[$i] == "#") $pattern[$i] = $phone[$k++]; } } return $pattern; } 

How do you like the algorithm in terms of efficiency and implementation? Was it right to use recursion?

  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky

3 answers 3

To replace format characters with numbers, you can use the built-in vsprintf() function - which “imprints” the transferred values ​​into the format. For example:

 vsprintf('%d-%d(%d)', array(1,2,3)); // "1-2(3)" 

The plan is to split the phone-only digits into an array, one by one, and “type” them into a format in which instead of # there is a place-under-number %d :

  $phone = str_split( preg_replace("/[^0-9]/", "", $phone)); // массив цифр if(substr_count($pattern, "#") != count($phone)) return false; // знак процента – специальный, его, если есть // в исходном паттерне, надо заменить на %% // и # меняем на %d $format = str_replace( array('%','#'), array('%%','%d'), $pattern); return vsprintf( $format, $phone); 

You can optimize the processing time of the format itself. It is set only once when an external call is called for PhoneFormat() , so in the case of an array of phones, you do not need to count the number of characters in it again, its length ( strlen($pattern) ) in your version, and its translation into the format for vsptinf() in the proposed my version - all this is enough to do only once and remember - in global variables, either wrap everything in a class, or transfer it to the 3rd and 4th parameters when calling a function.

    The code is not bad. You can complete the job started (processing $ phone in place), which simplifies the program.

    Somewhere like this:

     # Pattern format "# (###) ###-##-##" function PhoneReformat(&$phone, $pattern = "# (###) ###-##-##") { if(is_array($phone)) { foreach ($phone as &$item) { PhoneReformat($item, $pattern); } } else { $phone = preg_replace("/[^0-9]/", "", $phone); if(substr_count($pattern, "#") != strlen($phone)){ $phone = false; }else{ for($i = 0, $k = 0; $i < strlen($pattern); $i++) { if($pattern[$i] == "#") $pattern[$i] = $phone[$k++]; } $phone = $pattern; } } } 

      So far I can not leave comments, so the answer. I liked the piece substr_count ($ pattern, "#"), as an amusing charge I made an option without $ k. Obviously, both the readability of the code and, probably, the speed of execution suffer, but that was not the goal.

       function PhoneReformat(&$phone, $pattern = "# (###) ###-##-##") { if(is_array($phone)) { foreach ($phone as &$item) { PhoneReformat($item, $pattern); } } else { $phone = preg_replace("/[^0-9]/", "", $phone); if(substr_count($pattern, "#") != strlen($phone)){ $phone = false; }else{ foreach(str_split($pattern) as $key => $char){ if ($char == "#") { $pattern[$key] = substr($phone, -substr_count($pattern, "#"), 1); } } $phone = $pattern; } } }