BlaBla.cn

PHP: 数组 - Manual

BlaBla.cn
对象 > <字符串
Last updated: Wed, 19 Mar 2008

数组

PHP 中的数组实际上是一个有序图。图是一种把 values 映射到 keys 的类型。此类型在很多方面做了优化,因此可以把它当成真正的数组来使用,或列表(矢量),散列表(是图的一种实现),字典,集合,栈,队列以及更多可能性。因为可以用另一个 PHP 数组作为值,也可以很容易地模拟树。

解释这些结构超出了本手册的范围,但对于每种结构至少会发现一个例子。要得到这些结构的更多信息,建议参考有关此广阔主题的外部著作。

语法

定义 array()

可以用 array() 语言结构来新建一个 array。它接受一定数量用逗号分隔的 key => value 参数对。

array( 
 
key => 
value
     , ...
     )
// 
key 可以是 
integer 或者 
string
// 
value 可以是任何值
     

<?php
$arr 
= array( "foo"  =>  "bar" 12  =>  true );

echo 
$arr [ "foo" ];  // bar
echo  $arr [ 12 ];     // 1
?>

key 可以是 integer 或者 string。如果键名是一个 integer 的标准表达方法,则被解释为整数(例如 "8" 将被解释为 8,而 "08" 将被解释为 "08")。 key 中的浮点数被取整为 integer。PHP 中没有不同的数字下标和关联下标数组,数组的类型只有一种,它可以同时包含整型和字符串型的下标。

值可以是任何值。

<?php
$arr 
= array( "somearray"  => array( =>  5 13  =>  9 "a"  =>  42 ));

echo 
$arr [ "somearray" ][ 6 ];     // 5
echo  $arr [ "somearray" ][ 13 ];    // 9
echo  $arr [ "somearray" ][ "a" ];   // 42
?>

如果对给出的值没有指定键名,则取当前最大的整数索引值,而新的键名将是该值加一。如果指定的键名已经有了值,则该值会被覆盖。

<?php
// This array is the same as ...
array( =>  43 32 56 "b"  =>  12 );

// ...this array
array( =>  43 =>  32 =>  56 "b"  =>  12 );
?>

Warning

自 PHP 4.3.0 起,上述的索引生成方法改变了。如今如果给一个当前最大键名是负值的数组添加一个新值,则新生成的的索引将为零( 0)。以前新生成的索引为当前最大索引加一,和正值的索引相同。

使用 TRUE 作为键名将使 integer 1 成为键名。使用 FALSE 作为键名将使 integer 0 成为键名。使用 NULL 作为键名将等同于使用空字符串。使用空字符串作为键名将新建(或覆盖)一个用空字符串作为键名的值,这和用空的方括号不一样。

不能用数组和对象作为键名。这样做会导致一个警告: Illegal offset type

用方括号的语法新建/修改

可以通过明示地设定值来改变一个现有的数组。

这是通过在方括号内指定键名来给数组赋值实现的。也可以省略键名,在这种情况下给变量名加上一对空的方括号(“ []”)。

$arr[
key] = 
value;
$arr[] = 
value;
// 
key 可以是 
integer 或者 
string
// 
value 可以为任何值。
     
如果 $arr 还不存在,将会新建一个。这也是一种定义数组的替换方法。要改变一个值,只要给它赋一个新值。如果要删除一个键名/值对,要对它用 unset()
<?php
$arr 
= array( =>  1 12  =>  2 );
$arr [] =  56 ;     // This is the same as $arr[13] = 56;
                // at this point of the script
$arr [ "x" ] =  42 // This adds a new element to
                // the array with key "x"
unset( $arr [ 5 ]);  // This removes the element from the array
unset( $arr );     // This deletes the whole array
?>

Note: 如上所述,如果给出方括号但没有指定键名,则取当前最大整数索引值,新的键名将是该值 + 1。如果当前还没有整数索引,则键名将为 0。如果指定的键名已经有值了,该值将被覆盖。

Warning

自 PHP 4.3.0 起,上述的索引生成方法改变了。如今如果给一个当前最大键名是负值的数组添加一个新值,则新生成的的索引将为零( 0)。以前新生成的索引为当前最大索引加一,和正值的索引相同。


