PHP数据类型

PHP支持多种数据类型,这些类型可以分为三大类:标量类型、复合类型和特殊类型。了解和掌握这些数据类型是编写有效PHP代码的基础。

PHP数据类型分类

1. 标量类型

标量类型表示单个值,PHP支持四种标量类型:

  • 布尔型(boolean)- 表示真或假
  • 整型(integer)- 表示整数
  • 浮点型(float/double)- 表示小数
  • 字符串(string)- 表示字符序列

2. 复合类型

复合类型可以包含多个值,PHP支持两种复合类型:

  • 数组(array)- 可以存储多个相同或不同类型的值
  • 对象(object)- 表示类的实例

3. 特殊类型

PHP还支持三种特殊类型:

  • 资源(resource)- 表示对外部资源的引用
  • NULL - 表示空值
  • 回调/闭包(callable)- PHP 5.4+ 支持的匿名函数

标量类型详解

1. 布尔型(boolean)

布尔型是最简单的数据类型,它只有两个可能的值:TRUE 和 FALSE(不区分大小写)。

<?php
$isValid = true;
$isCompleted = false;

echo gettype($isValid); // 输出: boolean
?>

当转换为布尔型时,以下值被认为是 FALSE:

  • 布尔值 FALSE 本身
  • 整型值 0 和 -0
  • 浮点型值 0.0
  • 空字符串,以及字符串 "0"
  • 空数组
  • 特殊类型 NULL
  • 从空标记创建的 SimpleXML 对象

2. 整型(integer)

整型是没有小数部分的数字。在PHP中,整型可以是十进制、十六进制、八进制或二进制表示。

<?php
// 十进制表示
$decimal = 1234;

// 十六进制表示(前缀0x)
$hexadecimal = 0x4D2; // 等于十进制的1234

// 八进制表示(前缀0)
$octal = 02322; // 等于十进制的1234

// 二进制表示(前缀0b,PHP 5.4+支持)
$binary = 0b10011010010; // 等于十进制的1234

echo gettype($decimal); // 输出: integer
?>

整型的大小取决于平台,通常最大值是大约二十亿(32位有符号)。PHP 7支持64位整数,这取决于您的系统。

3. 浮点型(float/double)

浮点型(也叫双精度浮点数或实数)可以表示带小数部分的数字。

<?php
$float1 = 3.14;
$float2 = 2.5e3; // 科学计数法,表示2.5 * 10^3 = 2500
$float3 = 8E-5; // 科学计数法,表示8 * 10^-5 = 0.00008

echo gettype($float1); // 输出: double
// 注意:PHP中float和double是同义词,gettype()函数会返回"double"
?>

由于浮点数的内部表示方式,不要直接比较两个浮点数是否相等,应该比较它们的差值是否在一个很小的范围内。

4. 字符串(string)

字符串是字符的序列。在PHP中,字符串可以用三种方式定义:单引号、双引号和heredoc/nowdoc语法。

<?php
// 单引号字符串
$str1 = 'Hello, world!';

// 双引号字符串(会解析变量和转义序列)
$name = "John";
$str2 = "Hello, $name!";

// heredoc语法(多行字符串,会解析变量)
$str3 = <<<EOT
这是一个
多行字符串
示例
EOT;

// nowdoc语法(多行字符串,不解析变量)
$str4 = <<<'EOT'
这是一个
不解析变量的
多行字符串
EOT;

echo gettype($str1); // 输出: string
?>

复合类型详解

1. 数组(array)

数组是PHP中非常重要的数据类型,它可以存储一个或多个值,这些值可以是相同类型或不同类型。PHP支持索引数组和关联数组。

<?php
// 索引数组(默认从0开始的数字索引)
$colors = array("红色", "绿色", "蓝色");
// 或者PHP 5.4+的短语法
$colors = ["红色", "绿色", "蓝色"];

// 关联数组(使用自定义键名)
$person = array(
    "name" => "John",
    "age" => 30,
    "email" => "john@example.com"
);
// 或者PHP 5.4+的短语法
$person = [
    "name" => "John",
    "age" => 30,
    "email" => "john@example.com"
];

// 多维数组
$employees = [
    [
        "name" => "John",
        "age" => 30,
        "department" => "IT"
    ],
    [
        "name" => "Mary",
        "age" => 25,
        "department" => "HR"
    ]
];

echo gettype($colors); // 输出: array
?>

2. 对象(object)

对象是类的实例,是面向对象编程的基础。在使用对象之前,需要先定义类。

<?php
// 定义一个类
class Person {
    // 属性
    public $name;
    public $age;
    
    // 方法
    public function introduce() {
        return "我叫{$this->name},今年{$this->age}岁。";
    }
}

// 创建一个对象(实例化类)
$john = new Person();
$john->name = "John";
$john->age = 30;

echo gettype($john); // 输出: object

echo $john->introduce(); // 输出: 我叫John,今年30岁。
?>

