PHP:声明函数的参数类型

45

我正在尝试创建一个带有声明参数类型的函数,以便快速检查它们是否处于正确的格式,但当它返回一个字符串时,我会遇到这个错误:

Catchable fatal error: Argument 2 passed to myfunction() must be an instance of string, string given, called in path_to_file on line 69 and defined in path_to_file on line 49

示例

function myfunction( array $ARRAY, string $STRING, int $INTEGER ) { 
    return "Args format correct"; 
}
myfunction(array("1",'2','3','4'), "test" , 1234);

哪里出错了?


你不能为标量值提供提示。 - alexn
3
现在您可以使用PHP 7.0,只需访问http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration,即可实现。 - sobi3ch
9个回答

62
根据PHP5文档所述:

类型提示只能是对象和数组(自PHP 5.1以来)。不支持int和string的传统类型提示。

由于stringint不是类,因此您无法在函数中进行“类型提示”。

从PHP 7.0开始,支持将参数类型声明为字符串,整数,浮点数和布尔值。


12
此回答已过时,请参考 http://php.net/manual/zh/functions.arguments.php#functions.arguments.type-declaration 了解更多关于函数参数类型声明的信息。 - phil294
如果我有一个名为 Person 的类,并且我想将一个 Person 数组作为参数传递给我的函数,我该怎么做呢?如何实现? - arm

37

1
始终建议包含参数类型吗? - Alex Lacayo
6
使用boolean作为类型声明将检查instanceof boolean而不是检查布尔值。正确的类型声明应该是bool。例如,function a(value: boolean); a(true)会失败。 - a-ctor
这个函数的返回类型语法怎么样? - johannchopin
@AlexLacayo 我认为这是一个好的实践。PHP在变量类型和赋值方面一直非常宽松。但是过于开放最终会导致令人困惑的错误。 返回类型使用冒号后跟返回类型进行声明。例如:function foo() : int { return 0; } - Daniel Wu
根据https://www.php.net/manual/en/language.types.declarations.php,应该使用`bool`而不是`boolean`,对吗? - ᴍᴇʜᴏᴠ
@mehov 是的,自从我在2017年回答时,PHP中的类型支持已经变得更加健壮,当时文档中使用的是boolean而不是bool。我会更新答案,以便帮助现在看到它的其他人。 - Amal Ajith

5
根据PHP手册,在PHP 5.1及以上版本中,您可以对array进行操作,在PHP 7及以上版本中,您可以对stringint类型进行操作。请看以下内容:
  • 类/接口名称 参数必须是给定类或接口名称的实例。 PHP 5.0.0
  • self 参数必须是与定义该方法的类相同的类的实例。这只能用于类和实例方法。 PHP 5.0.0
  • array 参数必须是一个数组。 PHP 5.1.0

  • callable 参数必须是一个有效的可调用对象。 PHP 5.4.0
  • bool 参数必须是一个布尔值。 PHP 7.0.0
  • float 参数必须是一个浮点数。 PHP 7.0.0
  • int 参数必须是一个整数。 PHP 7.0.0

  • string 参数必须是一个字符串。 PHP 7.0.0

  • iterable 参数必须是数组或Traversable的实例。 PHP 7.1.0

1
自 PHP 5.1.0 起,您可以将数组用作提示。 - Roger Campanera
1
当然,你是对的,我在写错之后自己改正了它。呵呵。 - Machado

5
您可以尝试以下方法,这对我一直很有效:
对于字符串:
function setData($Name=""){ }

这将强制名称为字符串,但它不检查它是否为字符串。

对于数值类型的值

function setData($age=0){ }

这将强制年龄为数字。如果传递的是字符串,则该值将为0。

对于数组值,有两种变化。

function setData(array $data){ } 

如果没有传递数组,它将会抛出一个错误。

function setData($data=array()){ } 

如果没有给出$data的值,这将传递一个空数组。

8
为参数指定默认值是一项重要的技术,但不应将其等同于类型提示。例如,指定func($x=0)并不完全意味着强制$x的值为数字。相反,如果您的函数始终将$x的值视为数字进行处理,那么巧合的是,它会起作用。实际上,如果您传递一个可解析为数字的字符串,则会以数字方式处理。即使是func('5')也会愉快地将其当作整数值使用。而无法解析的字符串则被解释为零,因此您的默认值0是通过巧合起作用的。 - zerobandwidth

1

stringint和其他内置类型不是,在参数中您指定的是参数的。唯一支持放置在那里的内置类型是array


0
如果您没有使用 PHP 7.x 或需要一些复杂的参数验证(例如“数组或 \Traversable”,因为您可以遍历数组,但它们是原始类型,不实现 \Traversable 接口),则可以使用 args 模块来自非标准PHP类库 (NSPL)
use const \nspl\args\numeric;
use function \nspl\args\expects;

function sqr($x)
{
    expects(numeric, $x);
    return $x * $x;
}

sqr('hello world');

输出:

InvalidArgumentException: Argument 1 passed to sqr() must be numeric, string given in /path/to/example.php on line 17

Call Stack:
    0.0002     230304   1. {main}() /path/to/example.php:0
    0.0023     556800   2. sqr() /path/to/example.php:17

0

当我需要使用类型提示时,我会这样做:

<?php 
declare(strict_types=1);

3
请在您的回答中添加更多描述。 - always-a-learner

0

你不能将类型定义为stringint。PHP“不知道”它们是什么。


5
它知道类型,只是它不在意。 - Gumbo

0
在PHP7中声明变量参数类型

<?php
function total_intervals($unit, DateInterval ...$intervals) {
    $time = 0;
    foreach ($intervals as $interval) {
        $time += $interval->$unit;
    }
    return $time;
}

$a = new DateInterval('P1D');
$b = new DateInterval('P2D');
echo total_intervals('d', $a, $b).' days';

// This will fail, since null isn't a DateInterval object.
echo total_intervals('d', null);

https://www.php.net/manual/en/functions.arguments.php#example-164


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接