注意这里所使用的最大整数键名 不一定当前就在数组中。它只要在上次数组重新生成索引后曾经存在过就行了。以下面的例子来说明:
<?php
// 创建一个简单的数组
$array  = array( 1 2 3 4 5 );
print_r ( $array );

// 现在删除其中的所有单元,但保持数组本身的结构
foreach ( $array  as  $i  =>  $value ) {
    unset(
$array [ $i ]);
}
print_r ( $array );

// 添加一个单元(注意新的键名是 5,而不是你可能以为的 0)
$array [] =  6 ;
print_r ( $array );

// 重新索引:
$array  array_values ( $array );
$array [] =  7 ;
print_r ( $array );
?>

上例将输出:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Array
(
)
Array
(
    [5] => 6
)
Array
(
    [0] => 6
    [1] => 7
)

      

实用函数

有相当多的实用函数作用于数组,参见 数组函数一节。

Note: unset() 函数允许取消一个数组中的键名。要注意数组将不会重建索引。

<?PHP
$a 
= array(  =>  'one' =>  'two' =>  'three'  );
unset( 
$a [ 2 ] );
/* 将产生一个数组,定义为
   $a = array( 1=>'one', 3=>'three');
   而不是
   $a = array( 1 => 'one', 2 => 'three');
*/
$b  array_values ( $a );
// Now $b is array(0 => 'one', 1 =>'three')
?>

foreach 控制结构是专门用于数组的。它提供了一个简单的方法来遍历数组。

数组做什么和不做什么

为什么 $foo[bar] 错了?

应该始终在用字符串表示的数组索引上加上引号。例如用 $foo['bar'] 而不是 $foo[bar]。但是为什么 $foo[bar] 错了呢?可能在老的脚本中见过如下语法:

<?php
$foo
[ bar ] =  'enemy' ;
echo 
$foo [ bar ];
// etc
?>
这样是错的,但可以正常运行。那么为什么错了呢?原因是此代码中有一个未定义的常量(bar)而不是字符串('bar'-注意引号),而 PHP 可能会在以后定义此常量,不幸的是你的代码中有同样的名字。它能运行,是因为 PHP 自动将 裸字符串(没有引号的字符串且不对应于任何已知符号)转换成一个其值为该裸字符串的正常字符串。例如,如果没有常量定义为 bar ,PHP 将把它替代为 'bar' 并使用之。

Note: 这并不意味着 总是给键名加上引号。用不着给键名为 常量变量的加上引号,否则会使 PHP 不能解析它们。

<?php
error_reporting
( E_ALL );
ini_set ( 'display_errors' true );
ini_set ( 'html_errors' false );
// Simple array:
$array  = array( 1 2 );
$count  count ( $array );
for (
$i  0 $i  $count $i ++) {
    echo 
"\nChecking $i: \n" ;
    echo 
"Bad: "  $array [ '$i' ] .  "\n" ;
    echo 
"Good: "  $array [ $i ] .  "\n" ;
    echo 
"Bad: {$array['$i']}\n" ;
    echo 
"Good: {$array[$i]}\n" ;
}
?>
上例的输出类似于:
Checking 0:
Notice: Undefined index:  $i in /path/to/script.php on line 10
Bad:
Good: 1
Notice: Undefined index:  $i in /path/to/script.php on line 12
Bad:
Good: 1

Checking 1:
Notice: Undefined index:  $i in /path/to/script.php on line 10
Bad:
Good: 2
Notice: Undefined index:  $i in /path/to/script.php on line 12
Bad:
Good: 2

     

演示此效应的更多例子:

<?php
// 显示所有错误
error_reporting ( E_ALL );

$arr  = array( 'fruit'  =>  'apple' 'veggie'  =>  'carrot' );

// 正确
print  $arr [ 'fruit' ];   // apple
print  $arr [ 'veggie' ];  // carrot

// 不正确。This works but also throws a PHP error of
// level E_NOTICE because of an undefined constant named fruit
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print  $arr [ fruit ];     // apple

