PHP之数组

PHP之数组_第1张图片

PHP之数组

数组

PHP中的数组是一个有序映射(一种把values关联到keys的类型),或者称之为有序字典,Objective-c的数组的下标只能是数字,且元素必须是对象类型,而字典是一个映射,但字典是无序的且其键名不能是数字.这就很有意思.
数组一般作为容器类变量,用来承载多个变量或常量.
可以把数组分为三种类型:

  • 数值数组|索引数组(键名为数值类型的数组)
  • 关联数组(带有指定的键的数组,每个键关联一个值)
  • 多维数组(包含一个或多个数组的数组)
    注:PHP 实际并不区分索引数组和关联数组

数组的创建

空数组

$arr = array();

数值数组

用逗号,来分隔每个元素,用=> 来连接key和value,最后一个元素之后的逗号可以省略,键(key)可以是数值或者string,值(value)可以是任意类型的值

$arr = array('item','user',2,false,null);

关联数组,指定键名

$arr = array('key1'=>'value1',2=>false,'3'=>null);

二维数组

二维索引+索引

echo '

二维索引+索引

'; $arr = array( array(1,'zhangsan' ), array(2,'lisi','xxx','222333' ) ); print_r($arr);

二维索引+关联

echo '

二维索引+关联

'; $arr = array( array('id'=>1, 'username'=>'zhangsan' ), array('id'=>2, 'username'=>'lisi' ) ); print_r($arr);

二维关联+索引

echo '

二维关联+索引

'; $arr = array( 'users' =>array('king','queen','李四'), 'ages'=>array(13,24,22) ); print_r($arr);

二维关联+关联

echo '

二维关联+关联

'; $arr = array( 'user1' =>array( 'name'=>'king', 'age'=>22, 'id'=>'1352222' ), 'user2'=>array( 'name'=>'allen', 'age'=>23, 'id'=>'145222' ) ); print_r($arr);

新的定义方式[] PHP5.4起

用[]来代替array()
$arr = ['a','b','foo'=>'bar','name'=>'xiaosi'];
[]可以动态的修改数组
$arr[] = 'user';
$arr[] = 'sex';
$arr[] = 'age';
$arr['class']=32;
print_r($arr);
/*
Array
(
    [0] => user
    [1] => sex
    [2] => age
    [class] => 32
)
*/
[],{}访问数组

通过array[key]来访问,{}和[]相同

$arr = ['name'=>'xix','age'=>23,'sex'=>true];
var_dump($arr['name']);
var_dump($arr{'name'});

range(),compact()快速创建

range()创建索引数组

1.快速创建数组 range(参数1,参数2,参数3)是下标连续的,参数1是起始位置,参数2是结束位置,参数3是步长(可省略)

$arr= range(1, 10);
print_r($arr);

2.手动指定步长的数组,步长的正负并不影响,因为参数1和参数2的大小决定了步长的符号

$arr=range(2, -4,2);
print_r($arr);

3.参数1和参数2会自动转为整形,比如false=0,true=1,'2'=2,若两个都可以转化为ASCII码,则转换为ASCII,比如('2','a')时,=>(2,0),而('>','B')则按照ASCII进行

$arr=range('>', 'B');
print_r($arr);

4.range()其实同for循环动态创建索引数组,chr()将ASCII转成对应字符

for ($i=97; $i<=122 ; $i++){
    $arr1[] = chr($i);
}
print_r($arr1);
compact()创建关联数组

1.compact()

$username ='allen';
$age=24;
$email='[email protected]';
$arr = array(
    'username' => $username , 
    'age'=>$age,
    'email'=>$email
);
print_r($arr);

echo "方式2:[]动态创建数组

"; $userInfo['username']=$username; $userInfo['age']=$age; $userInfo['email']=$email; print_r($userInfo);

2.compact()创建,通过compact()创建数组的时候,只能写已经存在的变量的名称,不需要加$,名称就是对应的键名,然后会寻找该名称的变量名,如果变量名不存在,是没有对应的键值对的

$username ='allen';
$age=24;
$email='[email protected]';
$a=12;
$userInfo1=compact('username','age','email','a','b','c');
//不存在 'b','c';
print_r($userInfo1);

define,const定义常量数组

1.定义常量数组,const在php5.6之后可以定义常量

const ARR1 = array('优秀','良好','及格','不及格');
print_r(ARR1);

