PHP 7.1 数组兼职竟然可以重复,如何去掉这个特性? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ioioioioioioi
V2EX    PHP

PHP 7.1 数组兼职竟然可以重复,如何去掉这个特性?

  •  1
     
  •   ioioioioioioi 2017-01-19 12:58:50 +08:00 5881 次点击
    这是一个创建于 3189 天前的主题,其中的信息可能已经有所发展或是发生改变。
    $a['test'] = 'hi'; $a['test'] = 'hello'; 得到的结果是 [ [test] => hi [test] => hello ] 而我实际想要的是: [ [test] => hello ] 
    /div>
    第 1 条附言    2017-01-19 14:16:40 +08:00

    大家感兴趣可以这样测试,我这边出现重复:

    $keys = ['meta_description']; $ret = array_combine($keys, $keys); $ret['meta_description'] = 'tom'; echo '<pre>';print_r($ret);echo '</pre>';die; # 得到结果 Array ( [meta_description] => meta_description [meta_description] => tom ) 

    @haiyang416 @neilwong @skydiver @skydiver @zi

    第 2 条附言    2017-01-19 14:55:20 +08:00
    你们没有重复吗?
    第 3 条附言    2017-01-19 22:42:56 +08:00
    最终解决办法,给键值加 md5
    64 条回复    2017-02-14 16:14:59 +08:00
    haiyang416
        1
    haiyang416  
       2017-01-19 13:01:18 +08:00 via Android
    按理说这样的情况不可能出现,能不能贴一下完整的代码!
    haiyang416
        2
    haiyang416  
       2017-01-19 13:02:04 +08:00 via Android
    感叹号应该是?
    haiyang416
        3
    haiyang416  
       2017-01-19 13:10:27 +08:00 via Android
    特意在 PHP 7 测试了一遍,没有遇到你这样的问题。
    ioioioioioioi
        4
    ioioioioioioi  
    OP
       2017-01-19 13:25:56 +08:00
    @haiyang416 嗯,我测试了,没有出现,但是确实有:
    [1111] => Array
    (
    [meta_description] => meta_description
    [meta_description] => blalbal
    )
    neilwong
        5
    neilwong  
       2017-01-19 13:26:02 +08:00
    你逗呢?能测试好了再发帖么。
    skydiver
        6
    skydiver  
       2017-01-19 13:28:28 +08:00
    请给出完整的可重现测试用例
    anewg
        7
    anewg  
       2017-01-19 13:32:51 +08:00
    https://3v4l.org/8LZNd

    不懂楼主结果怎么弄出来的。。
    skydiver
        8
    skydiver  
       2017-01-19 13:35:11 +08:00
    key 里面有不可见字符的话,也会有这种结果
    比如:

    $a = [];

    $a["hell\u{2060}o"] = 1;
    $a["hello"] = 2;
    print_r($a);

    输出
    Array
    (
    [hell o] => 1
    [hello] => 2
    )
    skydiver
        9
    skydiver  
       2017-01-19 13:35:44 +08:00
    v2ex 自动排版了,输出是看不出空格的
    ioioioioioioi
        10
    ioioioioioioi  
    OP
       2017-01-19 13:45:48 +08:00
    @skydiver
    @anewg
    @skydiver
    @neilwong
    @haiyang416

    问题解决了,本来的代码是这样的:
    $ret = array_combine($keys, $keys);
    后面会对$ret 赋值(键值重复),
    这样修改后没有重复的问题了:
    $ret = $this->combineArr($keys);

    protected function combineArr($arr)
    {
    return array_combine($arr, $arr);
    }

    不知道为什么会出现这种情况。
    zi
        11
    zi  
       2017-01-19 13:50:58 +08:00
    @ioioioioioioi 眼睛都看花了,这修改前后有区别吗。。
    explon
        12
    explon  
       2017-01-19 13:55:14 +08:00
    小学生都会上网了
    ioioioioioioi
        13
    ioioioioioioi  
    OP
       2017-01-19 14:00:28 +08:00
    @zi 确实没什么区别,但是确实修复了我提到的 bug ,也是困惑中。。。
    luziafy
        14
    luziafy  
       2017-01-19 15:04:50 +08:00
    总想搞个大事情
    hheedat
        15
    hheedat  
       2017-01-19 15:44:55 +08:00   8
    你可能安装了假 PHP
    shiny
        16
    shiny  
       2017-01-19 15:49:33 +08:00 via iPhone
    这是想搞个大新闻啊,是不是什么隐藏字符在里面了。你要是代码能跑出来可以去官方报 bug 了
    Roope
        17
    Roope  
       2017-01-19 15:56:14 +08:00   1
    ```
    ~ # php t.php
    Array
    (
    [meta_description] => tom
    )
    ~ # ls
    t.php
    ~ # php -v
    PHP 7.1.0 (cli) (built: Dec 15 2016 21:09:42) ( NTS )
    Copyright (c) 1997-2016 The PHP Group
    Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.1.0, Copyright (c) 1999-2016, by Zend Technologies
    ```

    无法复现
    ioioioioioioi
        18
    ioioioioioioi  
    OP
       2017-01-19 15:56:35 +08:00
    @shiny 我按照这个方法确实重复的,要不你也跑跑看:
    $keys = ['meta_description'];

    $ret = array_combine($keys, $keys);

    $ret['meta_description'] = 'tom';

    echo '<pre>';print_r($ret);echo '</pre>';die;

    # 得到结果
    Array
    (
    [meta_description] => meta_description
    [meta_description] => tom
    )
    qiayue
        19
    qiayue  
    PRO
       2017-01-19 15:57:42 +08:00
    你用 array_keys 获取最后数组的键数组后,判断一下两个键是否相同
    qiayue
        20
    qiayue  
    PRO
       2017-01-19 15:59:20 +08:00   1
    楼主你新建一个 php 文件,然后从本帖复制代码过去,如果不重复,那就说明你之前的代码里有隐藏字符,在你贴到本贴时,隐藏字符已经丢失了,所以我们其他人测试不会出现你这个问题。
    zi
        21
    zi  
       2017-01-19 15:59:41 +08:00
    @ioioioioioioi 我也无法复现

    ~# php test.php
    <pre>Array
    (
    [meta_description] => tom
    )
    </pre>

    ~# php -v
    PHP 7.1.0 (cli) (built: Dec 2 2016 15:44:02) ( NTS )
    Copyright (c) 1997-2016 The PHP Group
    Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies
    ioioioioioioi
        22
    ioioioioioioi  
    OP
       2017-01-19 16:00:04 +08:00
    @Roope 晕了,我再去测测看,我的 PHP 有问题?
    HanSonJ
        23
    HanSonJ  
       2017-01-19 16:00:28 +08:00
    @ioioioioioioi http://imgur.com/a/uqeGQ 你应该是用了假的编辑器和解析器解析了一个假的 PHP ,所以给了一个假的结果
    moult
        24
    moult  
       2017-01-19 16:02:07 +08:00
    楼主在下面再来几句代码!我就不信 KEY 是一样的。老衲不信这个邪了。
    foreach($ret as $key=>$value){
    var_dump($key);
    var_dump(bin2hex($key));
    }
    lyragosa
        25
    lyragosa  
       2017-01-19 16:02:52 +08:00
    楼主你这是要搞大新闻啊……
    ioioioioioioi
        26
    ioioioioioioi  
    OP
       2017-01-19 16:04:16 +08:00
    @qiayue 新建文件测试确实没有重复了,可能如你所说,含有隐藏字符,这个是哥哥语言的翻译键值,或许是加其他语言翻译导致的,感谢,我再具体看看
    haiyang416
        27
    haiyang416  
       2017-01-19 16:10:00 +08:00 via Android
    @ioioioioioioi 你可能装了假 PHP7 ,我测试本地后还专门去网上找各个 PHP sandbox 粘帖运行你给出的代码,结果全是:
    <pre>Array
    (
    [meta_description] => tom
    )
    </pre>

    没有复现,没办法。
    ioioioioioioi
        28
    ioioioioioioi  
    OP
       2017-01-19 16:28:16 +08:00
    @haiyang416 嗯,感谢,那应该是隐藏字符吧。
    mko0okmko0
        29
    mko0okmko0  
       2017-01-19 16:53:40 +08:00
    重复使用的 key 就用一个变数存起来吧.重复使用$k 的方式可避免手残输入了神奇的文字.
    kaneg
        30
    kaneg  
       2017-01-19 16:56:57 +08:00
    或者是里面的字符看起来一样,其实不一样,我就被这两个坑过:[…] 和 [...]
    realpg
        31
    realpg  
    PRO
       2017-01-19 17:01:31 +08:00
    @ioioioioioioi
    报一下你的 PHP 版本, PHP 安装方式
    gouchaoer
        32
    gouchaoer  
       2017-01-19 17:03:39 +08:00 via Android
    可能是 linux 下带了\r 之类的,你比较一下两个 key 肯定不一样,退一万步。。。 array 本质上是 hash , key 怎么可能相同
    bianhua
        33
    bianhua  
       2017-01-19 17:05:40 +08:00
    楼主,建议你将出错的文件上传一下,这样大家可以帮你分析一下到底是怎么回事。
    void1900
        34
    void1900  
       2017-01-19 17:34:38 +08:00
    哈哈哈 sublime 这些隐藏字符会标出来~ 安利一波
    shiny
        35
    shiny  
       2017-01-19 17:53:52 +08:00
    @ioioioioioioi 我用 Docker 升级到 PHP7.1.0 来执行你的代码,并没有重现出你的结果。
    shiny
        36
    shiny  
       2017-01-19 17:55:05 +08:00
    建议你用能显示隐藏字符的编辑器查看下你本地的源码。
    flyingghost
        37
    flyingghost  
       2017-01-19 17:55:45 +08:00
    用 010editor 等 16 进制编辑器打开你的源码找找隐藏字符?
    youxiachai
        38
    youxiachai  
       2017-01-19 20:34:22 +08:00
    不可见字符....
    ioioioioioioi
        39
    ioioioioioioi  
    OP
       2017-01-19 20:36:35 +08:00
    @mko0okmko0
    @kaneg
    @realpg
    @gouchaoer
    @bianhua
    @void1900
    @shiny
    @flyingghost

    系统是 ubuntu16.04 , php7 ,法国源

    meta_description 是内部用户输入的键值,是各个翻译语言的键值,我上面贴出的结果,确实是我测试代码出的结果,但是后来 comment/uncomment 后测试又没有了,但是正式的代码,还是有重复的键值。哎,也不折腾了,通过对 meta_description 做特别处理解决了,不信还有第二个键值重复。能解释通的估计就是内部用户输入的键值 meta_description 含有隐藏字符了。
    Array
    (
    [meta_description] => meta_description
    [meta_description] => tom
    )
    realpg
        40
    realpg  
    PRO
       2017-01-19 20:39:19 +08:00 via Android
    @ioioioioioioi 请将能复现的数组按照 24 楼输出一下
    bianhua
        41
    bianhua  
       2017-01-19 20:58:30 +08:00
    @ioioioioioioi

    “估计”是不能真正解决问题的。你必须提供样本,问题不但无法准确定位,而且未来很有可能会在不经意的地方出现,比如那些效验用户输入的函数里。
    ioioioioioioi
        42
    ioioioioioioi  
    OP
       2017-01-19 21:10:37 +08:00
    @realpg
    @bianhua
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    string(16) "meta_description"
    string(32) "6d6574615f6465736372697074696f6e"
    ioioioioioioi
        43
    ioioioioioioi  
    OP
       2017-01-19 21:11:10 +08:00
    @realpg
    @bianhua 这是所有的 meta_description 键值
    bianhua
        44
    bianhua  
       2017-01-19 21:25:23 +08:00
    @ioioioioioioi

    那么这个问题很明显就不是“不可见字符”的问题了。

    你还是准备一个最小可复现的样本然后压缩好上传到能公开下载的地方吧。只有看了文件才能进一步排查问题。
    xbonline
        45
    xbonline  
       2017-01-19 21:41:56 +08:00
    也有可能是启用了啥 PHP 扩展造成的
    iyaozhen
        46
    iyaozhen  
       2017-01-19 22:35:01 +08:00 via Android
    同意楼上,估计是什么扩展
    ioioioioioioi
        47
    ioioioioioioi  
    OP
       2017-01-19 22:35:25 +08:00
    @bianhua 其他翻译也出现问了,键值也是 meta 开头 meta_description_detail , 测试了其他重复键值的,确并没用这样的错误。给键值加了 md5 后不再重复。
    ioioioioioioi
        48
    ioioioioioioi  
    OP
       2017-01-19 22:36:26 +08:00
    @xbonline
    @iyaozhen 但是加 md5 作为键值,不再出现重复的情况,啥情况?
    yangqi
        49
    yangqi  
       2017-01-19 22:56:15 +08:00
    应该是环境配置问题,贴 php -v, php -m
    ioioioioioioi
        50
    ioioioioioioi  
    OP
       2017-01-19 23:02:57 +08:00
    @yangqi
    PHP 7.1.0-5+deb.sury.org~xenial+1 (cli) ( NTS )
    Copyright (c) 1997-2016 The PHP Group
    Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.1.0-5+deb.sury.org~xenial+1, Copyright (c) 1999-2016, by Zend Technologies

    [PHP Modules]
    calendar
    Core
    ctype
    curl
    date
    dom
    exif
    fileinfo
    filter
    ftp
    gd
    gettext
    hash
    iconv
    igbinary
    json
    libxml
    mbstring
    mcrypt
    memcached
    msgpack
    mysqli
    mysqlnd
    OAuth
    openssl
    pcntl
    pcre
    PDO
    pdo_mysql
    Phar
    posix
    readline
    Reflection
    session
    shmop
    SimpleXML
    sockets
    SPL
    standard
    sysvmsg
    sysvsem
    sysvshm
    tokenizer
    wddx
    xml
    xmlreader
    xmlwriter
    xsl
    Zend OPcache
    zip
    zlib

    [Zend Modules]
    Zend OPcache
    Monstercat
        51
    Monstercat  
       2017-01-19 23:03:58 +08:00
    第一反应就是不可见字符。。然而 42 楼开始事情变得有趣了起来关注一下
    yangqi
        52
    yangqi  
       2017-01-19 23:17:54 +08:00   5
    via
        53
    via  
       2017-01-19 23:32:22 +08:00
    楼主激动得连标题中的错别字都不顾了
    ioioioioioioi
        54
    ioioioioioioi  
    OP
       2017-01-20 09:01:46 +08:00
    @yangqi 哈,高人,果然是 Opcache 的原因。竟然中招了,花了几乎一天时间就为了解决这个问题。不知道什么时候会修复。
    quericy
        55
    quericy  
       2017-01-20 09:11:35 +08:00
    刚点进这个帖子的时候我是不信的....涨姿势了
    frozenshadow
        56
    frozenshadow  
       2017-01-20 09:33:35 +08:00
    昨天等到现在,终于有答案了
    hoythan
        57
    hoythan  
       2017-01-20 11:31:04 +08:00
    这属于严重 BUG 了吧!
    8355
        58
    8355  
       2017-01-20 13:13:47 +08:00
    @yangqi 6666666666
    bianhua
        59
    bianhua  
       2017-01-20 13:18:49 +08:00
    @ioioioioioioi

    你试试看禁用你的 OPCache ,看看问题是不是消失了。
    ioioioioioioi
        60
    ioioioioioioi  
    OP
       2017-01-20 13:34:56 +08:00
    @bianhua 看 bug 描述,应该就是 opcache 导致的,我用循环生成数组,且键值加 md5 解决了。
    jfcherng
        61
    jfcherng  
       2017-01-20 14:30:57 +08:00
    看 bug report 的 7.1.1 已修了?
    bianhua
        62
    bianhua  
       2017-01-20 16:06:07 +08:00
    @ioioioioioioi

    你 54 楼表示“果然是 Opcache 的原因”,但在 60 楼却表示“ bug 描述,*应该*就是 opcache 导致的”。

    如果有人告诉你是因为天冷机器着凉导致的你会不会也就相信了?
    mingyun
        63
    mingyun  
       2017-01-21 22:17:54 +08:00
    还以为楼主想搞大新闻呢, 涨姿势了
    aksoft
        64
    aksoft  
       2017-02-14 16:14:59 +08:00
    ...不用 op
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     969 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 19:00 PVG 03:00 LAX 12:00 JFK 15:00
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86