// Let's define a constant to demonstrate what's going on.  We
// will assign value 'veggie' to a constant named fruit.
define ( 'fruit' , 'veggie' );

// Notice the difference now
print  $arr [ 'fruit' ];   // apple
print  $arr [ fruit ];     // carrot

// The following is okay as it's inside a string.  Constants are not
// looked for within strings so no E_NOTICE error here
print  "Hello $arr[fruit]" ;       // Hello apple

// With one exception, braces surrounding arrays within strings
// allows constants to be looked for
print  "Hello {$arr[fruit]}" ;     // Hello carrot
print  "Hello {$arr['fruit']}" ;   // Hello apple

// This will not work, results in a parse error such as:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// This of course applies to using autoglobals in strings as well
print  "Hello $arr['fruit']" ;
print 
"Hello $_GET['foo']" ;

// Concatenation is another option
print  "Hello "  $arr [ 'fruit' ];  // Hello apple
?>

当打开 error_reporting() 来显示 E_NOTICE 级别的错误(例如将其设为 E_ALL )时将看到这些错误。默认情况下 error_reporting 被关闭不显示这些。

和在 语法一节中规定的一样,在方括号(“ [”和“ ]”)之间必须有一个表达式。这意味着可以这样写:

<?php
echo  $arr [ somefunc ( $bar )];
?>
这是一个用函数返回值作为数组索引的例子。PHP 也可以用已知常量,可能之前已经见过 E_*
<?php
$error_descriptions
[ E_ERROR ]   =  "A fatal error has occured" ;
$error_descriptions [ E_WARNING ] =  "PHP issued a warning" ;
$error_descriptions [ E_NOTICE ]  =  "This is just an informal notice" ;
?>
注意 E_ERROR 也是个合法的标识符,就和第一个例子中的 bar 一样。但是上一个例子实际上和如下写法是一样的:
<?php
$error_descriptions
[ 1 ] =  "A fatal error has occured" ;
$error_descriptions [ 2 ] =  "PHP issued a warning" ;
$error_descriptions [ 8 ] =  "This is just an informal notice" ;
?>
因为 E_ERROR 等于 1,等等。

如同在以上例子中解释的那样, $foo[bar] 起作用但其实是错误的。它起作用是因为根据语法的预期, bar 被当成了一个常量表达式。然而,在这个例子中不存在名为 bar 的常量。PHP 就假定指的是字面上的 bar,也就是字符串 "bar",但忘记加引号了。

那么为什么这样做不好?

在未来的某一时刻,PHP 开发小组可能会想新增一个常量或者关键字,或者用户可能希望以后在自己的程序中引入新的常量,那就有麻烦了。例如已经不能这样用 emptydefault 这两个词了,因为他们是 保留字

Note: 重申一次,在双引号字符串中,不给索引加上引号是合法的因此 "$foo[bar]"是合法的。至于为什么参见以上的例子和 字符串中的变量解析中的解释。

转换为数组

对于任何的类型:整型、浮点、字符串、布尔和资源,如果将一个值转换为数组,将得到一个仅有一个元素的数组(其下标为 0),该元素即为此标量的值。

如果将一个对象转换成一个数组,所得到的数组的元素为该对象的属性(成员变量),其键名为成员变量名。

如果将一个 NULL 值转换成数组,将得到一个空数组。

比较

有可能通过 array_diff()数组运算符来比较数组。

例子

PHP 中的数组类型有非常多的用途,因此这里有一些例子展示数组的完整威力。

<?php
// this
$a  = array(  'color'  =>  'red' ,
            
'taste'  =>  'sweet' ,
            
'shape'  =>  'round' ,
            
'name'   =>  'apple' ,
                       
4         // key will be 0
          
);

// is completely equivalent with
$a [ 'color' ] =  'red' ;
$a [ 'taste' ] =  'sweet' ;
$a [ 'shape' ] =  'round' ;
$a [ 'name' ]  =  'apple' ;
$a []        =  4 ;         // key will be 0

$b [] =  'a' ;
$b [] =  'b' ;
$b [] =  'c' ;
// will result in the array array(0 => 'a' , 1 => 'b' , 2 => 'c'),
// or simply array('a', 'b', 'c')
?>

