PHP 的数组定义了键名,就不能使用索引了吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
koodai
V2EX    PHP

PHP 的数组定义了键名,就不能使用索引了吗?

  •  
  •   koodai 2017-01-14 15:08:54 +08:00 5268 次点击
    这是一个创建于 3208 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景:

    我的 PHP 数组定义了键名,情况如下:

    array( 'filed1'=>array(1,2,3), 'filed2'=>array(a,b,c), 'filed3'=>array(x,y,z), ); 

    预期:

    我根据这个数组要生成 sql :

    INSERT INTO `contents` (`fild1`,`filed2`,`filed3`) VALUES ((1,a,x) ,(2,b,y) ,(3,c,z) ) ; 

    问题:

     $value_str='('; for($i=0;$i<count( $data[ 0 ] );$i++) // 记录数 { for($j=0;$j<count($data);$j++) // 字段数量 { $value_str.="'".$data[$i][$j]."',"; } } $value_str.=')'; $filed_str='(`'.implode("`,`",array_keys($data)).'`)'; 

    就在记录数哪里,使用了索引值,$data[0]这样的方式,结果,就出问题了!数组越界 Undefined offset: 0

    SO:

    定义了键名的数组,就不能用索引来取值了吗?

    23 条回复    2017-01-16 15:11:32 +08:00
    koodai
        1
    koodai  
    OP
       2017-01-14 15:17:44 +08:00
    有没有大神顺手回复一下问题的 ^_^
    koodai
        2
    koodai  
    OP
       2017-01-14 15:20:56 +08:00
    现有方案:
    ```
    $data_array_keys = array_keys($data);
    $value_str='(';
    for($i=0;$i<count( $data[ $data_array_keys[0] ] );$i++) // 记录数
    {
    for($j=0;$j<count($data);$j++) // 字段数量
    {
    $value_str.="'".$data[$i][$j]."',";
    }
    }
    $value_str.=')';
    $filed_str='(`'.implode("`,`", $data_array_keys ).'`)';
    ```
    torbrowserbridge
        3
    torbrowserbridge  
       2017-01-14 15:23:24 +08:00
    array_values
    langmoe
        4
    langmoe  
       2017-01-14 15:24:17 +08:00
    for 改成 foreach ?
    koodai
        5
    koodai  
    OP
       2017-01-14 15:25:46 +08:00
    我回复的太着急了,$value_str.="'".$data[$i][$j]."',"; 这里也有问题,不过简单做下标的调换就可以 。$j 这里直接无法使用,需要根据 key 的值来取,
    koodai
        6
    koodai  
    OP
       2017-01-14 15:27:40 +08:00
    @langmoe 还有个计数的功能。
    如果使用 foreach ,可以先循环字段名,然后循环字段的值。

    就问题还存在,用了键名,就无法用下标了吗?以前都没注意过(⊙⊙)b
        7
    koodai  
    OP
       2017-01-14 15:29:01 +08:00
    @torbrowserbridge 把键名直接去掉,新的数组只含键值,再用下标,可以!好方法
    AbrahamGreyson
        8
    AbrahamGreyson  
       2017-01-14 15:29:55 +08:00 via iPhone
    代码风格倒腾明白了或许能帮你看看,这大 tab 在手机上都缩进到地平线了。
    koodai
        9
    koodai  
    OP
       2017-01-14 15:36:21 +08:00
    @AbrahamGreyson 不谈这个代码,简单一个问题,就问:对于有键名的数组,就不可以用索引的方式取值了?
    guoguoer
        10
    guoguoer  
       2017-01-14 15:46:10 +08:00 via iPhone
    @koodai 我的理解, php 里没有把数组和字典没分开。键值对的字典,需要用键去访问。在 php 里如果刚好键是从 0 开始的数字,就是数组了。

    所以用 foreach 更简单一致。
    mrgeneral
        11
    mrgeneral  
       2017-01-14 16:23:12 +08:00
    关联数组和索引数组的区别,关联数组不支持索引访问
    AbrahamGreyson
        12
    AbrahamGreyson  
       2017-01-14 17:02:08 +08:00 via iPhone
    @koodai 是的
    msg7086
        13
    msg7086  
       2017-01-14 18:01:00 +08:00 via Android
    你数组里哪有 0 => ?
    0 和 field1 都是索引,或者叫键。
    [5] 就是 [0 => 5],所以你才能用 0 键去访问啊。
    msg7086
        14
    msg7086  
       2017-01-14 18:02:56 +08:00 via Android
    /div>
    你标题里说的:索引和键名,在 PHP 里是一个东西。
    jswh
        15
    jswh  
       2017-01-14 18:21:27 +08:00
    @koodai 是的。
    还有个坑,索引比如 0 和数字字符串键名比如‘ 0 ’ 是一个东西,不做区分
    jswh
        16
    jswh  
       2017-01-14 18:23:32 +08:00
    @jswh 虽然实现上有些不一样,但理解上,你就是没有键的数组理解成所有键都是'0','1', '2', '3'就好了
    iyaozhen
        17
    iyaozhen  
       2017-01-14 20:52:31 +08:00 via Android
    实际上你这样 data 是一个 map 了,不能用下标索引了。而且楼主你这实现有点挫。且不论拼 SQL 这件事。其实你 filed 应该是确定的,没必要做 key 。 data 存成[[1,a,x] ,[2,b,y] ,[3,c,z]]不是更好?
    CoderRunner
        18
    CoderRunner  
       2017-01-14 21:43:41 +08:00
    文档里已经解释的很详细了
    http://php.net/manual/zh/language.types.array.php
    quericy
        19
    quericy  
       2017-01-14 21:50:45 +08:00
    楼主的实现方式就不吐槽了.
    但是单论有索引的数组,还是有些方法可以取第几个元素的
    比如 array_slice , length 置为 1, 偏移量 offset 作为序号
    koodai
        20
    koodai  
    OP
       2017-01-15 00:41:12 +08:00
    @msg7086 感谢,是自己学艺不精,以前真没认真考虑过;
    @jswh 握手握手,感谢,可能跟其他语言的使用习惯有点混淆了。
    @iyaozhen 只是一个 BAE 上的 php-worker 单文件抓取工具,场景单一相对来说不想复杂化,全手工实现一个小工具而已,可能在其他环境下这做法确实很挫;另外, filed 这里确实是固定的,但是正则匹配出来的东西,就是我给出的样子,没有再做加工;

    @quericy 感觉你的方法更加复杂了,,,对于一个百十行左右完整抓取、保存的小工具来说,我喜欢简单粗暴。 如果不在乎繁复,循环解千愁,也不是一定要取索引,只是偶然遇到这个问题,感觉有点奇葩。
    koodai
        21
    koodai  
    OP
       2017-01-15 00:42:03 +08:00
    @quericy thanks !
    -----------------------
    此外 key 会有如下的强制转换:

    包含有合法整型值的字符串会被转换为整型。例如键名 "8" 实际会被储存为 8 。但是 "08" 则不会强制转换,因为其不是一个合法的十进制数值。
    浮点数也会被转换为整型,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8 。
    布尔值也会被转换成整型。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0 。
    Null 会被转换为空字符串,即键名 null 实际会被储存为 ""。
    数组和对象不能被用为键名。坚持这么做会导致警告: Illegal offset type 。
    如果在数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了。

    Example #2 类型强制与覆盖示例

    <?php
    $array = array(
    1 => "a",
    "1" => "b",
    1.5 => "c",
    true => "d",
    );
    var_dump($array);
    ?>
    以上例程会输出:

    array(1) {
    [1]=>
    string(1) "d"
    }
    上例中所有的键名都被强制转换为 1 ,则每一个新单元都会覆盖前一个的值,最后剩下的只有一个 "d"。

    PHP 数组可以同时含有 integer 和 string 类型的键名,因为 PHP 实际并不区分索引数组和关联数组。
    -----------------------------
    这些定义,感觉很神奇! ^_^
    klom303
        22
    klom303  
       2017-01-16 10:25:27 +08:00
    其实要处理数组,不一定要套 for 循环,有一些很好用的数组函数啊,比如:
    ```
    $data = array(
    'filed1' => array(1, 2, 3),
    'filed2' => array('a', 'b', 'c'),
    'filed3' => array('x', 'y', 'z'),
    );

    $result = array_map(function ($filed1, $filed2, $filed3) {
    return "('{$filed1}','{$filed2}','{$filed3}')";
    }, $data['filed1'], $data['filed2'], $data['filed3']);

    echo implode(',',$result);
    ```
    koodai
        23
    koodai  
    OP
       2017-01-16 15:11:32 +08:00
    @klom303 十万个赞!我以前对 array_map 有用过,但是没有这么用过。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3662 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 10:33 PVG 18:33 LAX 03:33 JFK 06:33
    Do have faith in what you're doing.
    ubao msn 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