特殊类型详解

1. 资源(resource)

资源是指向外部资源的引用,例如数据库连接、文件句柄等。资源是通过特殊的函数创建的。

<?php
// 打开一个文件资源
$file = fopen("example.txt", "r");
if ($file) {
    echo gettype($file); // 输出: resource
    fclose($file); // 关闭资源
}

// 数据库连接资源(示例)
// $connection = mysqli_connect("localhost", "username", "password", "database");
// if ($connection) {
//     echo gettype($connection); // 输出: resource
//     mysqli_close($connection); // 关闭连接
// }
?>

使用完资源后,应该调用相应的关闭函数来释放资源,防止资源泄漏。

2. NULL

NULL是一个特殊的值,表示一个变量没有值。NULL类型只有一个值:NULL(区分大小写)。

<?php
// 声明一个变量并赋值为NULL
$var = NULL;

// 声明一个变量但不赋值
$unassigned;
// 注意:在PHP中,只声明不赋值的变量不是NULL,而是未定义的

// 销毁一个变量的值
$assigned = "值";
unset($assigned);

echo is_null($var) ? "是NULL" : "不是NULL"; // 输出: 是NULL
?>

以下情况变量被认为是NULL:

  • 直接赋值为NULL
  • 未被赋值的变量(仅对类成员变量有效)
  • 被unset()函数处理过的变量

3. 回调/闭包(callable)

PHP 5.4引入了闭包(匿名函数),这是一种可以赋值给变量或作为参数传递的函数。

<?php
// 定义一个闭包函数
$greeting = function($name) {
    return "Hello, $name!";
};

// 调用闭包函数
echo $greeting("John"); // 输出: Hello, John!

// 将闭包作为参数传递给其他函数
$numbers = [1, 2, 3, 4, 5];
$doubled = array_map(function($n) {
    return $n * 2;
}, $numbers);

print_r($doubled); // 输出: Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 )
?>

PHP 7+ 的类型声明

PHP 7引入了标量类型声明,允许在函数参数和返回值上指定类型。PHP 7.4进一步引入了属性类型声明。

<?php
// 标量类型声明(PHP 7+)
function add(int $a, int $b): int {
    return $a + $b;
}

echo add(5, 3); // 输出: 8
// echo add(5.5, 3.3); // PHP 7默认会进行类型转换,输出: 8

// 严格类型声明(PHP 7+)
// declare(strict_types=1);
// function strictAdd(int $a, int $b): int {
//     return $a + $b;
// }
// echo strictAdd(5.5, 3.3); // 在严格模式下会抛出TypeError

// 属性类型声明(PHP 7.4+)
class User {
    public string $name;
    public int $age;
    public ?string $email; // 可为空类型(PHP 7.1+)
}
?>

类型检测函数

PHP提供了一系列函数来检测变量的类型:

<?php
$var = "Hello";

// 检测类型的函数
echo gettype($var); // 获取变量类型的字符串表示
var_dump($var); // 显示变量的类型和值

// 特定类型检测函数
echo is_bool($var) ? "是布尔值" : "不是布尔值"; // 检查是否为布尔值
echo is_int($var) ? "是整数" : "不是整数"; // 检查是否为整数
echo is_float($var) ? "是浮点数" : "不是浮点数"; // 检查是否为浮点数
echo is_string($var) ? "是字符串" : "不是字符串"; // 检查是否为字符串
echo is_array($var) ? "是数组" : "不是数组"; // 检查是否为数组
echo is_object($var) ? "是对象" : "不是对象"; // 检查是否为对象
echo is_resource($var) ? "是资源" : "不是资源"; // 检查是否为资源
echo is_null($var) ? "是NULL" : "不是NULL"; // 检查是否为NULL
echo is_callable($var) ? "是可调用的" : "不是可调用的"; // 检查是否为可调用的
?>

类型转换

PHP是一种弱类型语言,它会在需要时自动转换类型。也可以使用强制类型转换来显式地转换类型。

<?php
// 自动类型转换示例
$num = "123" + 456; // 字符串"123"被自动转换为整数123
var_dump($num); // 输出: int(579)

// 强制类型转换示例
$int = 123;
$float = 45.67;
$string = "789";
$bool = true;

// 转换为整数
$int1 = (int)$float; // 45
$int2 = (int)$string; // 789
$int3 = (int)$bool; // 1

// 转换为浮点数
$float1 = (float)$int; // 123.0
$float2 = (float)$string; // 789.0
$float3 = (float)$bool; // 1.0

// 转换为字符串
$string1 = (string)$int; // "123"
$string2 = (string)$float; // "45.67"
$string3 = (string)$bool; // "1"

// 转换为布尔值
$bool1 = (bool)$int; // true(非零整数为true)
$bool2 = (bool)0; // false(零为false)
$bool3 = (bool)""; // false(空字符串为false)
$bool4 = (bool)"0"; // false(字符串"0"为false)
$bool5 = (bool)"non-zero"; // true(非空且非"0"字符串为true)