Example#1 使用 array()

<?php
// Array as (property-)map
$map  = array(  'version'     =>  4 ,
              
'OS'          =>  'Linux' ,
              
'lang'        =>  'english' ,
              
'short_tags'  =>  true
            
);

// strictly numerical keys
$array  = array(  7 ,
                
8 ,
                
0 ,
                
156 ,
                -
10
              
);
// this is the same as array(0 => 7, 1 => 8, ...)

$switching  = array(          10 // key = 0
                    
5     =>   6 ,
                    
3     =>   7 ,
                    
'a'   =>   4 ,
                            
11 // key = 6 (maximum of integer-indices was 5)
                    
'8'   =>   2 // key = 8 (integer!)
                    
'02'  =>  77 // key = '02'
                    
0     =>  12   // the value 10 will be overwritten by 12
                  
);
// empty array
$empty  = array();
?>

Example#2 集合

<?php
$colors 
= array( 'red' 'blue' 'green' 'yellow' );

foreach (
$colors  as  $color ) {
    echo 
"Do you like $color?\n" ;
}

?>

上例将输出:

Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?

    

直接改变数组的值在 PHP 5 中可以通过引用传递来做到。之前的版本需要需要采取别的方法:

Example#3 集合

<?php
// PHP 5
foreach ( $colors  as & $color ) {
    
$color  strtoupper ( $color );
}
unset(
$color );  /* 确保下面对 $color 的覆盖不会影响到前一个数组单元 */
// 之前版本的方法
foreach ( $colors  as  $key  =>  $color ) {
    
$colors [ $key ] =  strtoupper ( $color );
}

print_r ( $colors );
?>

上例将输出:

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)

     

本例产生一个下标从 1 开始的数组。

Example#4 下标从 1 开始的数组

<?php
$firstquarter  
= array( =>  'January' 'February' 'March' );
print_r ( $firstquarter );
?>

上例将输出:

Array
(
    [1] => 'January'
    [2] => 'February'
    [3] => 'March'
)
*/
?>

    

Example#5 填充数组

<?php
// fill an array with all items from a directory
$handle  opendir ( '.' );
while (
false  !== ( $file  readdir ( $handle ))) {
    
$files [] =  $file ;
}
closedir ( $handle );
?>

数组是有序的。也可以使用不同的排序函数来改变顺序。更多信息参见 数组函数。可以用 count() 函数来数出数组中元素的个数。

Example#6 数组排序

<?php
sort
( $files );
print_r ( $files );
?>

因为数组中的值可以为任意值,也可是另一个数组。这样可以产生递归或多维数组。

Example#7 递归和多维数组

<?php
$fruits 
= array (  "fruits"   => array (  "a"  =>  "orange" ,
                                       
"b"  =>  "banana" ,
                                       
"c"  =>  "apple"
                                     
),
                  
"numbers"  => array (  1 ,
                                       
2 ,
                                       
3 ,
                                       
4 ,
                                       
5 ,
                                       
6
                                     
),
                  
"holes"    => array (       "first" ,
                                       
=>  "second" ,
                                            
"third"
                                     
)
                );

// Some examples to address values in the array above
echo  $fruits [ "holes" ][ 5 ];     // prints "second"
echo  $fruits [ "fruits" ][ "a" ];  // prints "orange"
unset( $fruits [ "holes" ][ 0 ]);   // remove "first"

// Create a new multi-dimensional array
$juices [ "apple" ][ "green" ] =  "good" ;
?>

需要注意数组的赋值总是会涉及到值的拷贝。这还意味着在 current() 以及类似函数中使用的内部数组指针会被重置。需要在复制数组时用引用符号(&)。

<?php
$arr1 
= array( 2 3 );
$arr2  $arr1 ;
$arr2 [] =  4 // $arr2 is changed,
             // $arr1 is still array(2,3)

$arr3  = & $arr1 ;
$arr3 [] =  4 // now $arr1 and $arr3 are the same
?>



对象 > <字符串
Last updated: Wed, 19 Mar 2008
 

 
BlaBla.cn

© 2005-2008 BlaBla.cn 版权所有