PHPで電話番号を区切る方法【現役エンジニアが解説】

PROGRAM

今回は、PHPで電話番号を区切る方法について、電話番号マスタを取り込む方法と電話番号の形式への変換方法に分け、簡単に解説していきます。

電話番号マスタを取り込む方法

まず、市外局番と市内局番の電話番号マスタを総務省のページよりダウンロードします。

CREATE TABLE MST_PHONE(
    BANGO VARCHAR(6),
    BANGO_KUKAKU_CD VARCHAR(255),
    MA VARCHAR(255),
    SHIGAI VARCHAR(5),
    SHINAI VARCHAR(5),
    JIGYOSHA VARCHAR(255),
    JOKYO VARCHAR(255),
    BIKO VARCHAR(255),
    PRIMARY KEY(BANGO)
);

次に、ダウンロードしてきたマスタの形式に合わせて、上記のように、データベースに電話番号マスタのテーブルを作成します。

$pdo = new PDO("mysql:host={host};dbname={dbname}", "{user}", "{password}");
$pdo->beginTransaction();
$tmp = fopen("{csv_file_path}", "r");
$cnt = 0;
while ( $csv = fgetcsv($tmp) ) {
    if ($cnt == 0) {$cnt++;continue;}
    $sql = "INSERT INTO MST_PHONE (BANGO_KUKAKU_CD, MA, BANGO, SHIGAI, SHINAI, JIGYOSHA, JOKYO, BIKO) ".
           "VALUES(:BANGO_KUKAKU_CD, :MA, :BANGO, :SHIGAI, :SHINAI, :JIGYOSHA, :JOKYO, :BIKO)".
    $stmt = $pdo->prepare($sql);
    $stmt->bindValue(':BANGO_KUKAKU_CD', $csv[0]), PDO::PARAM_STR);
    $stmt->bindValue(':MA', $csv[1]), PDO::PARAM_STR);
    $stmt->bindValue(':BANGO', $csv[2]), PDO::PARAM_STR);
    $stmt->bindValue(':SHIGAI', $csv[3]), PDO::PARAM_STR);
    $stmt->bindValue(':SHINAI', $csv[4]), PDO::PARAM_STR);
    $stmt->bindValue(':JIGYOSHA', $csv[5]), PDO::PARAM_STR);
    $stmt->bindValue(':JOKYO', $csv[6]), PDO::PARAM_STR);
    $stmt->bindValue(':BIKO', $csv[7]), PDO::PARAM_STR);
    $result = $stmt->execute();
    if (!$result) {
        $pdo->rollBack();
        die("失敗");
    }
    $cnt++;
}
$pdo->commit();
echo "成功";

最後に、ダウンロードしてきたマスタを一つのCSVにまとめて、上記のコードのように、PHPのfopen関数でCSVファイルのパスを指定して、データベースに取り込みを行っていきます。

電話番号の形式への変換方法

電話番号マスタの準備が整えば、あとは電話番号を区切る処理を実装するだけです。

取り込んだマスタでは市外局番と市内局番を分けて持っているため、先頭6桁でデータベースからこれらの情報を取得してきます。

function toPhoneNumber($input) {
    $number = preg_replace('/[^\d]++/', '', $input);
    if ( strlen($number) < 10  || strlen($number) > 11 ) {return false;}
    if (strlen($number) == 11) {
        return substr($number,0,3)."-".substr($number,3,4)."-".substr($number,7,4);
    } else if (strlen($number) == 10) {
        if(strlen($number) == 10 && in_array(substr($number,0,4),["0120","0800"])) {
            return substr($number,0,4)."-".substr($number,4,3)."-".substr($number,7,3);
        }
        $sql = "SELECT SHIGAI, SHINAI FROM MST_PHONE WHERE BANGO = :BANGO";
        $pdo = new PDO("mysql:host={host};dbname={dbname}", "{user}", "{password}");
        $stmt = $pdo->prepare($sql);
        $stmt->bindValue(":BANGO", substr($number,0,6), PDO::PARAM_STR);
        $tel = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($tel) {
	    $SHIGAI = $tel['SHIGAI'];
	    $SHINAI = $tel['SHINAI'];
            return $SHIGAI."-".$SHINAI."-".substr($number,6);
        } else {
            return false;
        }
    }
}

上記のコードでは、まず引数から半角数字以外の余分なものを削除し、携帯電話やフリーダイヤルの場合を除き、電話番号マスタから取得した情報をもとに、市外局番と市内局番、それ以降に分けています。

電話番号の課題

市外局番と市内局番の分け方は今後変わる可能性があります。

そのため、電話番号マスタは定期的なメンテナンスが必要です。

また、昔の分け方をいつまでも正として使い続ける方もいるため、プログラムで分けてしまうことが正しいことかどうかはよく検討する必要があるでしょう。