> For the complete documentation index, see [llms.txt](https://php7.shujuwajue.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://php7.shujuwajue.com/php-70x-xin-te-xing/oop-te-xing/lei-xing-sheng-ming.md).

# 类型声明

## 简介：

在PHP7之前，我们在函数和类之间传递参数时不必声明变量类型，返回数据时也不必声明变量类型。任何数据类型都可以被传递、返回。这样会给PHP带来一个很大的问题：**PHP不清楚传递的是什么类型的变量，函数、方法接收到的变量也不知道是什么类型。为了解决这个问题，PHP7中引入了类型声明，目前明确的有两类变量可以声明类型：形参和返回值。**

> 类型声明在OOP与PHP程序中属于同一个特性，因为它既可以用在程序的函数中，也可以用在对象的方法中。

## 形参类型声明：

PHP7支持的形参类型声明的类型有：字符串型(string), 整型 (int), 浮点类型 (float), 以及布尔类型 (bool)。

```php
class Person
{
    public function age(int $age)
    {
        return $age;
    }

    public function name(string $name)
    {
        return $name;
    }

    public function isAlive(bool $alive)
    {
        return $alive;
    }
}


$person = new Person();

echo $person->name('Revin');
echo $person->age(27);
echo $person->isAlive(TRUE);
```

上面的代码，创建一个 Person 类，里面有三个方法，每个方法接受不同类型的形参且有着类型声明。如果执行上面的代码，能够正确运行并通过类型检测。

Age 支持浮点数型，例如 `27.5` 如果传递一个浮点数作为age方法的形参，也是正常运行的。代码如下：

```php
echo $person->age(30.5);
```

**默认请看下，形参类型声明不是完全限制的**，这就意味着我们可以传递一个浮点给期望得到整型数的方法, 也同样可以传递一个整形给期望得到整形术的方法。

```php
//echo $person->name(11111111111);
echo $person->name('Revin');
echo $person->age(27.5);
echo $person->isAlive(TRUE);
```

这样也就失去了指定声明形参类型,不过可以做一些限制，代码如下：

> 开启严格模式. 注意必须放在程序首行,否则会报`Fatal error: strict_types declaration must be the very first statement in the script in ...`

```php
declare(strict_types = 1);
```

此时我们若再传递一个浮点数给age方法的话，会得到一个 **Fatal error: Uncaught TypeError，**&#x8FD9;个Fatal 错误 的意思是 `Person::age` 只能接受一个整型数而非浮点型数。

> 注意：爱需要字符串形参的情况下，如果传入的不是字符串形参的话，也会出现以上类似的Fatal 错误。例如以下报错代码：
>
> ```php
> echo $person->isAlive('true');
> ```

## 返回类型声明：

**PHP 7 的另一个重要特性就是支持返回类型的声明，无论实在函数还是对象的方法中。**

这有点类似形参类型声明，对刚才的 Person 类进行修改，代码如下：

```php
declare(strict_types = 1);

class Person
{
    public function age(float $age) : float
    {
        return $age;
    }

    public function name(string $name) : string
    {
        return $name;
    }

    public function isAlive(bool $alive) : string
    {
        return ($alive) ? 'Yes' : 'No';
    }
}

$person = new Person();

echo $person->name('revin');
echo $person->age(27.5);
echo $person->isAlive(TRUE);
```

上面的代码 返回类型声明使用了 data-type 语法，对于形参类型声明与返回类型声明。

### 举个返回类型是对象的栗子：

修改上面的代码，加Address类， Person 类中加入 getAddress 方法，并且返回类型是Address对象。

```php
declare(strict_types = 1);

class Address
{
    public function getAddress()
    {
        return ['street' => 'shanghai', 'country' => 'China'];
    }
}

class Person
{
    public function age(float $age) : float
    {
        return $age;
    }

    public function name(string $name) : string
    {
        return $name;
    }

    public function isAlive(bool $alive) : string
    {
        return ($alive) ? 'Yes' : 'No';
    }

    public function getAddress() : Address
    {
        return new Address();
    }
}

$person = new Person();

var_dump($person->getAddress());
```

上面的代码执行没有问题，调用`Persion` 类中的 getAddress 方法执行完毕后，返回一个Address类型的数据。

若上面`Persion` 类中的getAddress 方法修改如下

```php
    public function getAddress() : Address
    {
        return ['street' => 'shanghai', 'country' => 'China'];
    }
```

再次实行会Fatal 错误，这是因为`Persion` 类中的 getAddress 方法返回了一个数组，而不是方法声明的Address类型的返回值。

```
Fatal error: Uncaught TypeError: Return value of Person::getAddress() must be an instance of Address, array returned in ..
```

## 为什么要使用类型声明？

它可以让函数、方法的形参与返回值有所预期，避免出现不必要的数据传递，从而造成错误。PHP 7 这个特性使代码更清晰且可读性更强，能够清楚的知道怎么样的数据类型将会被传递与返回。

## 补充知识: 三个点语法是什么?

当你看php7 官方的相关文档时m会看到`...` 的东西,如下示例:

```php
<?php
// Coercive mode
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));
```

其实这是PHP5.6 新特性-PHP 可变参数,详情官方文档:<http://php.net/manual/zh/functions.arguments.php#functions.variable-arg-list> , 把传进来的值，转成数组.

## 资料：

[PHP 7 标量类型声明 RFC](http://blog.jobbole.com/91735/)
