2

偉大な頭脳の 1 つがここで私を助けてくれることを願っています。

プロバイダーから国際電話番号を受け取る状況があり、データベースを検索して、電話番号がかけている国、地域、および電話の種類を把握する必要があります。

たとえば、電話番号 +393234567891 を受け取るとします。電話番号が属する国をテーブルで検索する必要があります。'39' がイタリアであることはわかっています。これは国コードとしてデータベースに登録されていますが、その番号が固定電話か携帯電話かを判断する必要があります。そのためには、電話番号からさらに情報が必要なので、'39' は固定電話、'393' は携帯電話です。電話番号に「393」が含まれていることを確認する必要があるため、それが携帯電話であることがわかります。

私の質問は、これを評価する最良の方法は何ですか? 電話番号の各セグメントをループして、最初の 2 つの電話番号をデータベースと比較し、次に最初の 3 つ、次に最初の 4 つを 1 つの結果が得られるまで比較しますか? たとえば、この例を続けてイタリアの '39' を db と比較すると、'39' と '393' と '3939' などがあるため、一連の結果が返されます。では、電話番号のプレフィックスと完全に一致するように電話番号全体を使用する最善の方法は何でしょうか?

電話番号をループして、電話番号の数字をループに追加して、結果が 1 つだけ返されるようにすることを考えていましたが、これが最も効率的な方法であることを確認したいだけです。

推奨事項はありますか?ありがとう!

4

4 に答える 4

2

次のようなテーブルがあるとします。

prefix (id, number)

次のようなデータを使用:

1, '39'
2, '393'
3, '33'
4, '331'

逆の LIKEで最長一致を取得できます。

SELECT id
FROM prefix
WHERE "393234567891" LIKE CONCAT(number, "%")
ORDER BY LENGTH(number)
LIMIT 1;

私はそれをテストしていませんが、最短のプレフィックスが2文字であると仮定すると、次のように改善される可能性があります(これは、で始まるプレフィックスのみをチェックします39。つまり、持っているすべてのプレフィックスの1%です):

SELECT id
FROM prefix
WHERE "393234567891" LIKE CONCAT(number, "%")
    AND number LIKE "39%"
ORDER BY LENGTH(number)
LIMIT 1;

次に、次のように、そのプレフィックスに情報が添付された別のテーブルを作成できます。

prefixinfo (id, prefix_id, type, data)

次のようなデータを使用:

1, 1, 'country', 'Italy'
2, 2, 'country', 'Italy'
3, 2, 'type',    'Landline'
4, 3, 'country', 'France'
5, 4, 'country', 'France'
6, 4, 'city',    'Paris'
于 2011-04-06T10:05:18.000 に答える
0

393 の携帯電話を表す最後の 3 つは、どの国でも同じですか?

理想的な状況は、国のテーブルと、関連する接頭辞を持つ別のテーブルを持つことです

Countries table                        Subsearch Table

countryMatch: 39                       substrMatch: 3 // for 393              
countryName: "Italy"                   substrCountry: 39
                                       substrMeaning: "cell"
                                       ...................
                                       substrMatch: 5 // 395
                                       substrCountry: 39
                                       substrMeaning: "something else"

そうすれば、国を特定したら、残りの検索を制限して、たとえば 393、3939 のようにさらに制限することができます。

SQLクエリを使用して一致するものが見つかるまで、少しずつループして、提案された方法は適切だと思います。したがって、最初の 2 桁 (39) をポップして国コードを検索し、見つかった場合はサブ検索テーブルにクエリを実行して結果を取得します。これらの結果をループして国コードに追加し、一致するかどうかを確認します

$subsearchArr = array("3" => "cell","5" => "something else") # from the database 
$match = false;
$country = 39;

foreach($subsearchArr as $key => $value)
{
  # append $key to $country e.g. 393, 395
  # if this is a match to the string
  # set match to true and do your logic
}

if($match == false) # no match so landline
{
  # logic here if landline
}

それはうまくいくと思いますが、正確なデータ構造を確認する必要があると思います。しかし、ええ、2つのテーブルは間違いなく望ましいです

于 2011-04-06T10:11:06.810 に答える
0

実際の電話番号が固定サイズの場合は、削除できます。sub_strreplace; たとえば、数字は 8 桁です。

$code = substr_replace($number,'',-1,8);

$code にはコード部分のみが含まれるようになりました。簡単に数字を数えて、必要なものを見つけることができます。

于 2011-04-06T09:48:17.853 に答える
-1

Mysql にデータがある場合でも、単純な配列ループを使用して PHP で比較を行う方がよい場合があります。モバイル、固定電話、地域などを区別するために、データベースから構築 (およびキャッシュ) された予想される国コードと各国内の既知の一意のプレフィックスの PHP 配列。

国コードごとに、入力した電話番号がそのコードで始まるかどうかを確認します。国が見つかったら、電話番号から国コードを削除し、残りの番号をその国の既知の携帯電話番号プレフィックスのリストと照合します。見つかれば携帯です。見つからない場合は、固定電話です。

たとえば、ギリシャの国コードは 30 で、その後はすべての携帯電話が 69 で始まります。ただし、携帯電話番号のプレフィックスが市外局番と区別できない国 (米国やカナダなど) を扱っている場合は、うまくいきません。

function checkMSISDN($msisdn) {

    $countries = array(
        'gr' => array(
            'countryPrefix' => '30',
            'mobilePrefix' => '3069',
            'length' => 12,
        ),
        'it' => array(
            'countryPrefix' => '39',
            'mobilePrefix' => '393',
            'length' => 12,
        ),
    ) ;

    foreach ($countries as $countryName => $countryRules)  {

        $msisdnCurrent = $msisdn ;

        $countryPrefix = $countryRules['countryPrefix'] ;
        $fullPrefix = $countryRules['mobilePrefix'] ;

        //remove leading + if any
        if (substr($msisdnCurrent, 0, 1) == '+') {
            $msisdnCurrent = substr($msisdnCurrent, 1) ;
        }

        //remove leading 00 if any
        if (substr($msisdnCurrent, 0, 2) == '00') {
            $msisdnCurrent = substr($msisdnCurrent, 2) ;
        }

        $msisdnLength = strlen($msisdnCurrent) ;
        if ($msisdnLength != $countryRules['length']) {
            //sanity check, not this country
            continue ;
        }

        if (substr($msisdnCurrent, 0, strlen($countryPrefix)) != $countryPrefix) {
            //not this country
            continue ;
        }

        if (substr($msisdnCurrent, 0, strlen($fullPrefix)) != $fullPrefix) {
            //not mobile
            return "isLandline" ;
        }
        else {
            //mobile
            return "isMobile" ;
        }
    }
    return false ;
}
于 2011-04-06T10:37:17.047 に答える