Function to add dashes to US phone number in PHP - php

What is the best way to add dashes to a phone number in PHP? I have a number in the format xxxxxxxxxx and I want it to be in the format xxx-xxx-xxxx. This only applies to 10 digit US phone numbers.

$number = "1234567890";
$formatted_number = preg_replace("/^(\d{3})(\d{3})(\d{4})$/", "$1-$2-$3", $number);
EDIT: To be a bit more generic and normalize a US phone number given in any of a variety of formats (which should be common practice - there's no reason to force people to type in a phone number in a specific format, since all you're interested in are the digits and you can simply discard the rest):
function localize_us_number($phone) {
$numbers_only = preg_replace("/[^\d]/", "", $phone);
return preg_replace("/^1?(\d{3})(\d{3})(\d{4})$/", "$1-$2-$3", $numbers_only);
}
echo localize_us_number("5551234567"), "\n";
echo localize_us_number("15551234567"), "\n";
echo localize_us_number("+15551234567"), "\n";
echo localize_us_number("(555) 123-4567"), "\n";
echo localize_us_number("+1 (555) 123-4567"), "\n";
echo localize_us_number("Phone: 555 1234567 or something"), "\n";

$number = '1234567890';
if(ctype_digit($number) && strlen($number) == 10) {
$number = substr($number, 0, 3) .'-'.
substr($number, 3, 3) .'-'.
substr($number, 6);
}
Or if you for some reason want to avoid substr:
$number = '1234567890';
if(ctype_digit($number) && strlen($number) == 10) {
$parts = str_split($number, 3);
$number = $parts[0] .'-'. $parts[1] .'-'. $parts[3].$parts[4];
}

iterate through the string and make counter. When counter is 3 or 7 insert dash.

I feel obliged to post. Cheesiest solution:
$number = "1234567890";
$formatted_number = "$number[0]$number[1]$number[2]-$number[3]$number[4]$number[5]-$number[6]$number[7]$number[8]$number[9]";
But it works and its fast. vs. the preg_replace solution:
250,000 iterations:
preg_replace: 1.23 seconds
ugly solution: 0.866 seconds
Pretty meaningless but fun :P

Here's what I used. It's not perfect, but it's an improvement over #Thilo's answer. It checks for a leading 1. If it's there, it ignores it. The code also ignores separating dashes, commas, and spaces, so it will work with 1231231234, 123 123 1234, and 123.123.1234. It doesn't handle numbers with parenthesis, but I'm sure there's another thread out there with that solution!
$formatted_number = preg_replace("/^1?(?:[- .])?(\d{3})(?:[- .])?(\d{3})(?:[- .])?(\d{4})$/", "($1) $2-$3", $not_formatted_phone_number);

A modification of Thilo's answer providing complete conditional formatting control over the leading "1".
public function phoneFormat($number) {
$numbersOnly = preg_replace("/[^\d]/", "", $number);
$nums = array_filter(explode("-", preg_replace("/^(1|)(\d{3})(\d{3})(\d{4})$/",
"$1-$2-$3-$4", $numbersOnly)));
$output = $numbersOnly;
if(count($nums) == 3){
$output = "($nums[1])-$nums[2]-$nums[3]";
}elseif(count($nums) == 4){
$output = "$nums[0]-($nums[1])-$nums[2]-$nums[3]";
}
return $output;
}

Here's what I came up with:
function format_phone($var_num) {
$var_num = trim($var_num);
$var_num = str_replace("(","",$var_num);
$var_num = str_replace(")","",$var_num);
$var_num = str_replace("-","",$var_num);
$var_num = str_replace(" ","",$var_num);
$var_num = str_replace(".","",$var_num);
$var_num = substr($var_num, -10);
$var_area_code = substr($var_num, 0, -7);
$var_exchange = substr($var_num, 3, -4);
$var_extention = substr($var_num, -4);
$var_return = "{$var_area_code}-{$var_exchange}-{$var_extention}";
return $var_return;
}
// Examples:
$phone_number = "1 (757) 555-1212";
// $phone_number = "17575551212";
// $phone_number = "(757) 555-1212";
// $phone_number = "757.555.1212";
echo "{$phone_number} = " . format_phone($phone_number);

Related

PHP Allow only numbers with 2 decimals

