关于PHP函数
首先
我是日本系统开发株式会社的藤井先生。
这次我总结了关于PHP函数的类型声明和参数的概要。
声明类型
简述
在函数的参数和返回值上,可以声明类型。
通过这样做,可以确保参数是声明的类型。
可用于类型声明的类型列表。
<?php
function sum(int $a, int $b): int
{
return $a + $b;
}
echo sum(1, 2) . PHP_EOL; // 3
?>
允许空值的类型声明(PHP7.1.0)
在类型声明前加上问号(?),可以允许NULL的类型声明。这样一来,参数就可以接受NULL。
<?php
function sum(int $a, ?int $b): int
{
$b = $b ?? 10;
return $a + $b;
}
echo sum(1, 2) . PHP_EOL; // 3
echo sum(1, null) . PHP_EOL; // 11
?>
综合型(PHP8.0.0)
可以通过组合单一类型来创建复合类型。以下有两种复合类型。
-
- 単一の型の集合を表すunion型(PHP8.0.0)
- クラス/インターフェイスの交差型(PHP8.1.0)
PHP8.0.0引入了union类型
如果将类型声明为union,可以接受多个不同的类型。
union的声明方法是T1|T2…。
<?php
function sum(int $a, int|string $b): int
{
return $a + $b;
}
echo sum(1, 2) . PHP_EOL; // 3
echo sum(1, "2") . PHP_EOL; // 3
?>
PHP8.1.0 的一种特性是交叉编译模式。
当将一个类型声明为交叉类型时,它将接受符合作为类/接口声明的类型的所有值。
<?php
interface I { public function sum(int $a, int $b): int; };
class A {};
class B extends A implements I {
function sum(int $a, int $b): int
{
return $a + $b;
}
};
function callSum(I&A $b): int
{
return $b->sum(1, 2);
}
echo callSum(new B()) . PHP_EOL; // 3
?>
仅使用返回值来表示有效类型
以下是对”void”的中文翻译及释义:
– 空白 – 表示没有返回值或不返回任何值的情况,常用于编程中。
请注意,以上所提供的答案是人工翻译,并不具有统计数据支持。
这是表示函数不返回任何值的返回值类型。
<?php
function display(string $str): void
{
echo $str . PHP_EOL;
}
display("Hello World"); // Hello World
?>
从未(PHP8.1.0)
这个返回值类型表示函数不会返回。
它表明在函数中调用exit()、抛出异常或进入无限循环中的任一情况。
静态的(PHP8.0.0)
返回值的类型表示为调用方法的类的实例。
严格的类型检查
默认情况下,在期望一个标量类型声明中,如果可以将错误类型的值进行转换,那么会发生隐式转换(强制模式)。
可以为每个文件启用严格类型检查(严格模式)。在严格模式下,只接受与类型声明对应的值,否则会抛出TypeError。
为了启用严格类型检查,在代码中需要写上`declare(strict_types=1);`。
严格类型化适用于在启用了strict模式的文件内部进行的函数调用。它不适用于对该文件中声明的函数的调用。
如果在禁用严格类型化的文件中调用启用了严格类型化的文件的函数,则调用方的模式(coercive模式)将被使用,值将被隐式转换。
联合类型与自动转换(PHP8.0.0)
如果严格的类型检查无效的话就会被应用。如果指定的值的类型不包括在联合内,那么类型转换将按以下顺序从联合内确定。
-
- 整数
-
- 浮点数
-
- 字符串
- 布尔值
型宣言が int|string
値の型がunionに含まれている
値:42 パラメータ:42 // 自動変換されない
値:"42" パラメータ:"42" // 自動変換されない
値の型がunionに含まれていない
値:42.5 パラメータ:42 // floatはintに変換できるためintに自動変換
値:new Object() パラメータ:__toString()の戻り値 // intに変換できないためstringに自動変換
値:[] パラメータ:TypeErrorがスロー // int、stringに変換できないためTypeErrorがスロー
在指定值是一个包含int和float的数字格式字符串的时候,根据字符串是int格式还是float格式来自动转换为相应的类型。通过例外的方式,无论字符串的顺序如何,数值格式的字符串都会自动转换为int或者float。
型宣言が int|float
値:"45" パラメータ:45 // 文字列がint形式のためintに自動変換
値:"45.5" パラメータ:45.5 // 文字列がfloat形式のためfloatに自動変換
函数的参数
传递值
当将值传递给函数时,默认使用按值传递。即使在函数内部更改参数的值,函数外部的值也不会改变。
<?php
function addString(string $str): void
{
$str .= " World";
}
$str = "Hello";
addString($str);
echo $str . PHP_EOL; // Hello
?>
参考传递
如果想要在函数内部更改参数的值,可以使用以下方式。
在函数的参数名称前加上&符号,即可实现引用传递。
<?php
function addString(string &$str): void
{
$str .= " World";
}
$str = "Hello";
addString($str);
echo $str . PHP_EOL; // Hello World
?>
默认参数
在参数中定义默认值。当参数未指定时,将使用默认值(例如用于可选参数等)。
如果将参数设置为NULL,则不会分配默认值。
<?php
function display(?string $str = "Hello World"): void
{
echo $str . PHP_EOL;
}
display(); // Hello World
display("hello"); // hello
display(null); // ""
?>
可变长度参数
在函数定义中使用…会接受可变长度的参数。
<?php
function avg(...$nums): int|float
{
$total = 0;
foreach($nums as $num) {
$total += $num;
}
return $total / count($nums);
}
echo avg(10, 11, 12) . PHP_EOL; // 11
?>
在函数调用时,使用…符号在数组等对象后面,可以展开该数组,并将其作为参数传递。
<?php
function multiDisplay(string $str, int $cnt): void
{
for ($i = 0; $i<$cnt; $i++) {
echo $str . PHP_EOL;
}
}
multiDisplay(...["Hello World", 3]);
?>
PHP8.0.0中的命名参数
引数を位置ではなく、引数名で渡すことができるようになります。
オプションの引数が複数ある場合に、変更したい引数のみを名前付きで指定できます。
<?php
$jsonStr = '{ "hoge": "hoge" }';
var_dump(json_decode($jsonStr, flags: JSON_THROW_ON_ERROR));
var_dump(json_decode($jsonStr, null, 512, JSON_THROW_ON_ERROR));
?>
整理
-
- 引数と戻り値に型宣言が使える
-
- 型宣言の前に?を付けるとnullableになる
declare(strict_types=1);を記載しないと値が自動変換される可能性がある
関数には値渡し、リファレンス渡しの2つの渡し方がある
デフォルト引数、可変長引数、名前付き引数(PHP8.0.0)の機能が利用できる