// 转换为数组
$array1 = (array)$int; // 索引数组: [0 => 123]
$array2 = (array)$string; // 索引数组: [0 => "789"]
$array3 = (array)$bool; // 索引数组: [0 => true]

// 使用settype()函数进行类型转换
$var = "123";
settype($var, "integer");
var_dump($var); // 输出: int(123)
?>

PHP数据类型综合示例

<?php
// 1. 标量类型示例
$bool = true; // 布尔型
$int = 123; // 整型
$float = 45.67; // 浮点型
$string = "Hello, PHP!"; // 字符串

// 输出标量类型信息
echo "<h4>标量类型示例</h4>";
echo "布尔型: $bool, 类型: ".gettype($bool)."<br>";
echo "整型: $int, 类型: ".gettype($int)."<br>";
echo "浮点型: $float, 类型: ".gettype($float)."<br>";
echo "字符串: $string, 类型: ".gettype($string)."<br><br>";

// 2. 复合类型示例

// 索引数组
$colors = ["红色", "绿色", "蓝色"];

// 关联数组
$person = [
    "name" => "John",
    "age" => 30,
    "email" => "john@example.com"
];

// 多维数组
$users = [
    [
        "name" => "John",
        "age" => 30,
        "role" => "管理员"
    ],
    [
        "name" => "Mary",
        "age" => 25,
        "role" => "用户"
    ]
];

// 对象示例
class Car {
    public $brand;
    public $model;
    public $year;
    
    public function getInfo() {
        return "{$this->year} {$this->brand} {$this->model}";
    }
}

$car = new Car();
$car->brand = "Toyota";
$car->model = "Corolla";
$car->year = 2022;

// 输出复合类型信息
echo "<h4>复合类型示例</h4>";
echo "索引数组类型: ".gettype($colors)."<br>";
echo "数组内容: ";
echo "<pre>";
print_r($colors);
echo "</pre>";

echo "关联数组类型: ".gettype($person)."<br>";
echo "数组内容: ";
echo "<pre>";
print_r($person);
echo "</pre>";

echo "对象类型: ".gettype($car)."<br>";
echo "对象信息: ".$car->getInfo()."<br><br>";

// 3. 特殊类型示例

// NULL示例
$nullVar = NULL;
echo "<h4>特殊类型示例</h4>";
echo "NULL变量类型: ".gettype($nullVar)."<br>";
echo "是NULL吗? ".(is_null($nullVar) ? "是" : "否")."<br>";

// 资源示例(尝试打开一个文件)
echo "资源类型示例: ";
$file = fopen("example.txt", "a+");
if ($file) {
    echo gettype($file)."<br>";
    fwrite($file, "这是测试内容\n");
    fclose($file);
    echo "文件已创建并写入内容。<br>";
} else {
    echo "无法创建或打开文件。<br>";
}

// 闭包示例
$greeting = function($name) {
    return "Hello, $name! Welcome to PHP programming.";
};

echo "闭包类型: ".(is_callable($greeting) ? "可调用" : "不可调用")."<br>";
echo "闭包调用结果: ".$greeting("PHP学习者")."<br><br>";

// 4. 类型转换示例
echo "<h4>类型转换示例</h4>";
$var = "123.45";

// 转换为整数
echo "字符串 '$var' 转换为整数: ".(int)$var."<br>";

// 转换为浮点数
echo "字符串 '$var' 转换为浮点数: ".(float)$var."<br>";

// 转换为布尔值
$emptyString = "";
echo "空字符串转换为布尔值: ".(bool)$emptyString." (" . ((bool)$emptyString ? "true" : "false") . ")<br>";
$nonEmptyString = "非空字符串";
echo "非空字符串转换为布尔值: ".(bool)$nonEmptyString." (" . ((bool)$nonEmptyString ? "true" : "false") . ")<br>";

// 自动类型转换
$num1 = "100"; // 字符串
$num2 = 200; // 整数
$result = $num1 + $num2;
echo "自动类型转换(字符串+整数): $result, 结果类型: ".gettype($result)."<br>";

// 5. PHP 7+ 类型声明示例

echo "<h4>PHP 7+ 类型声明示例</h4>";

// 带类型声明的函数
function calculateSum(int $a, int $b): int {
    return $a + $b;
}

// 调用带类型声明的函数
$sum = calculateSum(10, 20);
echo "类型声明函数调用结果: $sum<br>";

// 类型声明 - 传入浮点数会自动转换为整数
$sum2 = calculateSum(10.9, 20.5);
echo "传入浮点数的自动转换结果: $sum2<br>";

// 类型声明 - 传入字符串(如果可转换为数字)
$sum3 = calculateSum("15", "25");
echo "传入数字字符串的自动转换结果: $sum3<br>";
?>