const ARR2 = [
'timeInterval'=>3.0,
'content-type'=>'text/html',
'content-length'=>2457,
'accept-lanuage'=>'en'
];
print_r(ARR2);

2.通过define定义常量数组

define('TEST1', array('a','b','c'));
print_r(TEST1);

define('TEST2', ['2',true,344]);
print_r(TEST2);

define('CUSTOM_UPLOAD_ERRORS', [
    'ext_error'=>"上传文件扩展名不符合规格",
    'maxsize_error'=>"上传文件大小不符合规格",
    'time_error'=>"上传超时"
    ]
);
print_r(CUSTOM_UPLOAD_ERRORS);
echo "
"; echo CUSTOM_UPLOAD_ERRORS['ext_error'];

数组的使用

键转换规则

当键不是integer或string类型的数据,会发生强制转换(优先转换为整形,其次转为字符串类型):

  • 包含合法整型值的字符串会被转换为整形, 比如'8'=>8,'08'不是一个合法的整型值,不会发生强制转换.
  • 浮点数->整形,小数部分直接舍去,不是四舍五入
  • 布尔类型->整形 true->1,false->0
  • null转换为空字符串,null->''
  • 数组和对象不能当做键名

测试键名

$arrays = array(
    3 =>a ,
    'username'=>'zhansan',
    5.6 =>"浮点数转为整数", //5
    5=>'f',//覆盖上一个
    true=>'true=1',
    false=>'false=0',
    null=>'\'\''  //null = ''
);
var_dump($arrays);
/*
array(6) {
  [3]=>
  string(1) "a"
  ["username"]=>
  string(7) "zhansan"
  [5]=>
  string(1) "f"
  [1]=>
  string(6) "true=1"
  [0]=>
  string(7) "false=0"
  [""]=>
  string(2) "''"
}
*/

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

  • 键名重复,后定义的会覆盖前面的值.
  • 新添加的元素没有指定键名,它的下标为已有下标最大值加一(已有下标不全为负数)
  • 如果已有下标都为负数,新添加元素的下标从0开始.

不全为负数

$arr = array(
    'a',
    'b',
    18 => 'd',
    'c',
    'g' 
);
var_dump($arr);
/*
array(5) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [18]=>
  string(1) "d"
  [19]=>
  string(1) "c"
  [20]=>
  string(1) "g"
}
*/

全为负数从0开始

$arr = array(
    -11=>'a',
    -12=>'b',
    -3=>'c',
    'g' 
);
var_dump($arr);

/*
array(4) {
  [-11]=>
  string(1) "a"
  [-12]=>
  string(1) "b"
  [-3]=>
  string(1) "c"
  [0]=>
  string(1) "g"
}
*/

数组的解引用

自 PHP 5.4 起可以用直接对函数或方法调用的结果进行数组解引用,之前只能通过一个临时变量。
自 PHP 5.5 起可以直接对一个数组原型进行数组解引用.

function getArray() {
    return array(1, 2, 3);
}

// on PHP 5.4
$secondElement = getArray()[1];

// previously
$tmp = getArray();
$secondElement = $tmp[1];

// or 
list(, $secondElement) = getArray();

数组的增删改查

  • 查询: $array[key],$array{key}
  • 增: $array[key] = $value,key不存在
  • 改: $array[key] = $newValue,key存在,覆盖
  • 删: unset($array[key]);
