Skip to content

内置函数

PHP 自带大量函数,打开就能用,不必自己写:数个数、判断空、转义 HTML、调试打印。前面已经用过 var_dump()count()htmlspecialchars()。本篇先弄清「怎么调用」,再把最容易混的三个讲透:issetis_nullempty

php
<?php

$name = "PHP";

var_dump(isset($name));
var_dump(is_null($name));
var_dump(empty($name));

手册入口:https://www.php.net/manual/zh/funcref.php。不确定某个函数时,搜函数名即可。

怎么调用

函数有名字、参数、返回值。括号不能省(语言结构另说):

php
<?php

$langs = ["PHP", "HTML", "SQL"];
$n = count($langs);          // 传入数组,返回 int 3
echo strlen("PHP"), "\n";    // 3,按字节计长度
var_dump(in_array("PHP", $langs, true));

参数个数、类型以手册为准。多出来的参数 PHP 8 会 ArgumentCountError;该传却没传同样报错。

返回值要接住才会留下来:

php
<?php

$s = "abc";
strtoupper($s);      // 返回 "ABC",但没赋给变量,$s 仍是 abc
$s = strtoupper($s); // 现在 $s 是 ABC

多数内置函数不改你传入的变量(sort() 这类排序函数除外,会改原数组)。

语言结构还是函数

有几样写起来像函数,其实是语言结构,手册里会标明:

写法类型说明
isset / empty / unset语言结构可以探测未定义变量且不 Warning
echo / print语言结构echo 与 print
is_null()函数未定义变量会 Warning
count() / strlen()函数普通调用

语言结构不能当回调、不能写成 $fn = "isset"; $fn($x)is_null 可以,但没必要。

日常仍写成 isset($x)empty($x),和函数同一套括号习惯即可。

isset:有没有、且不是 null

isset($x) 为 true 当且仅当:这个名字已经定义,并且当前值不是 null

php
<?php

$name = "小明";
$blank = "";
$zero = 0;
$none = null;

var_dump(isset($name));    // true
var_dump(isset($blank));   // true,空字符串也算「有」
var_dump(isset($zero));    // true,0 也算「有」
var_dump(isset($none));    // false,值是 null
var_dump(isset($missing)); // false,未定义,且不报警

可以一次检查多个,全部 isset 才为 true(从左短路,左边失败右边不再看):

php
<?php

$a = 1;
$b = 2;
var_dump(isset($a, $b));       // true
var_dump(isset($a, $missing)); // false

数组键同样适用,见 数组

php
<?php

$user = ["name" => "小明", "bio" => null];

var_dump(isset($user["name"])); // true
var_dump(isset($user["bio"]));  // false,键在但值是 null
var_dump(isset($user["age"]));  // false,没有这个键

「键在不在、哪怕值是 null」要用 array_key_exists(),不要用 isset

unset($x) 之后 isset($x) 为 false,效果接近「从未定义」。

is_null:是不是 null

is_null($x) 等价于 $x === null。它是真正的函数,要求这个变量已经存在

php
<?php

$none = null;
$zero = 0;
$name = "小明";

var_dump(is_null($none)); // true
var_dump(is_null($zero)); // false
var_dump(is_null($name)); // false
var_dump($none === null); // true,更常见的写法

未定义时 PHP 8 会 Warning,再把变量当成 null,于是 is_null 还返回 true:

php
<?php

var_dump(is_null($missing));
// Warning: Undefined variable $missing
// bool(true)

所以:

  • 变量肯定已经赋值(包括可能被赋成 null)→ 用 === nullis_null
  • 变量可能根本没定义 → 不要 is_null,用 isset??

函数名叫 is_null(中间有下划线),没有 isnull()

empty:当成布尔假就算空

empty($x) 为 true 当「拿它当布尔值是假」,或者它未定义。未定义时不 Warning

下面这些 empty 都是 true:

说明
未定义变量不报警
null
false
00.0整数 / 浮点零
""空字符串
"0"字符串零,最容易踩坑
[]空数组
php
<?php

var_dump(empty(0));      // true
var_dump(empty("0"));    // true
var_dump(empty("00"));   // false,「00」不是 PHP 眼里的假
var_dump(empty("0.0"));  // false
var_dump(empty([]));     // true
var_dump(empty([0]));    // false,数组里有元素
var_dump(empty("false")); // false,非空字符串

等价记忆:empty($x)!isset($x) || !$x

表单里没填的输入常常是 "",用 empty 能拦住;但用户真的输入了 0(数量、评分),empty 也会当成没填。这种字段用 isset + 严格比较,或 ?? 再判断 === ""

对照表(建议动手跑一遍)

php
<?php

$samples = [
    "未定义" => "missing",
    "null"   => null,
    "false"  => false,
    "0"      => 0,
    '"0"'    => "0",
    '""'     => "",
    "[]"     => [],
    '"php"'  => "php",
    "1"      => 1,
];