I need a function to check if number have 2 decimals or not.
For example:
$number = '1.00'; // Valid
$number2 = '1'; // Not valid
$number3 = '1.000' //Not valid
You can check it like that:
$str = "1.23444";
print strlen(substr(strrchr($str, "."), 1));
You would have to convert your variable to a String, but this is not a big problem. Do it like that:
$d = 100.0/81.0;
$s = strval($d);
You can do something like this:
if(strlen(substr(strrchr($number, "."), 1)) == 2){
echo "valid";
}else{
echo "not valid";
}
Regex could be a solution since your numbers seem to be declared as strings.
Code :
<?php
$re = "/(\d\.\d{2})(?!\d)/";
$array_input = array('1.00', '1', '1.000');
foreach($array_input as $row)
{
if(preg_match($re, $row, $matches) == 0)
echo $row . " isn't a valid value with 2 decimals only. <br>";
else
echo $row . " is valid. <br>";
}
?>
Output :
1.00 is valid.
1 isn't a valid value with 2 decimals only.
1.000 isn't a valid value with 2 decimals only.
Why would you not just force them to have 2 decimals using something like this
$original = 2;
$float = number_format($number, 2);
// echo $float = 2.00
I guess if you need to enforce that a float only has 2 decimals you could do something like the following.
$numbers = array(2.453, 3.35, 2.53, 1.636);
foreach($numbers as $number) {
if(strpos($number, '.') !== false) {
if(strlen($parts[1]) == 2) {
echo $number .' is valid!';
} else {
echo $number .' is NOT valid!';
}
}
}
The above is one way to accomplish this but there are many others. You could use array_map or array_filter and you could also use math such as the following
$numbers = array(2.453, 3.35, 2.53, 1.636);
$valid_numbers = array_filter($numbers, function($number) { return strlen($number) - strpos($number, '.');
function check_decimals($input, $number_of_decimals)
{
if(strlen(substr(strrchr((string)$input, "."), 1)) == $number_of_decimals)
{
return TRUE;
}
else {
return FALSE;
}
}
check_decimals("1.000", 2);
This may be a solution using preg_match_all
$re = "/^\\d+(?:\\.\\d{2})?$/m";
$str = "1.00\n13333.55\n1.000";
preg_match_all($re, $str, $matches);
echo '<pre>';
print_r($matches);
echo '</pre>';
REGEX: https://regex101.com/r/nB7eC4/1
CODE: http://codepad.viper-7.com/49ZuEa

Validate IBAN PHP

As designing a new platform we tried to integrate the IBAN numbers. We have to make sure that the IBAN is validated and the IBAN stored to the database is always correct. So what would be a proper way to validate the number?
As the logic was explained in my other question, I've created a function myself. Based on the logic explained in the Wikipedia article find a proper function below. Country specific validation.
Algorithm and character lengths per country at https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN.
function checkIBAN($iban)
{
if(strlen($iban) < 5) return false;
$iban = strtolower(str_replace(' ','',$iban));
$Countries = array('al'=>28,'ad'=>24,'at'=>20,'az'=>28,'bh'=>22,'be'=>16,'ba'=>20,'br'=>29,'bg'=>22,'cr'=>21,'hr'=>21,'cy'=>28,'cz'=>24,'dk'=>18,'do'=>28,'ee'=>20,'fo'=>18,'fi'=>18,'fr'=>27,'ge'=>22,'de'=>22,'gi'=>23,'gr'=>27,'gl'=>18,'gt'=>28,'hu'=>28,'is'=>26,'ie'=>22,'il'=>23,'it'=>27,'jo'=>30,'kz'=>20,'kw'=>30,'lv'=>21,'lb'=>28,'li'=>21,'lt'=>20,'lu'=>20,'mk'=>19,'mt'=>31,'mr'=>27,'mu'=>30,'mc'=>27,'md'=>24,'me'=>22,'nl'=>18,'no'=>15,'pk'=>24,'ps'=>29,'pl'=>28,'pt'=>25,'qa'=>29,'ro'=>24,'sm'=>27,'sa'=>24,'rs'=>22,'sk'=>24,'si'=>19,'es'=>24,'se'=>24,'ch'=>21,'tn'=>24,'tr'=>26,'ae'=>23,'gb'=>22,'vg'=>24);
$Chars = array('a'=>10,'b'=>11,'c'=>12,'d'=>13,'e'=>14,'f'=>15,'g'=>16,'h'=>17,'i'=>18,'j'=>19,'k'=>20,'l'=>21,'m'=>22,'n'=>23,'o'=>24,'p'=>25,'q'=>26,'r'=>27,'s'=>28,'t'=>29,'u'=>30,'v'=>31,'w'=>32,'x'=>33,'y'=>34,'z'=>35);
if(array_key_exists(substr($iban,0,2), $Countries) && strlen($iban) == $Countries[substr($iban,0,2)]){
$MovedChar = substr($iban, 4).substr($iban,0,4);
$MovedCharArray = str_split($MovedChar);
$NewString = "";
foreach($MovedCharArray AS $key => $value){
if(!is_numeric($MovedCharArray[$key])){
if(!isset($Chars[$MovedCharArray[$key]])) return false;
$MovedCharArray[$key] = $Chars[$MovedCharArray[$key]];
}
$NewString .= $MovedCharArray[$key];
}
if(bcmod($NewString, '97') == 1)
{
return true;
}
}
return false;
}
Slight modification of #PeterFox answer including support for bcmod() when bcmath is not available,
<?php
function isValidIBAN ($iban) {
$iban = strtolower($iban);
$Countries = array(
'al'=>28,'ad'=>24,'at'=>20,'az'=>28,'bh'=>22,'be'=>16,'ba'=>20,'br'=>29,'bg'=>22,'cr'=>21,'hr'=>21,'cy'=>28,'cz'=>24,
'dk'=>18,'do'=>28,'ee'=>20,'fo'=>18,'fi'=>18,'fr'=>27,'ge'=>22,'de'=>22,'gi'=>23,'gr'=>27,'gl'=>18,'gt'=>28,'hu'=>28,
'is'=>26,'ie'=>22,'il'=>23,'it'=>27,'jo'=>30,'kz'=>20,'kw'=>30,'lv'=>21,'lb'=>28,'li'=>21,'lt'=>20,'lu'=>20,'mk'=>19,
'mt'=>31,'mr'=>27,'mu'=>30,'mc'=>27,'md'=>24,'me'=>22,'nl'=>18,'no'=>15,'pk'=>24,'ps'=>29,'pl'=>28,'pt'=>25,'qa'=>29,
'ro'=>24,'sm'=>27,'sa'=>24,'rs'=>22,'sk'=>24,'si'=>19,'es'=>24,'se'=>24,'ch'=>21,'tn'=>24,'tr'=>26,'ae'=>23,'gb'=>22,'vg'=>24
);
$Chars = array(
'a'=>10,'b'=>11,'c'=>12,'d'=>13,'e'=>14,'f'=>15,'g'=>16,'h'=>17,'i'=>18,'j'=>19,'k'=>20,'l'=>21,'m'=>22,
'n'=>23,'o'=>24,'p'=>25,'q'=>26,'r'=>27,'s'=>28,'t'=>29,'u'=>30,'v'=>31,'w'=>32,'x'=>33,'y'=>34,'z'=>35
);
if (strlen($iban) != $Countries[ substr($iban,0,2) ]) { return false; }
$MovedChar = substr($iban, 4) . substr($iban,0,4);
$MovedCharArray = str_split($MovedChar);
$NewString = "";
foreach ($MovedCharArray as $k => $v) {
if ( !is_numeric($MovedCharArray[$k]) ) {
$MovedCharArray[$k] = $Chars[$MovedCharArray[$k]];
}
$NewString .= $MovedCharArray[$k];
}
if (function_exists("bcmod")) { return bcmod($NewString, '97') == 1; }
// http://au2.php.net/manual/en/function.bcmod.php#38474
$x = $NewString; $y = "97";
$take = 5; $mod = "";
do {
$a = (int)$mod . substr($x, 0, $take);
$x = substr($x, $take);
$mod = $a % $y;
}
while (strlen($x));
return (int)$mod == 1;
}
The accepted answer is not the preferred way of validation. The specification dictates the following:
Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
Replace the two check digits by 00 (e.g. GB00 for the UK)
Move the four initial characters to the end of the string
Replace the letters in the string with digits, expanding the string as necessary, such that A or a = 10, B or b = 11, and Z or z = 35. Each alphabetic character is therefore replaced by 2 digits
Convert the string to an integer (i.e. ignore leading zeroes)
Calculate mod-97 of the new number, which results in the remainder
Subtract the remainder from 98, and use the result for the two check digits. If the result is a single digit number, pad it with a leading 0 to make a two-digit number
I've written a class that validates, formats and parses strings according to the spec. Hope this helps some save the time required to roll their own.
The code can be found on GitHub here.
top rated function does NOT work.
Just try a string with '%' in it...
I'm using this one :
function checkIBAN($iban) {
// Normalize input (remove spaces and make upcase)
$iban = strtoupper(str_replace(' ', '', $iban));
if (preg_match('/^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$/', $iban)) {
$country = substr($iban, 0, 2);
$check = intval(substr($iban, 2, 2));
$account = substr($iban, 4);
// To numeric representation
$search = range('A','Z');
foreach (range(10,35) as $tmp)
$replace[]=strval($tmp);
$numstr=str_replace($search, $replace, $account.$country.'00');
// Calculate checksum
$checksum = intval(substr($numstr, 0, 1));
for ($pos = 1; $pos < strlen($numstr); $pos++) {
$checksum *= 10;
$checksum += intval(substr($numstr, $pos,1));
$checksum %= 97;
}
return ((98-$checksum) == $check);
} else
return false;
}
I found this solution in cakephp 3.7 validation class. Plain beautiful php realization.
/**
* Check that the input value has a valid International Bank Account Number IBAN syntax
* Requirements are uppercase, no whitespaces, max length 34, country code and checksum exist at right spots,
* body matches against checksum via Mod97-10 algorithm
*
* #param string $check The value to check
*
* #return bool Success
*/
public static function iban($check)
{
if (!preg_match('/^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$/', $check)) {
return false;
}
$country = substr($check, 0, 2);
$checkInt = intval(substr($check, 2, 2));
$account = substr($check, 4);
$search = range('A', 'Z');
$replace = [];
foreach (range(10, 35) as $tmp) {
$replace[] = strval($tmp);
}
$numStr = str_replace($search, $replace, $account . $country . '00');
$checksum = intval(substr($numStr, 0, 1));
$numStrLength = strlen($numStr);
for ($pos = 1; $pos < $numStrLength; $pos++) {
$checksum *= 10;
$checksum += intval(substr($numStr, $pos, 1));
$checksum %= 97;
}
return ((98 - $checksum) === $checkInt);
}
This function check the IBAN and need GMP activate http://php.net/manual/en/book.gmp.php.
function checkIban($string){
$to_check = substr($string, 4).substr($string, 0,4);
$converted = '';
for ($i = 0; $i < strlen($to_check); $i++){
$char = strtoupper($to_check[$i]);
if(preg_match('/[0-9A-Z]/',$char)){
if(!preg_match('/\d/',$char)){
$char = ord($char)-55;
}
$converted .= $char;
}
}
// prevent: "gmp_mod() $num1 is not an integer string" error
$converted = ltrim($converted, '0');
return strlen($converted) && gmp_strval(gmp_mod($converted, '97')) == 1;
}
enjoy !

parse currency name to integer values in PHP

I have a currency value as follows say,
$6.041 billion USD (2006) or US$6.041 billion (2009)[1] or €6.041 billion (2010)[1].
I want to parse the currency value in such a way that I want to store it in three different variables i.e. $number, $currency, $year (i.e) $number = 6,041,000,000 and$currency = "euro" and $year = 2010.
The problem is that the string might have € or $ or USD. But I need to parse them accordingly.
Also I might end up having million also. According to that succeeding zeros should vary. Also I might or might not have decimal points in the currency. i.e 6.041 billion or 6 billion.
How to handle all the cases and store the result in the three variables I need?
similarly how to handle £(67.1) million (2011)[1] HK $ 648 million (2006) 22,440,000, 1,325.26 crore (US$241.2 million) [4].?
I am thinking of a brute force solution to handle each case one by one.
But that is not a apt one.
Is there any simplest way to do this?
Any help would be appreciated?
You could try running regular expressions something like this (untested):
if(preg_match('/([$€])([\d\.]+)\s?([\w]+)[^\(]*\((\d+)\)/',$value,$matches)){
switch($matches[1]){
case '$':
$currency = 'dollar';
break;
case '€':
$currency = 'euro';
break;
// and more for more currencies
}
$number = $matches[2];
switch($matches[3]){
case 'billion':
$number = intval($number*1000000000);
break;
case 'million':
$number = intval($number*1000000);
break;
// and more for more multipliers
}
$year = $matches[4];
}
Remember to add all the possible currency symbols you need to support in the first pair of square brackets in the regular expression [$€].
Untested and I am sure there are more elegant ways to do things, but this should work:
<?php
echo parseCurrency('$6.041 billion USD (2006)');
function parseCurrency($input){
if(strpos($input, 'USD') || strpos($input, '$')){
$currency = 'USD';
$floatVal = (float) get_string($input, '$', ' ');
}
elseif(strpos($input, '€')){
$currency = 'EUR';
$floatVal = (float) get_string($input, '€', ' ');
}
else{
$currency = 'undefined';
die();
}
if(strpos($input, 'billion'){
$number = $floatVal * 1000000000;
}
elseif(strpos($input, 'million'){
$number = $floatVal * 1000000;
}
else{
$number = 'undefined';
die();
}
if (preg_match('/\\([12][0-9]{3}\\)/', $input, $years)){
$year = $years[0];
}
else{
$year = 'undefined';
die();
}
return $number . ', ' . $currency . ', ' . $year;
}
//used to find million or billion
function get_string($string, $start, $end){
$string = " ".$string;
$pos = strpos($string,$start);
if ($pos == 0) return "";
$pos += strlen($start);
$len = strpos($string,$end,$pos) - $pos;
return substr($string,$pos,$len);
}

how to put comma in every 3 digit for a number

I want to put comma in every 3 digit for a number, for example.
$number = 1234567;
// should print 1,234,567
how can I do this?
update: please see this code
<?php
/**
* Get Popularity Text of a Domain via Alexa XML Data
*
* #return string|FALSE text or FALSE on error
*/
function alexa_get_rank($domain)
{
$alexa = "http://data.alexa.com/data?cli=10&dat=s&url=%s";
$request_url = sprintf($alexa, urlencode($domain));
$xml = simplexml_load_file($request_url);
if (!$xml) {
return FALSE;
}
$nodeAttributes = $xml->SD[1]->POPULARITY->attributes();
$text = (int) $nodeAttributes['TEXT'];
$num = number_format($text);
return $num;
}
in this return only 3 digit.
Use
echo number_format('1234567');
PHP Manual : number_format()
Try this one:
$number = 1234567;
echo number_format($number);
Use this as ref.
$number = 123456789;
$number = number_format($number);
echo $number;
See number_format.
<?php
echo number_format(1234567890); //1,234,567,890
$num = 1234567.65;
$num = number_format($num);
echo $num; // $num = 1,234,568
<?
$number = 1234567;
echo number_format($number); // this returns : 1,234,567
?>
Learn more about number_format();
$number = 1234.56;
//english notation (default)
$english_format_number = number_format($number);// 1,235
// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');// 1 234,56
//----------------------------------------------
$number = 1234.5678;
// english notation without thousands separator
$english_format_number = number_format($number, 2, '.', '');// 1234.57
Check out number_format() at php.net for more information.
To format numbers, one can use number_format
Try this code:
$number=1234567;
$number_format=number_format($number,0,".",","); // return 1,234,567

Need to re-format phone number entries in a PHP Formmail script

I have a simple text field for "Phone Number" in a contact form on a client's website. The formmail script returns whatever the user types into the field. For example, they'll receive "000-000-0000", "0000000000", (000) 000-000, etc. The client would like to receive all phone numbers in this form: 000-000-0000. Can someone provide a simple script that would strip out all extraneous punctuation, then re-insert the dashes?
I'm not a programmer, just a designer so I can't provide any existing code for anyone to evaluate, though I'll be happy to email the formmail script to anyone who can help.
Thanks.
A. Grant
<?php
function formatPhone($number)
{
$number = preg_replace('/[^\d]/', '', $number); //Remove anything that is not a number
if(strlen($number) < 10)
{
return false;
}
return substr($number, 0, 3) . '-' . substr($number, 3, 3) . '-' . substr($number, 6);
}
foreach(array('(858)5551212', '(858)555-1212', '8585551212','858-555-1212', '123') as $number)
{
$number = formatPhone($number);
if($number)
{
echo $number . "\n";
}
}
?>
the above returns:
858-555-1212
858-555-1212
858-555-1212
858-555-1212
function format_phone($phone)
{
$phone = preg_replace("/[^0-9]/", "", $phone);
if(strlen($phone) == 7)
return preg_replace("/([0-9]{3})([0-9]{4})/", "$1-$2", $phone);
elseif(strlen($phone) == 10)
return preg_replace("/([0-9]{3})([0-9]{3})([0-9]{4})/", "($1) $2-$3", $phone);
else
return $phone;
}
something like this
function formatPhone($number)
{
$number = str_replace(array('(', ')', '-', ' '), '', $number);
if (strlen($number) == 10)
{
$area = substr($number, 0, 3);
$part1 = substr($number, 3, 3);
$part2 = substr($number, 6);
return "$area-$part1-$part2";
}
else
{
return false;
}
}
If the number passed in is 10 digits long, it will return the properly formatted number. Otherwise, it will return FALSE
//phone number format
//example $phone = '1111111111'
$area = substr($phone, 0, 3);
$part1 = substr($phone, 3, 3);
$part2 = substr($phone, 6);
$phone = '('.$area.') '.$part1.'-'.$part2;
echo $phone;
//will look like (111) 111-1111

Categories