Skip to content
← Back to Functions
Code

Phone Number Cleaner

Normalizes phone numbers into a display value and optional E.164-like storage form.

Function signature

ogCleanPhoneNumber(phone, country_code = 'US', options = array())

Categories

  • Forms and Validation

Parameters

phoneRaw phone number.country_codeDefault country code such as US.optionsOptional min_digits and max_digits values. Recognized keys: `max_digits`, `min_digits`.

Return value

Short public-safe status message.

  • digits
  • display
  • e164

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets and internal paths out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Normalizes phone numbers into a display value and optional E.164-like storage form.
 *
 * Primary use case: Contact forms, ecommerce profiles, SMS workflows.
 * Typical inputs: raw phone, country default.
 * Typical output: clean phone metadata.
 *
 * Implementation note: Do not promise perfect validation without region metadata.
 *
 * @param string $phone Raw phone number.
 * @param string $country_code Default country code such as US.
 * @param array $options Optional min_digits and max_digits values.
 * @return array Structured phone normalization result.
 */
function ogCleanPhoneNumber($phone, $country_code = 'US', $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array('digits' => '', 'display' => '', 'e164' => '')
	);

	$phone = trim((string)$phone);
	$country_code = strtoupper(trim((string)$country_code));
	if (!is_array($options)) {
		$options = array();
	}

	if (empty($phone)) {
		$result['message'] = 'Missing phone number.';
		return $result;
	}

	$extension = '';
	if (preg_match('/(?:ext\.?|x)\s*([0-9]{1,8})$/i', $phone, $matches)) {
		$extension = $matches[1];
		$phone = preg_replace('/(?:ext\.?|x)\s*[0-9]{1,8}$/i', '', $phone);
	}

	$digits = preg_replace('/[^0-9]/', '', $phone);
	$min_digits = 7;
	$max_digits = 15;
	if (!empty($options['min_digits'])) {
		$min_digits = (int)$options['min_digits'];
	}
	if (!empty($options['max_digits'])) {
		$max_digits = (int)$options['max_digits'];
	}

	if (strlen($digits) < $min_digits || strlen($digits) > $max_digits) {
		$result['message'] = 'Phone number has an invalid digit count.';
		$result['data']['digits'] = $digits;
		return $result;
	}

	$e164 = '';
	if ($country_code === 'US' || $country_code === 'CA') {
		if (strlen($digits) == 10) {
			$e164 = '+1' . $digits;
		} elseif (strlen($digits) == 11 && substr($digits, 0, 1) === '1') {
			$e164 = '+' . $digits;
		}
	} elseif (strlen($digits) >= 8) {
		$e164 = '+' . $digits;
	}

	$display = $digits;
	if (strlen($digits) == 10) {
		$display = '(' . substr($digits, 0, 3) . ') ' . substr($digits, 3, 3) . '-' . substr($digits, 6);
	}
	if (!empty($extension)) {
		$display .= ' ext. ' . $extension;
	}

	$result['success'] = true;
	$result['message'] = 'Phone number normalized.';
	$result['data'] = array(
		'digits' => $digits,
		'display' => $display,
		'e164' => $e164,
		'extension' => $extension,
		'country_code' => $country_code
	);

	return $result;
}