$arr = array(5 => 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

array_values($array) 重建数组索引

对于索引数组,当我们删除其中的一个元素,但是还想其索引是连续的,可以使用array_values();对于关联数组,原有的key会被覆盖为数值

$a = array(1 => 'one', 2 => 'two', 3 => 'three','name'=>'zhangsan',"age"=> 12);

//删除一个元素
unset($a[2]);

//重建索引
$b = array_values($a);

print_r($b);
/*
Array
(
    [0] => one
    [1] => three
    [2] => zhangsan
    [3] => 12
)
*/

数组的个数count()

count — 计算数组中的单元数目,或对象中的属性个数,注意:非数组和对象类型的变量

$arr = range('a','z');
echo count($arr),'
'; $var = 123; //1 echo count($var),'
'; $var = null; //0 echo count($var),'
'; $var = true; //1 echo count($var),'
'; $var = false; //1 echo count($var),'
';

数组的遍历

1.数组的遍历 普通的for循环 (对于下标不连续的不适用)
$arr = range('a','z');
for ($i=0; $i <25; $i++) { 
    echo $arr[$i],'
'; }
2.foreach遍历数组,对象
//方式1:
foreach ($variable as $value) {
    # code...
}
//方式2:
foreach ($variable as $key => $value) {
    # code...
}
$arr = [
5=>'a',
12=>'b',
-123=>'c',
'age'=>20,
34=>'d',
'userName'=>'lisi',
];

foreach ($arr as $value) {
    echo $value,'
'; } foreach ($arr as $key => $value) { echo $key,' => ',$value,'
'; } echo $key,' _____ ',$value,'
'; unset($key); unset($value);

注意:最后变量$key和$value的是有值的,没有被销毁.
未销毁引用带来的错误

$arr = ['a','b','c','d'];
foreach ($arr as $key => &$value) {
    $value = $value.'_'.$value;
    echo $value.'
'; } print_r($arr); var_dump($value); echo "
"; foreach ($arr as $key => $value) { echo $value.'
'; print_r($arr); } echo "
"; print_r($arr);
PHP之数组_第2张图片
运行结果

foreach 通过值遍历时,操作的值是数组的副本 (有待考证~!!!!!)
猜想:如果是副本那么输出结果应该是数组的全部元素,但实际是最后一个元素没有输出,但不是副本吧,输出的结果也不符合,只能解释为 foreach 依赖内部数组指针,在循环中修改其值将可能导致意外的行为。

$arr = [1,'www','22',false];

foreach ($arr as $value) {
    echo $value,'
'; unset($arr[0]); } var_dump($arr); /* 1 www 22 array(3) { [1]=> string(3) "www" [2]=> string(2) "22" [3]=> bool(false) } */

在循环中改变数组 用&表示通过引用遍历,有更好的迭代性

$arr = [1,'www'];

//输出两个元素
foreach ($arr as $value) {
    echo $value,'
'; $arr[1] = 'b'; } //打印结果 //1 //www print_r($arr); $arr = [1,'www']; //输出三个元素 foreach ($arr as &$value) { echo $value,'
'; $arr[2] = 'b'; } //打印结果 //1 //www //b print_r($arr);

二维数组的遍历

$users = [
      ['id'=>12223,'username'=>'queen','age'=>24],
      ['id'=>23333,'username'=>'allen','age'=>34],
      ['id'=>32222,'username'=>'crush','age'=>54],
      ['id'=>40001,'username'=>'queen3','age'=>52],
      ['id'=>00001,'username'=>'queen4','age'=>23],
      ['id'=>33331,'username'=>'queen5','age'=>98]
    ];

foreach ($users as $user) {
    echo '编号: ',$user['id'],'
'; echo '姓名:',$user['username'],'
'; echo '年龄:',$user['age'],'
'; }

PHP7中的foreach使用 :endforeach;

$arr = ['a','b','c'];
foreach ($arr as $key => $value):
    echo $key,'----',$value,'
'; endforeach;

foreach不改变内部数组的(current())指针

$arr = ['a','b',3,false];

foreach ($arr as $key => $value) {
    var_dump(current($arr));
}
/*
string(1) "a"
string(1) "a"
string(1) "a"
string(1) "a"
*/

数组的类型转换

对于任意 integer,float,string,boolean 和 resource 类型,如果将一个值转换为数组,将得到一个仅有一个元素的数组,其下标为 0,该元素即为此标量的值。换句话说,(array)$scalarValue 与 array($scalarValue) 完全一样。

临时转换

$var = 123;
$res = (array)$var;
var_dump($res);
var_dump($var);

echo("
"); echo("
"); $var = 123.2222; $res = (array)$var; var_dump($res); var_dump($var); $var = true; $res = (array)$var; var_dump($res); var_dump($var); echo("
"); echo("
"); echo "

null是转换成空数组

"; $var = null; $res = (array)$var; var_dump($res); var_dump($var); echo "
";

永久转换settype

$var = 234;
settype($var, 'array');
var_dump($var);

如果一个 object 类型转换为 array,则结果为一个数组,其单元为该对象的属性。键名将为成员变量名,不过有几点例外:整数属性不可访问;私有变量前会加上类名作前缀;保护变量前会加上一个 '*' 做前缀。这些前缀的前后都各有一个 NULL 字符。这会导致一些不可预知的行为:

待添加

数组指针函数

1.key($array)得到当前指针所在的位置的键名,如果不存在返回null,current($array)得到当前指针所在位置的键值,如果不存在返回false

$users = ['name'=>'lisi','age'=>22,'class'=>'三年二班','score'=>127];

echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; /* */

2.next($array):将数组指针向下移动一位,并且返回当前指针所在位置的键值,如果没有,返回false

$users = ['name'=>'lisi','age'=>22,'class'=>'三年二班','score'=>127];

echo next($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; echo next($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; echo next($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; var_dump(next($users)); echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; /* 22 当前指针位置的键名:age 当前指针位置的键值:22 三年二班 当前指针位置的键名:class 当前指针位置的键值:三年二班 127 当前指针位置的键名:score 当前指针位置的键值:127 bool(false) 当前指针位置的键名: 当前指针位置的键值: */

3.prev($array):将数组指针向上移动一位,并且返回当前指针所在位置的键值,如果没有,返回false

$users = ['name'=>'lisi','age'=>22,'class'=>'三年二班','score'=>127];
echo end($users),'
'; echo prev($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; echo prev($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; echo prev($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; echo prev($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; /* 127 三年二班 当前指针位置的键名:class 当前指针位置的键值:三年二班 22 当前指针位置的键名:age 当前指针位置的键值:22 lisi 当前指针位置的键名:name 当前指针位置的键值:lisi 当前指针位置的键名: 当前指针位置的键值: */

4.reset($array):将数组指针移动到数组开始,并且返回当前指针位置所在位置的键值,若果没有,返回false

$users = ['name'=>'lisi','age'=>22,'class'=>'三年二班','score'=>127];
echo reset($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; /* lisi 当前指针位置的键名:name 当前指针位置的键值:lisi */

5.end($array):将数组指针移动到数组末尾,并且返回当前指针位置所在位置的键值,若果没有,返回false.

$users = ['name'=>'lisi','age'=>22,'class'=>'三年二班','score'=>127];
echo end($users),'
'; echo '当前指针位置的键名:',key($users),'
'; echo '当前指针位置的键值:',current($users),'
'; /* 127 当前指针位置的键名:score 当前指针位置的键值:127 */

6.通过指针函数遍历数组:

$array = ['c',null,null => false,0,''=>'naxx','22332',222];
print_r($array);

//不对的,有的值正好是false,0,null
while (current($array)) {   
    echo '当前指针位置的键名:',key($array),'
'; echo '当前指针位置的键值:',current($array),'
'; next($array); } /* Array ( [0] => c [1] => [] => naxx [2] => 0 [3] => 22332 [4] => 222 ) 当前指针位置的键名:0 当前指针位置的键值:c */ reset($array); echo '
'; while (!is_null(key($array))) { echo '当前指针位置的键名:',key($array),'
'; echo '当前指针位置的键值:',current($array),'
'; echo "
"; next($array); } /* 当前指针位置的键名:0 当前指针位置的键值:c 当前指针位置的键名:1 当前指针位置的键值: 当前指针位置的键名: 当前指针位置的键值:naxx 当前指针位置的键名:2 当前指针位置的键值:0 当前指针位置的键名:3 当前指针位置的键值:22332 当前指针位置的键名:4 当前指针位置的键值:222 */

7.end() 取得文件扩展名

$filename = '1229293.2xxx.php';
$arrs = explode('.', $filename);//按'.'分割成数组
print_r($arrs);
$extesion = end($arrs);//通过指针获取数组末尾的元素
echo $extesion; //php

数组运算符

1.合并数组 +,如果数组键名(比如下标相同的数组元素)相同,则只会使用左边的数组的键值,而不是覆盖!

$arr1 = ['a','b','c'];
$arr2 = ['a',11,true,'d'];

$newArr = $arr1 + $arr2;
print_r($newArr);

2.比较数组的键名和键值是否相同 == 相同返回true,否则返回false !=相反

$arr1 = ['id'=>1,'name'=>'zhangsan','age'=>23];
$arr2 = ['id'=>1,'age'=>23,'name'=>'zhangsan'];

$arr3 = ['id'=>2,'age'=>19,'name'=>'lisi'];
$arr4 = ['id'=>1,'name'=>'zhangsan','age'=>23];

var_dump($arr1 == $arr2); //true
var_dump($arr1 == $arr3); //false
var_dump($arr1 == $arr4); //true

var_dump($arr1 != $arr3); //true
var_dump($arr1 != $arr4); //false

3.比较数组的键名和键值是否相同,同时顺序也要相同,即全等于 === 相同返回true,否则返回false !== 相反

var_dump($arr1 === $arr2); //false
var_dump($arr1 === $arr4); //true

var_dump($arr1 !== $arr2); //true
var_dump($arr1 !== $arr4); //false

each()和list()

1.each()返回数组中当前的键/值对,并将数组指针向前移动一步,返回的是一个包含四个元素的数组,键名为0,1,key,value,0和key对应的是当前指针对应的键名,1和value对应的是当前指针对应的键值.如果当前指针不在数组范围中,返回false

$foo = array('name'=>"bob", "fred",233);

$bar = each($foo);
print_r($bar);

echo '当前指针位置的键名:',key($foo),'
'; echo '当前指针位置的键值:',current($foo),'
'; $bar = each($foo); echo '当前指针位置的键名:',key($foo),'
'; echo '当前指针位置的键值:',current($foo),'
'; $bar = each($foo); echo '当前指针位置的键名:',key($foo),'
'; echo '当前指针位置的键值:',current($foo),'
'; var_dump(each($foo)); /* Array ( [1] => bob [value] => bob [0] => name [key] => name ) 当前指针位置的键名:0 当前指针位置的键值:fred 当前指针位置的键名:1 当前指针位置的键值:233 当前指针位置的键名: 当前指针位置的键值: bool(false) */

2.list()把数组中的值赋给一组变量,感觉类似于ES6的解构赋值

$info = array('coffee', 'brown', 'caffeine');

// 列出所有变量
list($drink, $color, $power) = $info;
echo "$drink is $color and $power makes it special.\n";

// 列出他们的其中一个
list($drink, , $power) = $info;
echo "$drink has $power.\n";

// 或者让我们跳到仅第三个
list(,,$power) = $info;
echo "I need $power!\n";

// list() 不能对字符串起作用
list($bar) = "abcde";
var_dump($bar); // NULL
/*
coffee is brown and caffeine makes it special.
coffee has caffeine.
I need caffeine!
NULL
*/

2.1 list() 嵌套元素,也是可以获取值的

list($a,list($b,$c)) = array('apple',['hello',23]);
var_dump($a,$b,$c);
/*
string(5) "apple"
string(5) "hello"
int(23)
*/

2.2 list() 使用数组索引 php5和php7的顺序不一样,php7从左到右,php5相反

list($arr[0],list($arr[1],$arr[2])) = array('apple',['hello',23]);
var_dump($arr);

2.3 list() []空数组

list($a) = array();
var_dump($a); //null

list(,,$a) = array();
var_dump($a);//null

2.4 list()循环[] 关联数组不可用,使用索引数组(下标连续且从0开始),内部是按下标一一进行赋值

$arr = [
['name'=>"adson",'age'=>22,'sex'=>true],
['name'=>"adson1",'age'=>23,'sex'=>true],
['name'=>"adson3",'age'=>24,'sex'=>true],
['name'=>"adson4",'age'=>25,'sex'=>true]
];
foreach ($arr as list($name,$age,$sex)) {
    echo $name,'---',$age,'---',$sex,'
'; } /*输出: ------ ------ ------ ------ */ $arrs = [ ['aleen',23,true], ['alex',24,false], ['lisa',21,true] ]; foreach ($arrs as list($name,$age,$sex)) { echo $name,'---',$age,'---',$sex,'
'; } /* aleen---23---1 alex---24--- lisa---21---1 */

2.5 each() list()遍历数组

$fruit = array(
    'a' => 'apple', 
    'b' => 'banana', 
    'c' => 'cranberry'
    );

reset($fruit);
while (list($key, $val) = each($fruit)) {
    echo "$key => $val\n";
}
/*
a => apple
b => banana
c => cranberry
*/

2.6 caution:将一个数组赋值给另一个数组时会重置原来的数组指针,导致死循环

// reset($fruit);
// while (list($key, $val) = each($fruit)) {
//     echo "$key => $val\n";
//     //重新赋值
//     $fruit = ['x'];
// }

你可能感兴趣的:(PHP之数组)