Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/285.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.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
设计决策:将JSON中的西里尔字符与PHP匹配_Php_Regex_Json_Character Encoding_Http Headers - Fatal编程技术网

设计决策:将JSON中的西里尔字符与PHP匹配

设计决策:将JSON中的西里尔字符与PHP匹配,php,regex,json,character-encoding,http-headers,Php,Regex,Json,Character Encoding,Http Headers,我正在为CMS开发一个插件,但有一个意想不到的问题:因为插件支持多语言,所以输入可以是任何unicode字符集。该插件以json格式保存数据,并包含具有属性value和lookup的对象。对于value一切正常,但是PHP使用lookup属性来检索这些实体,并在某些时候通过regex(内容过滤器)进行检索。 问题是: 对于非拉丁字符(例如,Бimk_ССПСМ),正则表达式中的\w(单词char)不匹配任何内容有没有办法将西里尔字母字符识别为单词字符?还有其他隐藏的捕获物吗? 数据格式为JSON

我正在为CMS开发一个插件,但有一个意想不到的问题:因为插件支持多语言,所以输入可以是任何unicode字符集。该插件以json格式保存数据,并包含具有属性
value
lookup
的对象。对于
value
一切正常,但是PHP使用
lookup
属性来检索这些实体,并在某些时候通过regex(内容过滤器)进行检索。 问题是:

  • 对于非拉丁字符(例如,Бimk_ССПСМ),正则表达式中的
    \w
    (单词char)不匹配任何内容有没有办法将西里尔字母字符识别为单词字符?还有其他隐藏的捕获物吗?
  • 数据格式为JSON,非拉丁字符转换为JS unicodes,例如:
    \u042D\u043A\u0441\u043F\u043E\u0440\u0442
    不这样做安全吗?(服务器限制等)
  • 我提出的“设计”大问题源于前两个问题:

    我应该允许使用非拉丁字母表语言的用户使用自己的字符进行
    查找
    属性,还是应该强制他们使用传统的“word”字符,即a、b、c等+下划线(因此是另一种语言的字母表)?我希望能有一个技术建议来指导这个决定(而不是用户体验)。

    第一个问题 对于非拉丁字符(例如,Бimk_ССПСМ),正则表达式中的
    \w
    (单词char)不匹配任何内容。有没有办法把西里尔文字字符识别为单词字符?还有其他隐藏的陷阱吗

    您只需打开
    u
    标志:

    preg_match("#^\w+$#u", $str);
    

    这些数据在这里具有误导性:

    u(
    PCRE\u UTF8

    此修饰符打开与Perl不兼容的PCRE的附加功能。模式和主题字符串被视为UTF-8。此修饰符可从Unix上的PHP4.1.0或更高版本以及win32上的PHP4.2.3获得。从PHP4.3.5开始检查模式和主题的UTF-8有效性。无效的主题将导致preg_*函数不匹配;无效模式将触发级别E_警告错误。自PHP 5.3.4(分别为PCRE 7.3 2007-08-28)以来,五个和六个八位组UTF-8序列被视为无效;以前,这些被认为是有效的UTF-8

    我说这是误导性的,因为从上面的ideone测试来看,它不仅启用了PCRE_UTF8,而且还启用了PCRE_UCP(Unicode字符属性),这是您在这里想要的行为

    以下是PCRE文档对此的描述:

    PCRE\u UTF8

    此选项使PCRE将模式和主题视为UTF-8字符的字符串,而不是单字节字符串。但是,只有当PCRE构建为包含UTF支持时,它才可用。否则,使用此选项会引发错误。有关此选项如何更改PCRE行为的详细信息,请参见pcreunicode页面

    PCRE\U UCP

    此选项更改PCRE处理
    \B
    \B
    \D
    \D
    \S
    \S
    \W
    \W
    ,以及某些POSIX字符类的方式。默认情况下,仅识别ASCII字符,但如果设置了
    PCRE\u UCP
    ,则使用Unicode属性对字符进行分类。pcrepattern页面中有关泛型字符类型的部分提供了更多详细信息。如果设置了
    PCRE\u UCP
    ,则匹配其中一个受影响的项目需要更长的时间。只有使用Unicode属性支持编译PCRE时,此选项才可用

    如果您想让它一目了然,将设置
    PCRE\u UCP
    标志,您可以在开始时将其插入图案本身,如下所示:

    preg_match("#(*UCP)^\w+$#u", $str);
    
    另一个可能出现在模式开头的特殊序列是
    (*UCP)
    。这与设置
    PCRE\u UCP
    选项的效果相同:它使序列(如
    \d
    \w
    )使用Unicode属性确定字符类型,而不是通过查找表仅识别代码小于128的字符

    第二个问题 数据格式为JSON,非拉丁字符转换为JS unicodes,例如:
    \u042D\u043A\u0441\u043F\u043E\u0440\u0442
    。不这样做安全吗?(服务器限制等)

    只要
    内容类型
    标题定义了正确的编码,就可以安全地不这样做

    因此,您可能需要使用以下内容:

    header('Content-Type: application/json; charset=utf-8');
    
    确保你真的用UTF8发送

    然而,在转义序列中编码这些字符会使整个ASCII兼容,因此基本上可以通过这种方式完全消除问题

    设计问题 我应该允许使用非拉丁字母表语言的用户使用自己的字符进行
    查找
    属性,还是应该强制他们使用传统的“word”字符,即a、b、c等+下划线(因此是另一种语言的字母表)?我希望能有一个技术建议来指导这个决定(而不是UX)

    从技术上讲,只要整个堆栈支持Unicode(浏览器、PHP、数据库等),我认为这种方法没有问题。只需确保测试良好,并在数据库中使用支持Unicode的列类型即可

    小心,PHP是一种糟糕的字符串支持语言,因此您必须确保使用正确的函数(除非您确实需要字节计数,否则请避免使用非Unicode的函数,如
    strlen
    等)


    要确保一切正常运行,可能需要做更多的工作,但如果你想支持这一点,那就没有问题。

    这不是一个问题。我能回答第一部分,但不能回答第二部分。你会接受谁的答案?@Stribizev发现谜题的任何部分都会得到奖励。你建议我将这个问题重新措辞并分成2/3个问题吗?谢谢你的严格回答!A.