Метод оценки строк PHP - PullRequest
       13

Метод оценки строк PHP

2 голосов
/ 06 апреля 2011

Надеясь, один из великих умов может помочь мне здесь.

У меня есть ситуация, когда я получу международный телефонный номер от провайдера, и мне нужно выполнить поиск в базе данных и выяснить страну, регион и тип телефона, по которому звонит телефонный номер.

Например, скажем, я получу номер телефона +393234567891. Я должен посмотреть в таблице страну, которой принадлежит номер телефона. поэтому я знаю, что «39» - это Италия, и у меня есть это в качестве кода страны в базе данных, но я должен определить, является ли номер стационарным или мобильным телефоном. Для этого мне нужно больше информации из номера телефона, поэтому «39» - это стационарный телефон, а «393» - это мобильный телефон. Мне нужно убедиться, что номер телефона содержит «393», и поэтому я знаю, что это мобильный телефон.

Мой вопрос: как лучше всего это оценить? Будет ли циклически проходить каждый сегмент телефонного номера, как сначала сравнить первые два телефонных номера с базой данных, затем первые три, затем первые четыре, пока я не вернусь с одним единственным результатом? Например, если я продолжу этот пример и сравню «39» для Италии с БД, я вернусь с кучей результатов, потому что есть «39», «393», «3939» и так далее. Итак, как лучше всего использовать весь номер телефона, чтобы получить точное соответствие префикса номера телефона?

Я бы подумал просто просмотреть номер телефона и добавить цифру номера телефона в цикл, пока не вернусь только с одним результатом, я просто хочу убедиться, что это самый эффективный способ для достижения этой цели. ,

Есть какие-нибудь рекомендации? Спасибо!

Ответы [ 4 ]

2 голосов
/ 06 апреля 2011

Я предполагаю, что у вас есть таблица типа:

prefix (id, number)

с данными типа:

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

Вы можете получить самый длинный матч с reverse 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'
0 голосов
/ 06 апреля 2011

Может быть лучше проводить сравнения в PHP с простыми циклами массивов, даже если у вас есть данные в Mysql. Создайте из базы данных (и кеша) массив 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 ;
}
0 голосов
/ 06 апреля 2011

Последние 3, которые означают мобильный телефон в 393, это то же самое для каждой страны?

Идеальной ситуацией будет иметь таблицу для стран, а затем другую таблицу с соответствующими префиксами

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-запросов.Так что найдите код страны, вытолкнув первые две цифры (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
}

. Я считаю, что это сработает, но, наверное, мне нужно было бы увидеть точную структуру данных, чтобы быть уверенным.Но да, две таблицы определенно желательны

0 голосов
/ 06 апреля 2011

если фактический номер телефона имеет фиксированный размер, вы можете удалить его. с sub_strreplace; например номера состоят из 8 цифр:

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

$ код теперь будет содержать только часть кода. так что вы можете легко считать цифры и узнать, что вам нужно.

...