foreach ($samples as $label => $value) {
    if ($label === "未定义") {
        unset($tmp);
    } else {
        $tmp = $value;
    }
    echo sprintf(
        "%-8s isset=%s  is_null=%s  empty=%s\n",
        $label,
        isset($tmp) ? "T" : "F",
        // 未定义时 is_null 会 Warning,演示里用 @ 仅供对照,正式代码不要 @
        @is_null($tmp) ? "T" : "F",
        empty($tmp) ? "T" : "F",
    );
}

结果应当是:

issetis_nullempty
未定义FT(伴随 Warning)T
nullFTT
falseTFT
0TFT
"0"TFT
""TFT
[]TFT
"php"TFF
1TFF

读这张表只记三句:

  1. isset 认「有货」:0""false 都有货;null 和没定义没有
  2. is_null 只认 null(没定义时会先报警,再当成 null
  3. empty 认「布尔假」:上面所有假值 + 没定义

怎么选

你想问的问题
这个变量 / 键在不在,且不是 nullisset
这个(已存在的)值是不是 null=== null(或 is_null
没填、空串、0、空数组……一律当没有?empty(确认 0 也该被排除)
缺了就用默认值,0 要保留??? / ??=,见 三元运算符
数组键在不在,值是 null 也算在?array_key_exists
php
<?php

$page = $_GET["page"] ?? 1;          // 缺键用 1;传了 0 会留下 0 再自己转换
$page = (int) $page;

$title = $_POST["title"] ?? "";
if ($title === "") {
    echo "标题必填\n";
}

if (empty($_POST["agree"])) {
    echo "请勾选同意\n";             // checkbox 没勾选时键不存在
}

不要写 if (is_null($_GET["q"])) 来探测参数:没传时会 Warning。用 isset($_GET["q"])$_GET["q"] ?? null

???: 的关系

php
<?php

$zero = 0;

echo $zero ?? "兜底", "\n"; // 0,?? 只排除 null / 未定义
echo $zero ?: "兜底", "\n"; // 兜底,?: 把假值都换掉
echo empty($zero) ? "空" : "有", "\n"; // 空

?? 更接近「isset 则用原值,否则默认」:$a ?? $b$a 未定义或为 null 时取 $b,不会 Warning。多数读配置、读请求的场景,优先 ?? 而不是先 isset 再取值。

常见误区

empty 判断数量、ID。 empty(0) 为 true,库存为零会被当成「没这个字段」。

is_null 探测未定义或 $_GET 缺键。 PHP 8 会 Warning。改 isset??

以为 isset($x) 等于 !is_null($x) 变量已存在时两者相反;未定义时 isset 安静返回 false,is_null 报警。

以为 isset($arr["k"]) 能区分「没这个键」和「键的值是 null」。 两种都是 false。要区分用 array_key_exists

empty("0") 为 true。 表单传来的数字全是字符串,"0" 会被 empty 吃掉。需要 0 合法时,写 $n === "" 或先转 int 再另判。

isset / empty 传函数返回值以外的「未定义」很安全,于是到处 empty。 能表达更精确的意图就更精确:缺省用 ??,空串用 === ""

正式代码不要用 @is_null($x) 来吞 Warning,那是在掩盖问题。

已经用过的内置函数(速查)

函数作用
var_dump() / print_r()调试打印
htmlspecialchars()输出到 HTML 前转义
count()数组元素个数
strlen() / mb_strlen()字节长度 / 字符长度(中文用 mb)
implode() / explode()数组 ↔ 字符串
in_array()是否包含某值(第三个参数给 true
array_key_exists()键是否存在
sort() / array_merge()排序、合并,见 数组
filter_input()过滤请求参数,见 超全局变量
is_int() / is_string() / is_array()判断类型
gettype()返回类型名字符串

类型判断还有 is_null(),和 === null 选一个即可,本指南优先 === null

更多函数按主题查手册,不必一次背完。用到字符串、文件、时间时再对手册抄参数。

书写建议

  • 未定义可能发生的地方:isset??,不要 is_null、不要直接读
  • 已存在的值是不是 null=== null
  • empty 只用于「假值都不要」且你接受 "0" 也算空
  • 新代码读数组键优先 $arr["k"] ?? $default
  • 查手册时看清返回值会不会是 false(很多找位置的函数找不到就返回 false

练习

  1. $a 分别为未赋值、null0"0""""php",列出 isset / empty 的结果(is_null 只对已赋值的测,避免 Warning)。
  2. 写一段:仅当 $_GET["q"] 存在且不是 null 时打印它(用 isset);缺省时打印 。不要触发 Undefined array key。
  3. 模拟表单 $qty = "0"(字符串零)。分别用 empty($qty)$qty === "" 判断「没填」,解释哪一种会把合法的 0 件库存误判掉。
  4. $user = ["name" => "小明", "bio" => null],对照 issetis_null($user["bio"])array_key_exists("bio", $user) 三个结果。

上一篇:变量的作用域

基于 VitePress 构建的 PHP 基础学习指南