Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP字符串求值方法_Php_Mysql_Lookup_Telephony_String Evaluation - Fatal编程技术网

PHP字符串求值方法

PHP字符串求值方法,php,mysql,lookup,telephony,string-evaluation,Php,Mysql,Lookup,Telephony,String Evaluation,希望一位伟大的智者能在这里帮助我 我遇到的情况是,我将从提供商处收到一个国际电话号码,我必须进行数据库查找,并找出该电话号码拨打的国家、地区和电话类型 例如,假设我将收到一个电话号码+393234567891。我得在一张桌子上查一下那个电话号码所属的国家。所以我知道'39'是意大利,我在数据库中有一个国家代码,但我必须确定这个号码是固定电话还是手机。为此,我需要从电话号码中获得更多信息,因此“39”是固定电话,“393”是手机。我需要看到电话号码包含“393”,因此我知道这是一部手机 我的问题是

希望一位伟大的智者能在这里帮助我

我遇到的情况是,我将从提供商处收到一个国际电话号码,我必须进行数据库查找,并找出该电话号码拨打的国家、地区和电话类型

例如,假设我将收到一个电话号码+393234567891。我得在一张桌子上查一下那个电话号码所属的国家。所以我知道'39'是意大利,我在数据库中有一个国家代码,但我必须确定这个号码是固定电话还是手机。为此,我需要从电话号码中获得更多信息,因此“39”是固定电话,“393”是手机。我需要看到电话号码包含“393”,因此我知道这是一部手机

我的问题是什么是最好的评估方法?是否会像首先将前两个电话号码与数据库进行比较,然后是前三个,然后是前四个,直到我返回一个结果一样,对电话号码的每个部分进行循环?例如,如果我继续这个例子,将意大利的'39'与db进行比较,我会得到一系列结果,因为有'39'和'393'以及'3939'等等。那么,使用整个电话号码来获得电话号码前缀的精确匹配的最佳方法是什么

我本以为只需循环电话号码,并在循环中添加电话号码的一位数字,直到我只返回一个结果,我只想确保这是实现这一点最有效的方法


有什么建议吗?谢谢

如果实际电话号码是固定大小的,您可以将其删除。与子系统替换;e、 g.数字长度为8位:

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

$code now将只包含代码部分。因此,您可以轻松地计算数字并找出您需要的内容。

我假设您有一个如下表:

prefix (id, number)
数据如下:

1, '39'
2, '393'
3, '33'
4, '331'
1, 1, 'country', 'Italy'
2, 2, 'country', 'Italy'
3, 2, 'type',    'Landline'
4, 3, 'country', 'France'
5, 4, 'country', 'France'
6, 4, 'city',    'Paris'
您可以使用类似以下的反转获得最长的匹配:

我没有测试它,但是假设您的最短前缀是2个字符,您可能会得到一些改进(这将只检查以
39
开头的前缀,这是您所有前缀的1%):

然后,您可以有一个不同的表,其中的信息附加到该前缀,如:

prefixinfo (id, prefix_id, type, data)
数据如下:

1, '39'
2, '393'
3, '33'
4, '331'
1, 1, 'country', 'Italy'
2, 2, 'country', 'Italy'
3, 2, 'type',    'Landline'
4, 3, 'country', 'France'
5, 4, 'country', 'France'
6, 4, 'city',    'Paris'

最后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
}

我想这是可行的,但我想我必须看到确切的数据结构才能确定。但是,是的,两个表绝对是可取的

在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 ;
}

你问的是比较数据,而不是获取国家和地区代码数据,对吗?这不会有帮助,因为他有许多不同长度的前缀(如“39”、“393”和“3939”)。他需要将数字与最长的匹配前缀进行比较-这就是我解决问题的方法-注意,上面的代码中有一个错误-“ORDER BY number.length”应该是“ORDER BY length(number)DESC”,您可以将类型添加到前缀表(number,country,type)中,并在单个操作中获取结果。@symcbean Thnaks,更正!但我不能将信息块添加到前缀中,因为它们之间存在一对多关系。由于查询将只返回
393
(因为这是最具体的)的ID,因此必须从该记录开始提供所有信息。-由于像这样的
是最昂贵的操作,我不想得到所有适用的前缀,而只想得到最具体的前缀。我只是不明白为什么要将“country”和“type”分成两行,前缀为\u id=2。否则我喜欢这个解决方案。@Slava我将问题建模为可以自由附加到前缀的信息块。正如你在巴黎看到的例子,我们知道那个电话号码的位置。以手机为例,我们不知道它的位置,只知道它是一部手机。比如说卫星电话,我们甚至不知道这个国家。我可以创建一个包含许多字段的表,其中大多数字段在大多数情况下都是空的,但我不喜欢这种冗余。此外,在这个模型中,您可以自由添加新类型的信息,而无需更改表结构。好的,您也可以将所有这些信息合并到一个字段(xml/serialize/whatever)中,并且拥有更少的列(3个与您的4个相比),但好的,这只是另一种方法:)。您应该让数据库来做。如果脚本能够很好地处理大型数据数据库,那么这些数据库就不会实现如此复杂的查询语言。@Slava我大体上并不反对。但在这种情况下,,