# 基础

## 构建数组

```php
 $items = array(); 

 //也可以不做初始化直接写
 $items[0]= 'abc123' ; 
 $items[]='abc123' ;
 $items['name']='andy';

//
$item = ['a', 'b', 'c'];
```

## 数组式访问接口

**提供像访问数组一样访问对象的能力的接口。**

[ArrayAccess（数组式访问）接口](http://php.net/manual/zh/class.arrayaccess.php)

```php
ArrayAccess {
/* 方法 */
abstract public boolean offsetExists ( mixed $offset )
abstract public mixed offsetGet ( mixed $offset )
abstract public void offsetSet ( mixed $offset , mixed $value )
abstract public void offsetUnset ( mixed $offset )
}
```

* ArrayAccess::offsetExists — 检查一个偏移位置是否存在
* ArrayAccess::offsetGet — 获取一个偏移位置的值
* ArrayAccess::offsetSet — 设置一个偏移位置的值
* ArrayAccess::offsetUnset — 复位一个偏移位置的值

**示例:**

```php
class obj implements ArrayAccess {
    private $container = array();
    public function __construct() {
        $this->container = array(
             'one' => 1,
             'two' => 2,
             'three' => 3,
        );
    }

    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }
    function offsetExists($offset) {
        return isset($this->container[$offset]);
    }

    function offsetUnset($offset) {
        unset($this->container[$offset]);
    }

    function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : '';
    }
}

$obj = new obj();
$obj[] = 'Append 1';
$obj[] = 'Append 2';
$obj[] = 'Append 3';
print_r($obj);
die;
var_dump(isset($obj['two']));
var_dump($obj['two']);
unset($obj['two']);
var_dump(isset($obj['two']));
```

思考：

* 上面的四个接口方法分别有什么作用？在什么情况下会被调用？
* 如果不继承ArrayAccess接口，只是实现这四个方法还可以实现数组是访问的功能么？

## 数组key和value的限制条件

什么类型值可以当做数组的key，数组的value值又可以存什么类型？

* key 可以是 integer 或者 string。
* value 可以是任意类型。

**key 会有如下的强制转换:**

* **包含有合法整型值的字符串会被转换为整型**
* 浮点数和布尔值也会被转换为整型
* **键名 null 实际会被储存为 ""**
* 数组和对象不能被用为键名
* 相同键名，之前会被覆盖

示例：

```php
$array = array(
    1 => "a",
    "1" => "b",
    1.5 => "c",
    true => "d",
    false => 'e',
    null => 'f',
    '2.5' => 'g',
    3.5 => 'h',
);
var_dump($array);
```

结果：

```
array (size=5)
  1 => string 'd' (length=1)
  0 => string 'e' (length=1)
  '' => string 'f' (length=1)
  '2.5' => string 'g' (length=1)
  3 => string 'h' (length=1)
```

示例：

```php
$array = array(
    "foot" => "bar",
    "bar" => "foot",
    100 => -100,
    -100 => 100,
);
var_dump($array);
```

结果：

```
array (size=4)
  'foot' => string 'bar' (length=3)
  'bar' => string 'foot' (length=4)
  100 => int -100
  -100 => int 100
```

## 数组的访问

获取数组元素的值有哪些方法？

1. 方括号，数组单元可以通过 `array[key]` 语法来访问。
2. 花括号也可以，例如 `$array[42]`和`$array{42}` 效果相同。
3. 方括号可以包括“表达式”，例如：`$arr[somefunc($bar)];`
4. 自 PHP 5.4 起可以用数组间接引用函数或方法调用的结果。

示例

4.数组的间接引用

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

// 常规做法
$tmp = getArray();
$secondElement = $tmp[1];

// on PHP 5.4 
$secondElement = getArray()[1];
//或者
list(,$secondElement) = getArray();
```

## 数组元素的删除unset

unset() 函数允许删除数组中的某个键。

```php
$array = array(1, 2, 3, 4, 5, 6);
foreach ($array as $key => $value) {
    unset($array[$key]);
}
$array[] = 6;
print_r($array);
```

结果：

```
Array ( [6] => 6 )
```

> 注意：数组unset后，不会重建索引。

## PHP数组类型与其他类型的转换

在PHP中，存在8种变量类型，分为三类

* 标量类型： boolean、integer、float(double)、string
* 复合类型： array、object
* 特殊类型： resource、NULL

**思考：**

**如何将一个int、float、string、boolean 类型转换为数组？**

* int，float，string，boolean 和 resource 类型 (array)$scalarValue 等同 array($scalarValue) &#x20;
* object 转换为 array，结果为一个数组，其单元为该对象的属性，键名将为成员变量名
* 将 NULL 转换为 array 会得到一个空的数组

**var\_dump((array)false)和var\_dump((array)null)的输出结果是？**

```php
var_dump((array)false);
var_dump((array)null);
```

结果:

```
array(1) {
    [0] =>
    bool(false)
}
array(0) {
}
```

**示例:**

对象转数组

```php
//对象转为数组
class User{
    public $name = 'andy';
    public $age = 53;
    private $phone = '158xxxxxxxx';
    private $email = 'xx@gmail.com';
    protected $location = 'China';
}

var_dump((array) new User());
```

结果:

```php
array(5) {
  'name' =>
  string(4) "andy"
  'age' =>
  int(53)
  '\0User\0phone' =>
  string(11) "158xxxxxxxx"
  '\0User\0email' =>
  string(12) "xx@gmail.com"
  '\0*\0location' =>
  string(5) "China"
}
```

## 数组的遍历

1. for ：语句循环遍历&#x20;
2. foreach ：循环遍历&#x20;
3. while： (list($key, $val) = each($fruit))&#x20;
4. array\_walk、array\_map ：回调遍历
5. current和next ：内部指针遍历

**array\_walk与array\_map有什么不同**

* array\_walk 引用的方式对数组进行遍历，返回值不重要
* array\_map 为了改变数组的数据，支持多个数组数据合并，目的是返回新的数组
* walk和map的回调函数位置也不一样

**foreach 和 for 性能对比**

一般php推荐使用foreach来遍历数组。

**foreach遍历中的顺序**

加入元素的顺序

```php
$a = array();
$a[2] = 3;
$a[1] = 2;
$a[0] = 1;
foreach ($a as $v) {
    echo $v;
}
```

结果：

```
321
```

## PHP数组“指针”相关函数

* current() - 返回数组中的当前单元
* end() - 将数组的内部指针指向最后一个单元
* next() - 将数组中的内部指针向前移动一位
* prev() - 将数组中的内部指针向前移动一位
* reset() - 将数组的内部指针指向第一个单元
* each() - 返回当前的键/值对并将指针向前一步

## PHP中的预定义变量（数组）

PHP 中的许多预定义变量都是“超全局的”。

这意味着它们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 `global $variable;` 就可以访问它们。

* $GLOBALS — 引用全局作用域中可用的全部变量
* $\_SERVER — 服务器和执行环境信息
* $\_GET — HTTP GET 变量
* $\_POST — HTTP POST 变量
* $\_FILES — HTTP 文件上传变量
* $\_REQUEST — HTTP Request 变量
* $\_SESSION — Session 变量
* **$\_ENV — 环境变量**
* $\_COOKIE — HTTP Cookies


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://phper.shujuwajue.com/shu-zu/ji-chu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
