全网最全最新 -- PHP教程(PHP 8+)

PHP基础教程

前言

PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习,使用广泛,主要适用于Web开发领域。

如果数据量较大,PHP语言还可以拓宽链接面,与各种数据库相连,缓解数据存储、检索及维护压力。随着技术的发展,PHP 语言搜索引擎还可以量体裁衣,实行个性化服务,如根据客户的喜好进行分类收集储存,极大提高了数据运行效率。


一、语法基础

(1)标准语法

PHP脚本以<?php开始 和 以?>标记结束。

PHP定界符<?php(?>在下面的示例中)简单地告诉PHP引擎将,封闭的代码块视为PHP代码,而不是简单的HTML。

每个PHP语句均以分号(;)结尾 - 告诉PHP引擎已到达当前语句的结尾。

<?php
// 要执行的一些代码
echo "Hello, world!";
?>

在这里插入图片描述

(2)在 html 中嵌套php代码

PHP文件是扩展名为.html的纯文本文件。 在PHP文件中,您可以像在常规HTML页面中一样编写HTML,还可以嵌入PHP代码以供服务器端执行。

直接使用浏览器并不能解析出.php文件,是因为:

  1. PHP 是服务器端脚本,需在服务器上运行并生成 HTML 等客户端代码;
  2. 浏览器没有 PHP 解析引擎,也不具备运行 PHP 的环境和权限;
  3. 从安全和架构设计出发,核心逻辑必须放在服务器端执行。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"
    <title>一个简单的PHP文件</title>
</head>

    <h1><?php echo "Hello, world!"; ?></h1>

</html>

在浏览器运行后的结果如下:

在这里插入图片描述

(3)注释

PHP支持单行和多行注释。要编写单行注释,请以两个斜杠(//)或井号(#)开头。要编写多行注释,在注释前加一个斜杠,然后加上一个星号(/* ),然后在注释前加一个星号,然后再加上一个斜杠( */),如下所示:

<?php
//这是单行注释
#这也是单行注释
/*
这是一个多行注释块。
它跨越的范围超过。
一行
*/
echo "Hello, world!";
?>

(4)PHP中的区分大小写

HP中的变量名称区分大小写。作为结果的变量 c o l o r , color, colorColor和$COLOR被视为三个不同的变量。

<?php 
    $color = "bule";
    echo $color;
    echo $COLOR;
    echo $Color;

?>
#运行结果
bule
Warning: Undefined variable $COLOR in E:\Code\20250728\test.php on line 4
Warning: Undefined variable $Color in E:\Code\20250728\test.php on line 5

运行上面的实例,它只会显示该变量的值 c o l o r ,并产生 color,并产生 color,并产生Color和$COLOR变量的“未定义的变量”警告。

但是,关键字,函数和类的名称不区分大小写。结果调用gettype() 或 GETTYPE()产生相同的结果。

<?php 
    $color = "bule";
    echo gettype($color) ;
    echo "<br>";
    echo GETTYPE($color) ;
?>
#运行结果
string
string

(5)变量

1.变量声明

声明格式: v a r n a m e = v a l u e ; ∗ ∗ ‘ var_name = value; **` varname=value;变量名`之间不能有空格,必须挨着 **

PHP变量的命名约定

  • PHP中的所有变量均以 $ 符号开头,后跟变量名称。
  • 变量名必须以字母或下划线(_)字符开头。
  • 变量名不能以数字开头。
  • 在PHP变量名只能包含字母数字字符和下划线(A-z,0-9,和 _)。
  • 变量名称不能包含空格。

注意: PHP中的变量名称区分大小写,表示 $x 和 $X 是两个不同的变量。因此,定义变量名时要小心。

变量用于存储数据,例如文本字符串,数字等。变量值可以在脚本过程中更改。以下是有关变量的一些重要信息:

  • 在PHP中,在向变量添加值之前无需声明变量。PHP根据变量的值自动将其转换为正确的数据类型。
  • 声明变量后,可以在整个代码中重复使用它。
  • 赋值运算符(=)用于为变量赋值。
<?php 
    $color = "bule";
    $num = 10;
    echo $num;
    echo "<br>";
    echo $color;
?>
#运行结果
10
bule
2.作用域

作用域可以定义为变量对声明它的程序所具有的可用性范围。PHP变量可以是四种作用域类型之一。

1、局部变量

在函数中声明的变量被认为是局部变量。 也就是说,只能在该函数中引用它。 该函数以外的任何赋值都将被视为与该函数中包含的赋值完全不同的变量

<?php 
    $x = 10;
    function test(){
         $x = 20;
         print "内部的x是: $x\n";
     }
    test();
    print "<br> 外部的x是: $x\n";
?>
//运行结果
内部的x是: 20
外部的x是: 10
2、函数参数 (形参)

函数参数在函数名称后和括号内声明。它们的声明非常像典型变量:

<?php
   function multiply ($value) { //将值乘以10,然后将其返回给调用方
      $value = $value * 10;
      return $value;
   }
   $retval = multiply (10);
   Print "返回值为 $retval\n";
?>
//运行结果
返回值为 100
3、静态变量

作用域称为静态。与声明为函数参数的变量(在函数出口处销毁)相反,静态变量在函数退出时不会丢失其值,并且如果再次调用该函数,则仍将保留该值。只需将关键字STATIC放在变量名称的前面,即可将变量声明为静态变量。

<?php
   function keep_track() {
      STATIC $count = 0;
      $count++;
      print $count;
      print "<br />";
   }
   keep_track();
   keep_track();
   keep_track();
?>
//运行结果
1
2
3
1. 函数内部的静态变量

当静态变量在函数内部定义时,它属于局部变量。这类变量有以下特点:

  • 仅在函数内部可见。
  • 不会在函数执行结束后被销毁,会保留上一次的值。
  • 每次函数被调用时,不会重新初始化。
function test() {
    static $count = 0; // 静态局部变量
    $count++;
    echo $count . "\n";
}

test(); // 输出1
test(); // 输出2(保留了上次的值)
2. 类中的静态属性

要是静态变量是在类中定义的(即静态属性),它就不属于局部变量,而是类变量。其特点如下:

  • 被类的所有实例共享。
  • 可以不依赖类的实例直接访问。
  • 作用域是整个类。
class MyClass {
    public static $shared = 0; // 类变量,非局部变量
}

MyClass::$shared++; // 不依赖实例访问
echo MyClass::$shared; // 输出1
总结
  • 函数内部的静态变量属于局部变量,其作用域局限于函数内部。
  • 类中的静态属性属于类变量,其作用域是整个类。
4、全局变量

与局部变量不同,全局变量可以在程序的任何部分访问。 但是,为了进行修改,全局变量必须在要修改的函数中显式声明为全局变量。 这可以非常方便地通过将关键字global放在应该被识别为全局的变量前面来实现。 将此关键字放在已经存在的变量前面会告诉PHP使用具有该名称的变量。

$a = 10; // 全局变量
function test() {
    global $a; // 显式声明:这里的$a是全局变量
    $a = 20; // 修改全局变量
    echo $a; // 输出20(全局变量的值)
}
test();
echo $a; // 输出20(全局变量已被修改)

(6)常量

1.命名约定

常量名称必须遵循与变量名称相同的规则,这意味着有效的常量名称必须以字母或下划线开头,后跟任意数量的字母,数字或下划线,但有一个例外:常量名称不需要前缀$

**注意:**按照惯例,常量名称通常以大写字母书写。这是因为它们易于识别并与源代码中的变量区分开。

2.普通常量

常量是固定值的名称或标识符。常量就像变量一样,除了常量一旦定义后就不能取消定义或更改(魔术常量除外)。

常量对于存储脚本运行时不会更改的数据非常有用。此类数据的常见示例包括配置设置,例如数据库用户名和密码,网站的基本URL,公司名称等。

常量是使用PHP的define()函数定义的,该函数接受两个参数:常量的名称及其值。一旦定义了常量值,就可以随时通过引用其名称来对其进行访问。

<?php
// 定义常量
define("SITE_URL", "/");
// 使用常量
echo '感谢您访问 - ' . SITE_URL;
?>
//运行结果
感谢您访问 - /

常量和变量之间的区别是

  • 不需要在常量之前写一个美元符号($),而变量中必须在名称前面写一个美元符号。
  • 常量不能通过简单的赋值来定义,只能使用define()函数来定义。
  • 可以在任何位置定义和访问常量,而无需考虑变量作用域规则。
  • 一旦设置了常量,就不能重新定义或取消定义。
3.Magic常量

有五个神奇的常数会根据使用的位置而变化。这些特殊常量不区分大小写,如下所示-

Sr.No名称& 描述
1**LINE**文件的当前行号。
2**FILE**文件的完整路径和文件名。 如果在Include中使用,则返回包含文件的名称。 从PHP 4.0.2开始,__file__总是包含绝对路径,而在旧版本中,在某些情况下它包含相对路径。
3**FUNCTION**函数名称。 (在PHP 4.3.0中添加)从PHP 5开始,此常量返回声明的函数名称(区分大小写)。 在PHP4中,它的值总是小写的。
4**CLASS**类名。 (在PHP 4.3.0中添加)从PHP 5开始,此常量返回声明的类名(区分大小写)。 在PHP4中,它的值总是小写的。
5**METHOD**类方法名称。(在PHP5.0.0中添加)方法名按声明返回(区分大小写)。

(7)echo & print

1.echo

echo语句可以输出一个或多个字符串。一般来说,echo语句可以显示可以显示给浏览器的任何内容,例如字符串,数字,变量值,表达式的结果等。

由于echo是一种语言构造,而不是实际的函数(如if语句),因此可以在不带括号的情况下使用它,例如echo或echo()。但是,如果要将多个参数传递给echo,则不能将这些参数括在括号中。

显示文本字符串
<?php
//显示文本字符串
echo "Hello World!";
?>
//运行结果
Hello World!
显示HTML代码
<?php
//显示HTML代码
echo "<h4>这是一个简单的标题。</h4>";
echo "<h4 style='color: red;'>这是有样式的标题。</h4>";
?>

在这里插入图片描述

显示变量
<?php
//定义变量
$txt = "Hello World!";
$num = 123456789;
$colors = array("Red", "Green", "Blue");
//定义变量
echo $txt;
echo "<br>";
echo $num;
echo "<br>";
echo $colors[0];
?>
//运行结果
Hello World!
123456789
Red
2.print

使用print语句(echo的代替方法)将输出显示到浏览器。像echo一样,打印也是一种语言构造函数,而不是真正的函数。因此可以在不带括号的情况下使用它:print 或 print()。

echo和print语句的工作方式完全相同,只是print语句只能输出一个字符串,并且始终返回1。这就是echo语句被认为比print语句快一点的原因,因为它不返回任何值。

显示文字字符串
<?php
//显示文本字符串
print "Hello World!";
?>
//输出结果
Hello World!
显示HTML代码
<?php
//显示HTML代码
print "<h4>这是一个简单的标题。</h4>";
print "<h4 style='color: red;'>这是有样式的标题。</h4>";
?>

在这里插入图片描述

显示变量
<?php
//定义变量
$txt = "Hello World!";
$num = 123456789;
$colors = array("Red", "Green", "Blue");
//定义变量
print $txt;
print "<br>";
print $num;
print "<br>";
print $colors[0];
?>
//输出结果
Hello World!
123456789
Red

(8)数据类型

PHP 中的变量可以存储不同类型的数据,从简单的标量值到复杂的对象和资源。PHP 支持多种数据类型,可分为原始类型复合类型伪类型三类(共13个):

类型分类数据类型描述示例
原始类型整数 (int)没有小数部分的数字,支持十进制、十六进制、八进制或二进制表示。$num = 42; $hex = 0xFF; // 255
浮点数 (float)有小数部分的数字,或指数形式表示的数字。$float = 3.14; $scientific = 1.2e3; // 1200
字符串 (string)字符序列,可使用单引号、双引号或 Heredoc/Nowdoc 语法定义。$str = "Hello"; $heredoc = <<<EOT\n多行文本\nEOT;
布尔值 (bool)只有两个值:truefalse,用于条件判断。$isValid = true;
资源 (resource)保存到外部资源的引用(如文件句柄、数据库连接等)。$file = fopen('test.txt', 'r');
NULL只有一个值:NULL,表示变量没有值或被显式赋值为 NULL$var = NULL;
复合类型数组 (array)有序的键值对集合,键可以是整数或字符串,值可以是任意类型。$arr = [1, 'key' => 'value'];
对象 (object)类的实例,通过 new 关键字创建,包含属性和方法。class Person {} $obj = new Person();
可调用 (callable)表示一个可以被调用的函数、方法或闭包。function sum($a, $b) { return $a + $b; } $callable = 'sum';
迭代器 (iterable)可遍历的对象或数组,用于 foreach 循环。$arr = [1, 2, 3]; function gen() { yield 1; }
伪类型混合 (mixed)表示可以是任意类型的值(PHP 8.0+ 推荐使用联合类型 `Type1Type2`)。
数值 (number)表示可以是整数或浮点数的值。function add(number $a, number $b) { return $a + $b; }
回调 (callback)callable 相同,用于兼容旧代码。array_map(callback $callback, $array);

关键说明:

  1. 类型声明:PHP 7+ 引入了严格类型模式declare(strict_types=1)),允许函数参数和返回值使用更精确的类型声明(如 intstring|null)。
  2. 联合类型(PHP 8.0+):允许变量或参数为多种类型之一(如 int|string),部分替代了 mixed 的使用。
  3. 资源类型:通常由外部函数(如 fopen()mysqli_connect())创建,需通过对应函数(如 fclose()mysqli_close())释放。
  4. 可调用类型:包括函数名(字符串)、对象方法(数组形式)和闭包(Closure 对象)。
1.整数

整数可以使用十进制(以10为基数),十六进制(以16为基数-前缀0x)或八进制(以8为基数-前缀0)表示法指定,并可选地以符号(-或+)开头。

<?php
$a = 123; // 十进制数
echo "(123)₁₀ = " . gettype($a) . "(" . $a . ")<br>";

$b = -123; // 负数
echo "(-123)₁₀ = " . gettype($b) . "(" . $b . ")<br>";

$c = 0x1A; // 十六进制数
echo "(0x1A)₁₆ = " . gettype($c) . "(" . $c . ")<br>";

$d = 0123; // 八进制数
echo "(0123)₈ = " . gettype($d) . "(" . $d . ")<br>";

$f = 0b11111111; // 二进制数
echo "(0b11111111)₂ = " . gettype($f) . "(" . $f . ")<br>";
?>
//运算结果
(123)₁₀ = integer(123)
(-123)₁₀ = integer(-123)
(0x1A)₁₆ = integer(26)
(0123)₈ = integer(83)
(0b11111111)₂ = integer(255)

**注意:**从PHP 5.4+开始,您还可以以二进制(基数2)表示法指定整数。要使用二进制表示法,请在数字前加0b(例如$var = 0b11111111;)。

2.PHP 字符串

字符串是字符序列,其中每个字符都与字节相同。字符串最大可以为2GB(最大2147483647字节)。指定字符串的最简单方法是将其括在单引号中(例如,‘Hello world!’),也可以使用双引号(“ Hello world!”)。

<?php
$a = 'Hello world!';
echo $a;
echo "<br>";
 
$b = "Hello world!";
echo $b;
echo "<br>";
 
$c = 'Stay here, I\'ll be back.';
echo $c;
?>
//运行结果
Hello world!
Hello world!
Stay here, I'll be back.
3.PHP 浮点数或双精度数

浮点数(也称为“浮点数”,“双精度数”或“实数”)是十进制或小数。

<?php
$a = 1.234;
var_dump($a);
echo "<br>";
 
$b = 10.2e3;
var_dump($b);
echo "<br>";
 
$c = 4E-10;
var_dump($c);
?>
//运行结果
float(1.234)
float(10200)
float(4.0E-10)
4.PHP 布尔值

布尔值就像一个开关,它只有两个可能的值1(true)或0(false)。

<?php
//将值true赋给变量
$show_error = true;
var_dump($show_error);
?>
//运行结果
bool(true)
5.PHP 数组

数组是一次可以容纳多个值的变量。将一系列相关项目汇总在一起非常有用,例如一组国家或城市名称。数组被正式定义为数据值的索引集合。数组的每个索引(也称为键)都是唯一的,并且引用相应的值。

<?php
$colors = array("Red", "Green", "Blue");
var_dump($colors);
echo "<br>";
 
$color_codes = array(
    "Red" => "#ff0000",
    "Green" => "#00ff00",
    "Blue" => "#0000ff"
);
var_dump($color_codes);
?>
//运行结果
array(3) { [0]=> string(3) "Red" [1]=> string(5) "Green" [2]=> string(4) "Blue" }
array(3) { ["Red"]=> string(7) "#ff0000" ["Green"]=> string(7) "#00ff00" ["Blue"]=> string(7) "#0000ff" }
6.对象

对象是一种数据类型,它不仅允许存储数据,而且还提供有关如何处理该数据的信息。对象是用作对象模板的类的特定实例。通过new关键字基于此模板创建对象。

每个对象都有与其父类相对应的属性和方法。每个对象实例都是完全独立的,具有自己的属性和方法,因此可以独立于同一类的其他对象进行操作。

<?php
//类定义
class greeting{
    // 属性
    public $str = "Hello World!";
    
    // 方法
    function show_greeting(){
        return $this->str;
    }
}
//从类创建对象
$message = new greeting;
var_dump($message);
echo "<br />";
echo $message->show_greeting();
?>
//运行结果
object(greeting)#1 (1) { ["str"]=> string(12) "Hello World!" }
Hello World!

**提示:**存储在对象中的数据元素被称为对象的属性和信息,或者描述如何处理数据的代码称为对象的方法。

7.NULL

特殊的NULL值用于表示PHP中的空变量。 NULL类型的变量是没有任何数据的变量。 NULL是null类型的唯一可能值。

<?php
$a = NULL;
var_dump($a);
echo "<br>";
 
$b = "Hello World!";
$b = NULL;
var_dump($b);
?>
//运行结果
NULL
NULL

如果在PHP中创建变量时没有使用 v a r 之类的值,则会自动为其赋值为 N U L L 。错误地认为 var之类的值,则会自动为其赋值为NULL。 错误地认为 var之类的值,则会自动为其赋值为NULL。错误地认为var1=null;和 v a r 2 = “”;是相同的,但事实并非如此。这两个变量是不同的: var2=“”;是相同的,但事实并非如此。 这两个变量是不同的: var2=“”;是相同的,但事实并非如此。这两个变量是不同的:var1具有空值,而$var2表示没有为其赋值。

8.资源

资源是一个特殊变量,其中包含对外部资源的引用。资源变量通常包含打开的文件和数据库连接的特殊处理程序。

<?php
// 打开要读取的文件
$handle = fopen("note.txt", "r");
if ($handle === false) {
    die("无法打开文件: " . error_get_last()['message']);
}
var_dump($handle);
echo "<br>";
// 使用mysqli连接到MySQL数据库服务器
$mysqli = new mysqli("localhost", "admin", "admin", "sky_take_out");
// 检查连接是否成功
if ($mysqli->connect_error) {
    die("数据库连接失败: " . $mysqli->connect_error);
}
var_dump($mysqli);
// 关闭资源
fclose($handle);
$mysqli->close();
?>
//输出结果
resource(5) of type (stream)
object(mysqli)#1 (18) { ["affected_rows"]=> int(0) ["client_info"]=> string(14) "mysqlnd 8.4.10" ["client_version"]=> int(80410) ["connect_errno"]=> int(0) ["connect_error"]=> NULL ["errno"]=> int(0) ["error"]=> string(0) "" ["error_list"]=> array(0) { } ["field_count"]=> int(0) ["host_info"]=> string(20) "localhost via TCP/IP" ["info"]=> NULL ["insert_id"]=> int(0) ["server_info"]=> string(6) "8.0.40" ["server_version"]=> int(80040) ["sqlstate"]=> string(5) "00000" ["protocol_version"]=> int(10) ["thread_id"]=> int(20) ["warning_count"]=> int(0) }
9. 可调用类型 (callable)

callable 表示可以被调用的结构,包括函数名、对象方法、匿名函数(闭包)等,常用于回调函数场景。

<?php
// 1. 普通函数
function add($a, $b) {
    return $a + $b;
}
$func = 'add'; // 函数名作为字符串
var_dump($func); // 验证是否为callable
echo "调用结果:" . $func(2, 3) . "<br>";

// 2. 对象方法(数组形式:[对象, 方法名])
class Math {
    public function multiply($a, $b) {
        return $a * $b;
    }
}
$math = new Math();
$method = [$math, 'multiply'];
var_dump($method);
echo "调用结果:" . $method(2, 3) . "<br>";

// 3. 匿名函数(闭包)
$subtract = function($a, $b) {
    return $a - $b;
};
var_dump($subtract);
echo "调用结果:" . $subtract(5, 2) . "<br>";
?>
// 运行结果
string(3) "add" 调用结果:5
array(2) { [0]=> object(Math)#1 (0) { } [1]=> string(8) "multiply" } 调用结果:6
object(Closure)#2 (1) { ["parameter"]=> array(2) { ["$a"]=> string(10) "<required>" ["$b"]=> string(10) "<required>" } } 调用结果:3
10. 迭代器类型 (iterable)

iterable 表示可遍历的结构(数组或实现Traversable接口的对象),主要用于函数参数或返回值声明,确保变量可用于foreach循环。

<?php
// 1. 数组(天然可迭代)
$arr = [10, 20, 30];
function printIterable(iterable $data) {
    foreach ($data as $item) {
        echo $item . " ";
    }
}
echo "数组遍历:";
printIterable($arr);
echo "<br>";

// 2. 生成器(实现迭代器接口)
function numberGenerator() {
    yield 1;
    yield 2;
    yield 3;
}
$generator = numberGenerator();
echo "生成器遍历:";
printIterable($generator);
echo "<br>";

// 验证类型
var_dump(is_iterable($arr)); // 数组是可迭代的
var_dump(is_iterable($generator)); // 生成器是可迭代的
?>
// 运行结果
数组遍历:10 20 30 
生成器遍历:1 2 3 
bool(true)
bool(true)
11. 混合类型 (mixed)

mixed 表示变量可以是任意类型(PHP 8.0 前常用,8.0 + 推荐用联合类型替代),常用于无法确定具体类型的场景。

<?php
// 接受任意类型的参数
function debug(mixed $data) {
    echo "类型:" . gettype($data) . ",值:";
    var_dump($data);
    echo "<br>";
}

debug(123); // 整数
debug("hello"); // 字符串
debug([1, 2, 3]); // 数组
debug(null); // NULL
?>
// 运行结果
类型:integer,值:int(123)
类型:string,值:string(5) "hello"
类型:array,值:array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
类型:NULL,值:NULL
12. 数值类型 (number)

number 表示变量可以是整数(int)或浮点数(float),用于限制参数只能为数值类型。

<?php
function calculate(number $a, number $b) {
    return [
        '和' => $a + $b,
        '积' => $a * $b
    ];
}

// 整数参数
var_dump(calculate(2, 3));
echo "<br>";

// 浮点数参数
var_dump(calculate(2.5, 1.5));
echo "<br>";

// 非数值参数(会报错)
// calculate("2", 3); // 错误:参数必须是number类型
?>
// 运行结果
array(2) { ["和"]=> int(5) ["积"]=> int(6) }
array(2) { ["和"]=> float(4) ["积"]=> float(3.75) }
13. 回调类型 (callback)

callbackcallable的别名,用于兼容旧版本代码,功能与callable完全一致。

<?php
// 使用callback声明回调函数参数
function processArray(array $arr, callback $func) {
    return array_map($func, $arr);
}

// 回调函数:计算平方
function square($n) {
    return $n * $n;
}

$numbers = [1, 2, 3, 4];
$result = processArray($numbers, 'square');
var_dump($result);
?>
// 运行结果
array(4) { [0]=> int(1) [1]=> int(4) [2]=> int(9) [3]=> int(16) }

补充说明:

  • callablecallback:两者完全等效,callback是历史遗留的别名,建议优先使用callable
  • iterable的范围:包括所有数组和实现Traversable接口的对象(如生成器、ArrayObject等)。
  • mixed的替代方案:PHP 8.0+ 引入的联合类型(如int|string|null)比mixed更精确,推荐优先使用。

(9)字符串

字符串是字母,数字,特殊字符和算术值或所有元素的组合的序列。创建字符串的最简单方法是将字符串文字(即字符串字符)括在单引号(')中,如下所示:

$my_string ='世界你好';
1.’ '与" "的区别

也可以使用双引号(“)。但是,单引号和双引号的作用方式不同。用单引号括起来的字符串几乎按字面意思处理,而用双引号分隔的字符串用变量值的字符串表示形式替换变量,并专门解释某些转义序列。

转义序列替换为:

  • \n 由换行符替换
  • \r 由回车符代替
  • \t 被制表符替换
  • $ 由美元符号本身($)代替
  • " 用一个双引号(")代替
  • \ 由单个反斜杠(\)代替

这是一个示例说明单引号和双引号字符串之间的区别:

<?php
$my_str = 'World';
echo "Hello, $my_str!<br>";      // 显示: Hello, World!
echo 'Hello, $my_str!<br>';      // 显示: Hello, $my_str!
 
echo '<pre>Hello\tWorld!</pre>'; // 显示: Hello\tWorld!
echo "<pre>Hello\tWorld!</pre>"; // 显示: Hello   World!
echo 'I\'ll be back';            // 显示: I'll be back
?>
2.操作字符串的函数

PHP提供了许多用于处理字符串的内置函数。

序号函数描述示例代码输出结果
1addcslashes()返回在指定的字符前添加反斜杠的字符串。echo addcslashes('foo[]', 'A..z');\f\o\o\[ \]
2addslashes()返回在预定义的字符前添加反斜杠的字符串。$str = "Is your name O'Reilly?";<br/><br/>// Outputs:<br/>echo addslashes($str);I\'m a PHP developer!
3bin2hex()把 ASCII 字符的字符串转换为十六进制值。echo bin2hex('Hello');48656c6c6f
4chop()移除字符串右侧的空白字符或其他字符(rtrim() 的别名)。echo chop(' Hello ');Hello
5chr()从指定 ASCII 值返回字符。echo chr(65);A
6chunk_split()把字符串分割为一连串更小的部分。`echo chunk_split(‘abcdef’, 2, ’');`
7convert_cyr_string()把字符串由一种 Cyrillic 字符集转换成另一种。echo convert_cyr_string('Привет', 'w', 'i');ÐðÑет(示例结果)
8convert_uudecode()对 uuencode 编码的字符串进行解码。echo convert_uudecode("+22!L;W9E(%!(4\"$\n");I love PHP!
9count_chars()用于返回有关字符串中使用的字符的信息。print_r(count_chars('Hello', 1));Array ( [72] => 1 [101] => 1 [108] => 2 [111] => 1 )
10crc32()计算一个字符串的 32 位 CRC(循环冗余校验)。echo crc32('Hello');1579032032
11crypt()用于哈希字符串(单向加密)。echo crypt('password', '$2y$10$saltsaltsaltsalt$');$2y$10$saltsaltsaltsalt$...(哈希结果,省略部分)
12echo()输出一个或多个字符串。echo 'Hello', ' ', 'World!';Hello World!
13explode()按指定字符分割字符串并组成数组。print_r(explode(' ', 'Hello World'));Array ( [0] => Hello [1] => World )
14fprintf()用于将格式化的字符串写入流。fprintf(STDOUT, "Number: %d\n", 42);Number: 42
15get_html_translation_table()返回 htmlspecialchars()htmlentities() 使用的转换表。print_r(get_html_translation_table());Array ( [34] => " ... )(双引号对应实体为 "
16hebrev()把希伯来 (Hebrew) 文本转换为可见文本。echo hebrev('שלום');םלוּש
17hebrevc()把希伯来 (Hebrew) 文本转换为可见文本,并把新行(\n)转换为 <br>echo hebrevc("שלום\nעולם");םלוּש<br>םלוע
18hex2bin()用于将十六进制字符串转换为 ASCII 字符。echo hex2bin('48656c6c6f');Hello
19html_entity_decode()用于把 HTML 实体转换为字符。echo html_entity_decode('<b>Hello</b>');<b>Hello</b>
20htmlentities()用于把字符转换为 HTML 实体。echo htmlentities('<b>Hello</b>');<b>Hello</b>(转换为实体)
21htmlspecialchars_decode()把一些预定义的 HTML 实体转换为字符。echo htmlspecialchars_decode('<b>Hello</b>');<b>Hello</b>(解码实体为原始字符)
22htmlspecialchars()把一些预定义的字符转换为 HTML 实体。echo htmlspecialchars('<b>Hello</b>');<b>Hello</b>(转换为实体)
23implode()通过字符串连接数组元素。echo implode(', ', ['apple', 'banana', 'cherry']);apple, banana, cherry
24join()implode() 的别名,从数组的元素中返回字符串。echo join(', ', ['apple', 'banana', 'cherry']);apple, banana, cherry
25lcfirst()把字符串中的首字符转换为小写。echo lcfirst('Hello');hello
26levenshtein()返回两个字符串之间的 Levenshtein 距离。echo levenshtein('kitten', 'sitting');3
27localeconv()返回本地数字及货币格式信息。print_r(localeconv());Array ( [decimal_point] => . ... )
28ltrim()从字符串开头去除空格或其他字符。echo ltrim(' Hello');Hello
29md5_file()用于计算给定文件的 md5 散列。echo md5_file('example.txt');e10adc3949ba59abbe56e057f20f883e(示例哈希值)
30md5()用于计算字符串的 md5 散列。echo md5('password');5f4dcc3b5aa765d61d8327deb882cf99(固定哈希值)
31metaphone()计算字符串的 metaphone 键。echo metaphone('Christopher', 5);KRSTF
32money_format()用于将数字格式化为货币字符串。setlocale(LC_MONETARY, 'en_US'); echo money_format('%.2n', 1234.56);$1,234.56
33nl_langinfo()包含有关语言和语言环境的信息。echo nl_langinfo(CODESET);UTF-8(示例结果)
34nl2br()在字符串中的每个新行之前插入 HTML 换行符。echo nl2br('Hello\nWorld');Hello<br>World
35number_format()通过千位分组来格式化数字。echo number_format(1234567.89, 2);1,234,567.89
36ord()返回字符串中第一个字符的 ASCII 值。echo ord('A');65
37parse_str()用于将字符串解析为变量。parse_str('name=John&age=30', $output); print_r($output);Array ( [name] => John [age] => 30 )
38print()输出字符串。print 'Hello World!';Hello World!
39printf()输出格式化的字符串。printf("Hello %s, you are %d years old.", "John", 30);Hello John, you are 30 years old.
40mb_substr()截取字符串中指定长度字符(支持多字节字符)。echo mb_substr('你好世界', 0, 2, 'UTF-8');你好
41quoted_printable_decode()用于将带引号的可打印字符串转换为 8 位字符串。echo quoted_printable_decode('Hello=20World=21');Hello World!
42quoted_printable_encode()用于将 8 位字符串转换为带引号的可打印字符串。echo quoted_printable_encode('Hello World!');Hello=20World=21
43quotemeta()用于引用元字符。echo quotemeta('Hello+World*.txt');Hello\+World\*\.\txt
44rtrim()移除字符串右侧的空白字符或其他字符。echo rtrim('Hello ');Hello
45setlocale()用于设置地区信息。echo setlocale(LC_TIME, 'fr_FR');fr_FR(成功设置时返回地区值)
46sha1_file()计算文件的 SHA-1 散列。echo sha1_file('example.txt');a94a8fe5ccb19ba61c4c0873d391e987982fbbd(示例哈希值)
47sha1()计算字符串的 SHA-1 散列。echo sha1('password');5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8(固定哈希值)
48similar_text()用于计算两个字符串之间的相似度。echo similar_text('Hello', 'Hallo');4(相同字符数)
49soundex()计算字符串的 soundex 键。echo soundex('Smith');S530
50sprintf()用于格式化字符串。echo sprintf("Hello %s, you are %d years old.", "John", 30);Hello John, you are 30 years old.
51str_getcsv()用于解析将 CSV 字符串解析为数组。print_r(str_getcsv('apple,banana,"cherry,grape"'));Array ( [0] => apple [1] => banana [2] => cherry,grape )
52str_ireplace()替换字符串中的一些字符(不区分大小写)。echo str_ireplace('world', 'PHP', 'Hello World!');Hello PHP!
53str_pad()用于将字符串填充到新长度。echo str_pad('Hello', 10, '-', STR_PAD_BOTH);--Hello---
54str_repeat()用于字符串重复指定的次数。echo str_repeat('Hello', 3);HelloHelloHello
55str_replace()替换字符串中的一些字符(区分大小写)。echo str_replace('world', 'PHP', 'Hello world!');Hello PHP!
56str_rot13()对字符串执行 ROT13 编码。echo str_rot13('Hello');Uryyb
57str_shuffle()随机地打乱字符串中的所有字符。echo str_shuffle('Hello');lleoH(随机结果)
58str_split()把字符串分割为数组。print_r(str_split('Hello', 2));Array ( [0] => He [1] => ll [2] => o )
59str_word_count()计算字符串中的单词数。echo str_word_count('Hello world!');2
60strcasecmp()用于比较两个字符串(不区分大小写)。echo strcasecmp('Hello', 'hello');0
61strchr()查找字符串在另一字符串中的第一次出现。(strstr() 的别名。)echo strchr('Hello', 'e');ello
62strcmp()比较两个字符串(区分大小写)。echo strcmp('Hello', 'hello');-32
63strcoll()比较两个字符串(根据本地设置)。setlocale(LC_COLLATE, 'en_US'); echo strcoll('apple', 'banana');-1(可能因环境而异)
64strcspn()返回在找到任何指定的字符之前,在字符串查找的字符数。echo strcspn('Hello', 'aeiou');1
65strip_tags()删除字符串中的 HTML 和 PHP 标签。echo strip_tags('<b>Hello</b>');Hello
66stripcslashes()删除由 addcslashes() 函数添加的反斜杠。echo stripcslashes('foo\[bar\]');foo[bar]
67stripos()用于查找一个字符串在另一个字符串中首次出现的位置(不区分大小写)。echo stripos('Hello', 'e');1
68stripslashes()删除由 addslashes() 函数添加的反斜杠。echo stripslashes('I\'m a PHP developer!');I'm a PHP developer!
69stristr()返回字符串在另一字符串中第一次出现的位置(不区分大小写)。echo stristr('Hello', 'e');ello
70strlen()用于获取字符串长度。echo strlen('Hello');5
71strnatcasecmp()使用一种 “自然排序” 算法来比较两个字符串(不区分大小写)。echo strnatcasecmp('file10', 'file2');1
72strnatcmp()使用一种 “自然排序” 算法来比较两个字符串(区分大小写)。echo strnatcmp('file10', 'file2');1
73strncasecmp()前 n 个字符的字符串比较(不区分大小写)。echo strncasecmp('Hello', 'hello', 3);0
74strncmp()前 n 个字符的字符串比较(区分大小写)。echo strncmp('Hello', 'hello', 3);-32
75strpbrk()在字符串中搜索指定字符中的任意一个。echo strpbrk('Hello', 'aeiou');ello
76strpos()用于查找一个字符串在另一个字符串中首次出现的位置(区分大小写)。echo strpos('Hello', 'e');1
77strrchr()用于查找字符串中字符的最后一次出现。echo strrchr('Hello', 'l');lo
78strrev()用于反转字符串。echo strrev('Hello');olleH
79strripos()查找字符串在另一字符串中最后一次出现的位置(不区分大小写)。echo strripos('Hello', 'l');3
80strspn()返回在字符串中包含的特定字符的数目。echo strspn('Hello', 'H');1
81strstr()查找字符串在另一字符串中的第一次出现(区分大小写)。echo strstr('Hello', 'e');ello
82strtok()把字符串分割为更小的字符串。$str = 'Hello World!'; $token = strtok($str, ' '); echo $token;Hello
83strtolower()把字符串转换为小写字母。echo strtolower('HELLO');hello
84strtoupper()把字符串转换为大写字母。echo strtoupper('hello');HELLO
85strtr()转换字符串中特定的字符。echo strtr('Hello', 'el', 'ip');Hippo
86substr_compare()用于比较两个字符串格式与特定的开始位置。echo substr_compare('Hello', 'lo', -2);0
87substr_count()用来计算子字符串的数量。echo substr_count('Hello', 'l');2
88substr_replace()把字符串的一部分替换为另一个字符串。echo substr_replace('Hello', 'PHP', 0, 3);PHPlo
89substr()用来返回字符串的一部分。echo substr('Hello', 1, 3);ell
90trim()用来移除字符串两侧的空白字符和其他字符。echo trim(' Hello ');Hello
91ucfirst()用于将字符串的第一个字符转换为大写。echo ucfirst('hello');Hello
92ucwords()把字符串中每个单词的首字符转换为大写。echo ucwords('hello world');Hello World
93vfprintf()把格式化的字符串写到指定的输出流。vfprintf(STDOUT, "Number: %d\n", [42]);Number: 42
94vprintf()输出格式化的字符串。vprintf("Number: %d\n", [42]);Number: 42
95vsprintf()返回格式化的字符串。echo vsprintf("Number: %d\n", [42]);Number: 42
96wordwrap()按照指定长度对字符串进行换行处理。echo wordwrap('Hello World!', 5, '\n');Hello\nWorld!
97convert_uuencode()使用 uuencode 编码一个字符串。echo convert_uuencode('Hello, World!');+22!L;W9E(%!(4\"$=

(10)运算符

1. 算术运算符
运算符描述在线示例结果
+加法$x + $y和y 的总和
-减法$x - $y和y 之差
*乘法$x * $y和y 的乘积
/除法$x / $y和y 的商
%求模$x % $y除以y 的余数
**幂运算$x ** $y的y 次幂(PHP 5.6+)
<?php
$x = 10;
$y = 4;
echo($x + $y) . "<br>"; // 输出: 14
echo($x - $y) . "<br>"; // 输出: 6
echo($x * $y) . "<br>"; // 输出: 40
echo($x / $y) . "<br>"; // 输出: 2.5
echo($x % $y) . "<br>"; // 输出: 2
echo($x ** $y) . "<br>"; // 输出: 10000(PHP 5.6+)
?>
2. 赋值运算符
运算符描述在线示例等同于
=赋值$x = $y$x = $y
+=相加赋值$x += $y$x = $x + $y
-=相减赋值$x -= $y$x = $x - $y
*=相乘赋值$x *= $y$x = $x * $y
/=相除赋值$x /= $y$x = $x / $y
%=模赋值(余数)$x %= $y$x = $x % $y
.=字符串连接赋值$x .= $y$x = $x.$y
??=空合并赋值(PHP 7.4+)$x ??= $y$x = $x ?? $y(仅当 $x 为 null 时赋值)
<?php
$x = 25;
$y = 35;
$z = "25";
$nullable = null;

var_dump($x == $z) . "<br>";  // 输出: 布尔值 true
var_dump($x === $z) . "<br>"; // 输出: 布尔值 false
var_dump($x != $y) . "<br>";  // 输出: 布尔值 true
var_dump($x !== $z) . "<br>"; // 输出: 布尔值 true
var_dump($x < $y) . "<br>";   // 输出: 布尔值 true
var_dump($x > $y) . "<br>";   // 输出: 布尔值 false
var_dump($x <= $y) . "<br>";  // 输出: 布尔值 true
var_dump($x >= $y) . "<br>";  // 输出: 布尔值 false

// 空合并赋值示例
$nullable ??= 'default';
echo $nullable; // 输出:default
?>
3. 递增 / 递减运算符
运算符名称描述
++$x预增量将加,然后返回x
$x++后增量返回,然后将x 加 1
–$x预减量将减,然后返回x
$x–后减量返回,然后将x 减 1
<?php
$x = 10;
echo ++$x . "<br>"; // 输出: 11
echo $x . "<br>";   // 输出: 11
 
$x = 10;
echo $x++ . "<br>"; // 输出: 10
echo $x . "<br>";   // 输出: 11
 
$x = 10;
echo --$x . "<br>"; // 输出: 9
echo $x . "<br>";   // 输出: 9
 
$x = 10;
echo $x-- . "<br>"; // 输出: 10
echo $x . "<br>";   // 输出: 9
?>
4. 逻辑运算符
运算符名称在线示例结果
and$x and $y如果和y 都为 true,则为 true
or$x or $y如果或y 为 true,则为 true
xor异或$x xor $y如果或y 为 true,但不同时为 true,则为 true
&&$x && $y如果和y 都为 true,则为 true
||$x || $y如果或y 为 true,则为 true
!!$x如果 $x 不为 true,则为 true
<?php
$year = 2024;
// 闰年判断:能被400整除,或能被4整除但不能被100整除
if(($year % 400 == 0) || (($year % 100 != 0) && ($year % 4 == 0))){
    echo "$year 是闰年。";
} else{
    echo "$year 不是闰年。";
}
?>
5. 字符串运算符
运算符描述在线示例结果
.字符串连接$str1 . $str2和str2 的连接结果
.=连接赋值$str1 .= $str2将追加到str1
<?php
$x = "Hello";
$y = " World!";
echo $x . $y . "<br>"; // 输出: Hello World!
 
$x .= $y;
echo $x . "<br>"; // 输出: Hello World!
?>
6. 数组运算符
运算符名称在线示例结果
+联合$x + $y和y 的联合(相同键名时保留 $x 的元素)
==相等$x == $y如果和y 具有相同的键 / 值对,则为 true
===全等$x === $y如果和y 具有相同顺序和相同类型的相同键 / 值对,则为 true
!=不相等$x != $y如果不等于y,则为 true
<>不相等$x <> $y如果不等于y,则为 true
!==不全等$x !== $y如果与y 不相同则为 true
<?php
$x = array("a" => "Red", "b" => "Green");
$y = array("b" => "Blue", "c" => "Yellow");
$z = $x + $y; // 联合操作,相同键名时保留$x的元素

print_r($z); // 输出:Array ( [a] => Red [b] => Green [c] => Yellow )
var_dump($x == $y);   // 输出:bool(false)
var_dump($x === $y);  // 输出:bool(false)
var_dump($x != $y);   // 输出:bool(true)
var_dump($x <> $y);   // 输出:bool(true)
var_dump($x !== $y);  // 输出:bool(true)
?>
7. 类型运算符
运算符名称描述示例
instanceof类型检查检查对象是否属于特定类或接口$obj instanceof MyClass
::class类名获取(PHP 5.5+)获取类的完全限定名称MyClass::class 返回 “MyClass”
<?php
class MyClass {}
$obj = new MyClass();

var_dump($obj instanceof MyClass); // 输出:bool(true)
echo MyClass::class; // 输出:MyClass
?>
8. 三元运算符
语法描述
$a ? $b : $c如果为,返回b,否则返回 $c
$a ?: $b简写形式(PHP 5.3+):如果存在且不为,返回a,否则返回 $b
$a ?= $b条件赋值(PHP 8.4+):如果为或,赋值b 并返回 $b
<?php
$age = 20;
$status = ($age >= 18) ? "成年人" : "未成年人";
echo $status; // 输出:成年人

// 简写形式
$name = "";
$displayName = $name ?: "游客";
echo $displayName; // 输出:游客

// 条件赋值
$email = null;
$email ?= "default@example.com";
echo $email; // 输出:default@example.com
?>
9. 错误控制运算符
运算符名称描述
@错误抑制符抑制表达式产生的错误信息
<?php
// 尝试打开不存在的文件,抑制错误信息
$file = @fopen("nonexistent.txt", "r");
if (!$file) {
    echo "文件打开失败,但没有错误信息输出";
}
?>
10. 执行运算符
运算符名称描述
...反引号执行系统命令
<?php
// 获取当前目录下的文件列表(仅在支持shell的环境中有效)
$output = `ls -l`;
echo "<pre>$output</pre>";
?>
11. 太空船运算符(<=>)

PHP 7引入了一个新的太空船运算符(<=>),可用于比较两个表达式。也称为组合比较运算符。$a <=> $b 若a<b 返回 - 1,若a==b 返回 0,若a>b 返回 1。 基本提供三向对比,如下表所示:

运算符<=> 相当于
$x < $y($x <=> $y) === -1
$x <= $y`($x <=> $y) === -1
$x == $y($x <=> $y) === 0
$x != $y($x <=> $y) !== 0
$x >= $y`($x <=> $y) === 1
$x > $y($x <=> $y) === 1
<?php
// 比较整数
echo 1 <=> 1; // 输出: 0
echo 1 <=> 2; // 输出: -1
echo 2 <=> 1; // 输出: 1
 
// 比较浮点数
echo 1.5 <=> 1.5; // 输出: 0
echo 1.5 <=> 2.5; // 输出: -1
echo 2.5 <=> 1.5; // 输出: 1
 
// 比较字符串
echo "x" <=> "x"; // 输出: 0
echo "x" <=> "y"; // 输出: -1
echo "y" <=> "x"; // 输出: 1
?>
12. 其他运算符
运算符名称描述示例
match模式匹配(PHP 8.0+)更强大的条件表达式$result = match ($x) { 1 => 'one', 2 => 'two' };
展开运算符(PHP 5.6+)展开数组或参数列表$arr = [...$arr1, ...$arr2];
?->空安全调用(PHP 8.0+)避免空值引发错误$obj?->method();
<?php
// match表达式
$day = 3;
$name = match ($day) {
    1 => 'Monday',
    2 => 'Tuesday',
    3 => 'Wednesday',
    default => 'Unknown'
};
echo $name; // 输出:Wednesday

// 展开运算符
$arr1 = [1, 2];
$arr2 = [...$arr1, 3, 4];
print_r($arr2); // 输出:[1, 2, 3, 4]

// 空安全调用
$obj = null;
echo $obj?->property; // 不报错,返回null
?>

(11)条件语句

1.if 语句

仅当指定条件的值为true时,if语句才用于执行代码块。这是最简单的PHP条件语句,可以这样写:

if(condition){ 
    //要执行的代码
}
<?php
$d = date("D");
if($d == "Fri"){
    echo "周末愉快!";
}
?>
//如果当前日期是星期五,则将输出“周末愉快!”
2.if…else 语句
if(condition){
    //条件为true时执行的代码
 } else {
    //条件为false时执行的代码
}
<?php
$d = date("D");
if($d == "Fri"){
    echo "周末愉快!";
} else{
    echo "祝您愉快!";
}
?>
// 如果当前日期是星期五,则将输出“周末愉快!否则输出“祝您愉快!”
3.if…elseif…else 语句

if … elseif … else特殊语句,用于组合多个if … else语句。

if(condition1){
    //如果condition1为true时将执行的代码
} elseif(condition2){
    //如果condition1为false且condition2为true时将执行的代码
} else {
    //如果condition1和condition2都将执行的代码是错误的
}
<?php
$d = date("D");
if($d == "Fri"){
    echo "周末愉快!";
} elseif($d == "Sun"){
    echo "祝您星期日愉快!";
} else{
    echo "祝您愉快!";
}
?>
//如果当前日期是星期五,并且“祝您星期日愉快!” 如果当前日期是星期天,否则将输出“祝您愉快!”
4.switch…case

switch-case语句是if-elseif-else语句的代替方法,它执行几乎相同的操作。 switch-case语句针对一系列值测试变量,直到找到匹配项,然后执行与该匹配项对应的代码块。

switch(n){
    case label1:
        // 要执行的代码,当 n=label1
        break;
    case label2:
        // 要执行的代码,当 n=label2
        break;
    ...
    default:
        // 要执行的代码,当n与所有标签都不匹配
}

看以下示例,示例每天显示不同的消息。

<?php
$today = date("D");
switch($today){
    case "Mon":
        echo "今天是星期一。 打扫你的房子。";
        break;
    case "Tue":
        echo "今天是星期二。 买一些食物。";
        break;
    case "Wed":
        echo "今天是星期三。 去看医生。";
        break;
    case "Thu":
        echo "今天是星期四。 修理你的车。";
        break;
    case "Fri":
        echo "今天是星期五。 今夜开派对。";
        break;
    case "Sat":
        echo "今天是星期六。是看电影的时间。";
        break;
    case "Sun":
        echo "今天是星期天。休息一下。";
        break;
    default:
        echo "当天没有可用信息。";
        break;
}
?>

switch-case语句与if-elseif-else语句的不同之处在于一个重要方面。 switch语句逐行执行(即逐条语句),一旦PHP找到一个条件表达式为true的case语句,它不仅执行与case语句相对应的代码,而且还将执行所有后续case语句,直到该语句结束为止。 会自动切换switch的块。为了防止这种情况,请在每个case块的末尾添加一个break语句。 break语句告诉PHP一旦执行了与第一个真实case相关的代码,便跳出switch-case语句块。

(12)数组

您可以创建三种类型的数组。这些是:

  • 索引数组 — 具有数字键的数组。
  • 关联数组 — 每个键都有其特定值的数组。
  • 多维数组 — 本身包含一个或多个数组的数组。
1.索引数组

索引数组或数字数组存储每个具有数字索引的数组元素。以下示例显示了创建索引数组的两种方法,最简单的方法是:

<?php
//定义一个索引数组
$colors = array("Red", "Green", "Blue");
// 打印数组结构
print_r($colors);
?>

**注意:**在索引或数字数组中,将自动分配索引并从0开始,并且值可以是任何数据类型。

这等效于以下示例,其中手动分配了索引:

<?php
$colors[0] = "Red"; 
$colors[1] = "Green"; 
$colors[2] = "Blue"; 
// 打印数组结构
print_r($colors); 
?>
2.关联数组

在关联数组中,分配给值的键可以是任意的和用户定义的字符串。在以下示例中,数组使用键而不是索引号:

<?php
//定义一个关联数组
$ages = array("Peter"=>22, "Clark"=>32, "John"=>28);
// 打印数组结构
print_r($ages ); 
?>

下面的示例与前面的示例等效,但是显示了创建关联数组的另一种方式:

<?php
$ages["Peter"] = "22";
$ages["Clark"] = "32";
$ages["John"] = "28";
// 打印数组结构
print_r($ages );
?>
3.多维数组

多维数组是一个数组,其中每个元素也可以是一个数组,子数组中的每个元素可以是一个数组,或者进一步在其内部包含数组,依此类推。多维数组的示例如下所示:

<?php
//定义多维数组
$contacts = array(
    array(
        "name" => "Peter Parker",
        "email" => "peterparker@mail.com",
    ),
    array(
        "name" => "Clark Kent",
        "email" => "clarkkent@mail.com",
    ),
    array(
        "name" => "Harry Potter",
        "email" => "harrypotter@mail.com",
    )
);
//访问嵌套值
echo "彼得.帕克的电子邮件 id 是: " . $contacts[0]["email"];
?>
4.查看数组的结构和值

可以使用两个语句 var_dump()print_r() 之一,查看任何数组的结构和值。但是print_r()语句提供的信息稍少一些。看以下示例:

<?php
//定义数组
$cities = array("London", "Paris", "New York");
//显示城市数组
print_r($cities);
?>

print_r() 语句提供以下输出:

Array ( [0] => London [1] => Paris [2] => New York )

此输出显示数组中每个元素的键和值。要获取更多信息,请使用以下语句:

<?php
//定义数组
$cities = array("London", "Paris", "New York");
//显示城市数组
var_dump($cities);
?>

var_dump()语句提供以下输出:

array(3) { [0]=> string(6) "London" [1]=> string(5) "Paris" [2]=> string(8) "New York" }

除了键和值,此输出还显示每个元素的数据类型,例如6个字符的字符。

5.函数对数组进行排序

PHP附带了许多内置函数,这些函数专门设计用于以不同的方式对数组元素进行排序,例如按字母或数字的升序或降序。在这里,我们将探讨一些最常用于数组排序的函数。

  • sort() 和 rsort() — 对索引数组进行排序
  • asort() 和 arsort() — 用于按值对关联数组进行排序
  • ksort() 和 krsort() — 用于按键对关联数组进行排序
a.升序排序索引数组

sort()函数用于按升序对索引数组的元素进行排序(字母按字母顺序,数字按数字)。

<?php
//定义数组
$colors = array("Red", "Green", "Blue", "Yellow");
//排序和打印数组
sort($colors);
print_r($colors);
?>

print_r() 语句提供以下输出:

 Array ( [0] => Blue [1] => Green [2] => Red [3] => Yellow )

同样,可以按升序对数组的数字元素进行排序。

<?php
//定义数组
$numbers = array(1, 2, 2.5, 4, 7, 10);
 
//排序和打印数组
sort($numbers);
print_r($numbers);
?>

print_r() 语句提供以下输出:

Array ( [0] => 1 [1] => 2 [2] => 2.5 [3] => 4 [4] => 7 [5] => 10 )
b.按降序对索引数组排序

rsort()函数用于按降序对索引数组的元素进行排序(字母顺序按字母,数字顺序按数字)。

<?php
//定义数组
$colors = array("Red", "Green", "Blue", "Yellow");
 
// 排序和打印数组
rsort($colors);
print_r($colors);
?>

print_r() 语句提供以下输出:

Array ( [0] => Yellow [1] => Red [2] => Green [3] => Blue )

同样,您可以按降序对数组的数字元素进行排序。

<?php
//定义数组
$numbers = array(1, 2, 2.5, 4, 7, 10);
 
//排序和打印数组
rsort($numbers);
print_r($numbers);
?>

print_r() 语句提供以下输出:

Array ( [0] => 10 [1] => 7 [2] => 4 [3] => 2.5 [4] => 2 [5] => 1 )
c.按值升序对关联数组进行排序

asort()函数根据按升序对关联数组的元素进行排序。 它的工作方式类似于sort(),但在排序时保留了键及其值之间的关联。

<?php
//定义数组
$age = array("Peter"=>20, "Harry"=>14, "John"=>45, "Clark"=>35);
 
//按值对数组排序并打印
asort($age);
print_r($age);
?>

print_r() 语句提供以下输出:

Array ( [Harry] => 14 [Peter] => 20 [Clark] => 35 [John] => 45 )
d.按值降序对关联数组进行排序

arsort()函数根据该以降序对关联数组的元素进行排序。 它的工作方式与rsort()相似,但是在排序时会保留键及其值之间的关联。

<?php
//定义数组
$age = array("Peter"=>20, "Harry"=>14, "John"=>45, "Clark"=>35);
 
//按值对数组排序并打印
arsort($age);
print_r($age);
?>

print_r() 语句提供以下输出:

Array ( [John] => 45 [Clark] => 35 [Peter] => 20 [Harry] => 14 )
e.按键升序对关联数组进行排序

ksort()函数按的升序对关联数组的元素进行排序。与asort()函数相同,它在排序时保留键及其值之间的关联。

<?php
//定义数组
$age = array("Peter"=>20, "Harry"=>14, "John"=>45, "Clark"=>35);
 
//按键排序数组并打印
ksort($age);
print_r($age);
?>

print_r() 语句提供以下输出:

Array ( [Clark] => 35 [Harry] => 14 [John] => 45 [Peter] => 20 )
f.按键降序对关联数组进行排序

ksort()函数通过键对其升序对关联数组的元素进行排序。 与asort()函数相同,它在排序时保留键及其值之间的关联。

<?php
//定义数组
$age = array("Peter"=>20, "Harry"=>14, "John"=>45, "Clark"=>35);
 
//按键排序数组并打印
krsort($age);
print_r($age);
?>

print_r()语句提供以下输出:

Array ( [Peter] => 20 [John] => 45 [Harry] => 14 [Clark] => 35 )

(13)循环体

PHP支持四种不同类型的循环。

  • while — 只要指定的条件求值为true,就循环遍历代码块。
  • do…while — 执行一次代码块,然后评估条件。如果条件为true,则只要指定条件为true,就重复该语句。
  • for — 遍历代码块,直到计数器达到指定的数字。
  • foreach遍历数组中每个元素的代码块。
1.while循环

while只要while语句中指定的条件评估为true,该语句将循环遍历代码块。

while(条件){ 
    //要执行的代码
}

以下示例定义了一个以 i = 1 开头的循环。只要 i=1开头的循环。只要 i=1开头的循环。只要i小于或等于3 ,循环将继续运行。每次循环运行,循环将$i增加1:

<?php
$i = 1;
while($i <= 3){
    $i++;
    echo "这个数字是 " . $i . "<br>";
}
?>
//输出
这个数字是 2
这个数字是 3
这个数字是 4
2.do…while 循环

do-while 循环是while循环的一种变体,它在每次循环迭代结束时评估条件。 通过do-while循环,代码块执行一次,然后对条件进行评估,如果条件为true,则只要指定的条件评估为true,就重复该语句。

do {
    //要执行的代码
}
while(条件);

下面的示例定义了一个以 i = 1 开始的循环。然后它将 i=1开始的循环。然后它将 i=1开始的循环。然后它将i加1,并打印输出。 然后计算条件,只要$i小于或等于3,循环就会继续运行。

<?php
$i = 1;
do{
    $i++;
    echo "这个数字是 " . $i . "<br>";
}
while($i <= 3);
?>
//输出
这个数字是 2
这个数字是 3
这个数字是 4

while 和 do…while 循环之间的区别

​ while 循环与do-while 循环有一个重要的不同之处:while循环在每次循环迭代的开始测试要评估的条件,因此,如果条件表达式的计算结果为false,则永远不会执行该循环 。另一方面,对于do-while循环,即使条件表达式为false,该循环也将始终执行一次,因为条件是在循环迭代的末尾而不是开始时求值的。

3.for 循环

for 只要满足特定条件,循环就会重复执行一段代码。它通常用于执行代码块一定次数。

for(initialization;condition;increment){ 
    //要执行的代码
}

for循环的参数具有以下含义:

  • initialization — 它用于初始化计数器变量,并在第一次执行循环体之前无条件地计算一次。
  • condition — 在每次迭代的开始,条件被评估。如果计算结果为true,则继续循环并执行嵌套语句。如果计算结果为false,则循环的执行结束。
  • increment — 它用新值更新循环计数器。它在每次迭代结束时进行计算。

下面的示例定义了一个以 i = 1 开始的循环。该循环将一直持续到 i=1开始的循环。该循环将一直持续到 i=1开始的循环。该循环将一直持续到i小于或等于3。每次循环运行时,变量$i都会递增1:

<?php
for($i=1; $i<=3; $i++){
    echo "这个数字是 " . $i . "<br>";
}
?>
4.foreach 循环

foreach循环用于遍历数组。

foreach($array as $value){ 
    //要执行的代码
}

下面的示例演示一个循环,该循环将打印给定数组的值:

<?php
$colors = array("Red", "Green", "Blue");
 
//遍历颜色数组
foreach($colors as $value){
    echo $value . "<br>";
}
?>
//运行结果
Red
Green
Blue

foreach 循环还有另外一种语法,它是第一种的扩展。

foreach($array as $key => $value){ 
    //要执行的代码
}
<?php
$superhero = array(
    "name" => "Peter Parker",
    "email" => "peterparker@mail.com",
    "age" => 18
);
 
//遍历$superhero数组
foreach($superhero as $key => $value){
    echo $key . " : " . $value . "<br>";
}
?>
//运行结果
name : Peter Parker
email : peterparker@mail.com
age : 18

(14)函数

1.PHP 内置函数

函数是执行特定任务的独立代码块。PHP有一个巨大的集合内置函数,你可以在你的PHP脚本中直接调用执行特定的任务,如:gettype(),print_r(),var_dump等。官方文档

2.PHP 用户定义的函数

除了内置函数,PHP还允许定义自己的函数。这是创建执行特定任务的可重用代码包的一种方法,并且可以与主程序分开保存和维护。以下是使用函数的一些优点:

  • 函数减少了程序中代码的重复 - 函数允许您将常用的代码块提取到单个组件中。现在,您可以通过在脚本中的任何位置调用此函数来执行相同的任务,而不必反复复制和粘贴相同的代码块。
  • 函数使代码的维护更加容易 - 由于一次创建函数可以多次使用,因此在函数内部进行的任何更改都会在所有位置自动实现,而无需修改多个文件。
  • 通过函数可以更轻松地消除错误 - 将程序细分为函数时,如果发生任何错误,您将确切知道是哪个函数导致了错误以及在哪里可以找到它。因此,修复错误变得容易得多。
  • 可以在其他应用程序中重用功能 - 由于函数与脚本的其余部分是分开的,因此仅通过包含包含这些函数的php文件,就可以在其他应用程序中轻松重复使用相同的功能。
3.创建和调用函数

创建自定义函数的基本语法可以给出:

function functionName(){ 
    //要执行的代码
}

用户定义函数的声明以单词function开头,后跟要创建的函数的名称,再后跟括号,即(),最后将函数的代码放在大括号之间{ }。这是一个用户定义函数的简单示例,其中显示了今天的日期:

<?php
//定义函数
function whatIsToday(){
    echo "Today is " . date('l', mktime());
}
//调用函数
whatIsToday();
?>

**注意:**函数名称必须以字母或下划线字符开头,而不以数字开头,还可以选择后面跟有更多字母,数字或下划线字符。函数名称不区分大小写。

4.带参数的函数

在定义函数以在运行时接受输入值时指定参数。 参数的工作方式类似于函数中的占位符变量;它们在运行时被调用时提供给函数的值(称为参数)替换。

function myFunc($oneParameter,$anotherParameter){ 
    //要执行的代码
}

您可以根据需要定义任意多个参数。

<?php
//定义函数
function getSum($num1, $num2){
  $sum = $num1 + $num2;
  echo "两个数字$num1和$num2的和是 : $sum";
}
 
//调用函数
getSum(10, 20);
?>

上面代码的输出将是:

两个数字10和20的和是 : 30

**提示:**参数是您传递给函数的值,参数是函数中接收参数的变量。但是,在通常用法中,这些术语是可以互换的,即参数是自变量。

5.具有可选参数和默认值的函数

也可以创建带有可选参数的函数 - 只需插入参数名称,后跟等号(=),然后是默认值,如下所示。

<?php
//定义函数
function customFont($font, $size=1.5){
    echo "<p style=\"font-family: $font; font-size: {$size}em;\">Hello, world!</p>";
}
 
//调用函数
customFont("Arial", 2);
customFont("Times", 3);
customFont("Courier");
?>

正如您可以看到的,对 customFont ()的第三个调用不包括第二个参数。这将导致 PHP 引擎使用 $size 参数的默认值,即1.5。

6.从函数返回值

函数可以使用return语句将值返回给调用该函数的脚本。该值可以是任何类型,包括数组和对象。

<?php
//定义函数
function getSum($num1, $num2){
    $total = $num1 + $num2;
    return $total;
}
 
//打印返回值
echo getSum(5, 10); // 输出: 15
?>

一个函数不能返回多个值。但是,您可以通过返回一个数组来获得类似的结果,如以下示例所示。

<?php
//定义函数
function divideNumbers($dividend, $divisor){
    $quotient = $dividend / $divisor;
    $array = array($dividend, $divisor, $quotient);
    return $array;
}
 
//将变量作为数组进行赋值
list($dividend, $divisor, $quotient) = divideNumbers(10, 2);
echo $dividend;  // 输出: 10
echo $divisor;   // 输出: 2
echo $quotient;  // 输出: 5
?>
7.通过引用将参数传递给函数

在PHP中,有两种方式可以将参数传递给函数:按值传递和通过引用传递。 默认情况下,函数参数按值传递,因此如果函数内的参数值发生更改,它不会受到函数外部的影响。 但是,要允许函数修改其参数,它们必须通过引用传递。

通过引用传递参数的方法是在函数定义中的参数名称前加上与号(&),如下例所示:

<?php
/* 定义一个与数字相乘的函数
并返回新值 */
function selfMultiply1(&$number){
    $number *= $number;
    return $number;
}

function selfMultiply2($number){
    $number *= $number;
    return $number;
}
$mynum = 5;

selfMultiply2($mynum);
echo $mynum; // 输出: 5
 
selfMultiply1($mynum);
echo $mynum; // 输出: 25
?>
8.创建递归函数

递归函数是一次又一次调用自身直到满足条件的函数。递归函数通常用于求解复杂的数学计算或处理深度嵌套的结构,例如,打印深度嵌套数组的所有元素。

<?php
//定义递归函数
function printValues($arr) {
    global $count;
    global $items;
    
    //检查$arr是否为数组
    if(!is_array($arr)){
        die("ERROR: Input is not an array");
    }
    
    /*
        遍历数组,如果value本身是数组,则递归调用
        函数将找到的值添加到输出项目数组中,
        并为找到的每个值将计数器加1
    */
    foreach($arr as $a){
        if(is_array($a)){
            printValues($a);
        } else{
            $items[] = $a;
            $count++;
        }
    }
    
    //返回数组中的总计数和值
    return array('total' => $count, 'values' => $items);
}
 
//定义嵌套数组
$species = array(
    "birds" => array(
        "Eagle",
        "Parrot",
        "Swan"
    ),
    "mammals" => array(
        "Human",
        "cat" => array(
            "Lion",
            "Tiger",
            "Jaguar"
        ),
        "Elephant",
        "Monkey"
    ),
    "reptiles" => array(
        "snake" => array(
            "Cobra" => array(
                "King Cobra",
                "Egyptian cobra"
            ),
            "Viper",
            "Anaconda"
        ),
        "Crocodile",
        "Dinosaur" => array(
            "T-rex",
            "Alamosaurus"
        )
    )
);
 
//计算和打印嵌套数组中的值
$result = printValues($species);
echo $result['total'] . ' value(s) found: ';
echo implode(', ', $result['values']);
?>
//输出结果
16 value(s) found: Eagle, Parrot, Swan, Human, Lion, Tiger, Jaguar, Elephant, Monkey, King Cobra, Egyptian cobra, Viper, Anaconda, Crocodile, T-rex, Alamosaurus

(15)面向对象

在面向对象的程序设计(Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。

对象的主要三个特性:

  • 对象的行为:可以对对象施加的操作(如 “开灯”“关灯”)。
  • 对象的形态:施加操作时对象的响应(如颜色、尺寸、状态)。
  • 对象的表示:区分相同行为与状态的具体标识(如唯一 ID)。

例如,Animal(动物)是抽象类,而 “狗” 和 “羊” 是具体对象,它们有$color属性,有run()eat()等行为。

1. 面向对象核心概念
概念说明(PHP 8+ 增强)
定义事物的抽象特征(数据结构与操作方法),需显式声明属性类型与访问修饰符。
对象类的实例化结果,PHP 8.0+ 支持通过 “命名参数” 灵活初始化。
成员变量类的属性,需声明访问修饰符(public/protected/private)和类型(如string)。
成员函数类的方法,支持参数类型、返回值类型声明(PHP 7.0+),PHP 8.0+ 新增联合类型(`int
继承子类通过extends继承父类,PHP 8.0+ 支持接口默认方法,不支持多继承。
多态同一方法在不同类中实现不同逻辑,PHP 8+ 联合类型增强了多态的灵活性。
封装通过访问修饰符限制属性 / 方法访问范围,PHP 8+ 强化了私有属性的隔离性。
构造函数初始化对象,PHP 8.0+ 支持 “属性提升”(参数直接声明属性,简化代码)。
析构函数对象销毁时自动执行,用于资源清理(如关闭连接),PHP 8+ 逻辑无本质变化。
抽象类 / 接口抽象类含抽象方法(需子类实现),接口仅定义方法规范,PHP 8+ 强化类型检查。
2. 类定义

PHP 8+ 要求类属性必须显式声明访问修饰符(public/protected/private),并推荐添加类型声明(如stringint),不再推荐使用var关键字var仅作为public的别名保留)。

语法格式:

<?php
class PhpClass {
  // 显式声明属性:访问修饰符 + 类型 + 变量名(可带初始值)
  public string $name;
  protected int $age = 18;
  private bool $isActive = true;
  
  // 方法:参数类型 + 返回值类型声明
  public function setName(string $newName): void {
    $this->name = $newName;
  }
  
  public function getName(): string {
    return $this->name;
  }
}
?>

示例(完整类):

<?php
class Site {
  /* 成员变量(带类型声明) */
  public string $url;   // 公开属性:URL地址
  public string $title; // 公开属性:标题
  
  /* 成员函数(带参数类型与返回值类型) */
  // 设置URL(无返回值,用void)
  public function setUrl(string $par): void {
    $this->url = $par;
  }
  
  // 获取URL(返回字符串)
  public function getUrl(): string {
    return $this->url;
  }
  
  // 设置标题
  public function setTitle(string $par): void {
    $this->title = $par;
  }
  
  // 获取标题
  public function getTitle(): string {
    return $this->title;
  }
}
?>
  • $this:表示当前对象实例,用于访问对象的属性和方法(如$this->url)。
  • 类型声明:PHP 8+ 默认为 “弱类型检查”,但显式声明类型可提升代码可读性和安全性(类型不匹配会抛出TypeError)。
3. 创建对象(PHP 8.0+ 增强)

使用new运算符实例化类,PHP 8.0+ 支持命名参数(可忽略参数顺序,通过参数名指定值)。

<?php
// 实例化对象
$taobao = new Site();
$google = new Site();

// 调用方法设置属性(传统方式:按参数顺序)
$taobao->setTitle("淘宝");
$taobao->setUrl("www.taobao.com");

// PHP 8.0+ 命名参数(更清晰,无需记忆顺序)
$google->setTitle(par: "Google 搜索"); // 显式指定参数名“par”
$google->setUrl(par: "www.google.com");

// 访问属性(通过方法返回值)
echo $taobao->getTitle(); // 输出:淘宝
echo $google->getUrl();   // 输出:www.google.com
?>
4. 构造函数(PHP 8.0+ 核心改进)

构造函数用于初始化对象,PHP 8.0+ 引入构造函数属性提升(Constructor Property Promotion),可在构造函数参数中直接声明并初始化属性,无需单独定义属性。

传统写法(PHP 7.x):

class Site {
  // 先声明属性
  public string $url;
  public string $title;
  
  // 再在构造函数中赋值
  public function __construct(string $par1, string $par2) {
    $this->url = $par1;
    $this->title = $par2;
  }
}

PHP 8.0+ 简化写法(属性提升):

class Site {
  // 构造函数参数直接声明属性(访问修饰符 + 类型 + 参数名)
  public function __construct(
    public string $url,  // 自动创建 public 属性 $url 并赋值
    public string $title // 自动创建 public 属性 $title 并赋值
  ) {} // 无需额外代码
}

使用示例:

<?php
// 直接通过构造函数初始化(传统方式)
$nhooo = new Site('www.cainiaojc.com', '菜鸟教程');

// PHP 8.0+ 命名参数(参数顺序可任意)
$tmall = new Site(
  title: '天猫商城', 
  url: 'www.tmall.com'
);

// 直接访问属性(因属性为 public)
echo $nhooo->title; // 输出:菜鸟教程
echo $tmall->url;   // 输出:www.tmall.com
?>
5. 析构函数

析构函数在对象生命周期结束时(如脚本执行完毕、对象被 unset)自动执行,用于资源清理(如关闭文件、释放数据库连接)。

语法:

<?php
class MyDestructableClass {
  private string $name;
  
  // 构造函数(初始化资源)
  public function __construct(string $name) {
    $this->name = $name;
    echo "构造函数:初始化 {$this->name}\n";
  }
  
  // 析构函数(清理资源)
  public function __destruct() {
    echo "析构函数:销毁 {$this->name}\n";
  }
}

// 实例化对象
$obj = new MyDestructableClass("测试对象");
// 脚本结束时自动调用析构函数
?>

输出:

构造函数:初始化 测试对象
析构函数:销毁 测试对象
6. 继承

PHP 通过extends关键字实现单继承(一个子类只能继承一个父类),子类可复用父类的属性和方法,并可扩展新功能。

示例:

<?php
// 父类
class Site {
  // 父类构造函数(属性提升)
  public function __construct(
    public string $url,
    public string $title
  ) {}
  
  // 父类方法(返回字符串)
  public function getInfo(): string {
    return "{$this->title}{$this->url})";
  }
}

// 子类继承父类
class ChildSite extends Site {
  // 子类新增属性(通过构造函数属性提升)
  public function __construct(
    string $url,
    string $title,
    public string $category // 子类特有属性:分类
  ) {
    // 调用父类构造函数(必须显式调用)
    parent::__construct($url, $title);
  }
  
  // 重写父类方法(返回值类型需兼容)
  public function getInfo(): string {
    // 复用父类逻辑 + 子类扩展
    return parent::getInfo() . " - 分类:{$this->category}";
  }
}

// 使用子类
$child = new ChildSite(
  url: 'www.php.net',
  title: 'PHP 官网',
  category: '技术'
);
echo $child->getInfo(); // 输出:PHP 官网(www.php.net) - 分类:技术
?>
7. 方法重写

子类可重写父类的方法(覆盖原有逻辑),但需满足:

  • 方法名必须与父类一致;
  • 参数类型、数量必须兼容(PHP 8+ 严格检查);
  • 返回值类型必须兼容(如父类返回int,子类可返回intfloat,但不能返回string)。

示例:

<?php
class ParentClass {
  // 父类方法:参数为 int,返回 int
  public function calculate(int $x): int {
    return $x * 2;
  }
}

class ChildClass extends ParentClass {
  // 重写父类方法:参数类型(int)和返回值类型(int)兼容
  public function calculate(int $x): int {
    return $x * 3; // 子类自定义逻辑
  }
}

$obj = new ChildClass();
echo $obj->calculate(5); // 输出:15(而非父类的 10)
?>
8. 访问控制

通过访问修饰符限制属性和方法的访问范围,PHP 8+ 要求显式声明(不允许隐式public)。

修饰符访问范围示例场景
public类内、子类、外部均可访问通用属性(如$title
protected仅类内及子类可访问需子类扩展的属性(如$config
private仅当前类内可访问(子类不可见)内部状态(如$password

示例(含类型声明):

<?php
class MyClass {
  public int|string $public = 'Public'; // 联合类型(int 或 string)
  protected ?float $protected = 3.14;   // 可空类型(float 或 null)
  private bool $private = true;         // 私有属性
  
  public function printAll(): void {
    // 类内可访问所有属性
    echo $this->public . " | " . $this->protected . " | " . $this->private;
  }
}

$obj = new MyClass();
echo $obj->public; // 允许(public)
// echo $obj->protected; // 错误(protected,外部不可访问)
// echo $obj->private;   // 错误(private,外部不可访问)
$obj->printAll(); // 输出:Public | 3.14 | 1
?>
9. 接口

接口(interface)定义类必须实现的方法规范(仅声明方法,不实现逻辑),PHP 8+ 支持接口方法的类型声明和常量。

语法:

<?php
// 声明接口(方法必须为 public,需显式类型)
interface iTemplate {
  public const VERSION = 1.0; // 接口常量(默认 public)
  
  // 声明方法:参数类型 + 返回值类型
  public function setVariable(string $name, mixed $value): void;
  public function getHtml(string $template): string;
}

// 实现接口(必须完全实现所有方法)
class Template implements iTemplate {
  private array $vars = [];
  
  // 实现接口方法(严格匹配类型)
  public function setVariable(string $name, mixed $value): void {
    $this->vars[$name] = $value;
  }
  
  public function getHtml(string $template): string {
    foreach ($this->vars as $name => $value) {
      $template = str_replace("{{$name}}", $value, $template);
    }
    return $template;
  }
}

// 使用
$tpl = new Template();
$tpl->setVariable('name', 'PHP');
echo $tpl->getHtml('Hello {{name}}'); // 输出:Hello PHP
?>
10. 类常量

类常量是类中固定不变的值(如版本号),PHP 7.1+ 支持为常量添加访问修饰符(public/protected/private),默认public

示例:

<?php
class Config {
  public const VERSION = '1.0.0';       // 公开常量
  private const MAX_SIZE = 1024;        // 私有常量(仅类内访问)
  
  public function getMaxSize(): int {
    return self::MAX_SIZE; // 类内访问私有常量
  }
}

echo Config::VERSION; // 输出:1.0.0(公开常量可外部访问)
$obj = new Config();
echo $obj->getMaxSize(); // 输出:1024(通过方法访问私有常量)
// echo Config::MAX_SIZE; // 错误(私有常量不可外部访问)
?>
11. 抽象类

抽象类(abstract class)含至少一个抽象方法(abstract,仅声明不实现),不能直接实例化,需子类继承并实现所有抽象方法。

PHP 8+ 要求: 抽象方法必须声明参数类型和返回值类型,子类实现时需严格匹配。

示例:

<?php
abstract class AbstractData {
  // 抽象方法(需子类实现)
  abstract public function format(): string;
  abstract public function setValue(mixed $value): void;
}

class StringData extends AbstractData {
  private mixed $data;
  
  // 实现抽象方法(类型需匹配)
  public function setValue(mixed $value): void {
    $this->data = $value;
  }
  
  public function format(): string {
    return (string)$this->data;
  }
}

$obj = new StringData();
$obj->setValue(123);
echo $obj->format(); // 输出:123(转为字符串)
?>
12. Static 关键字

static用于声明静态属性 / 方法,可直接通过类名访问(无需实例化),静态方法中不能使用$this(无对象实例)。

PHP 8.0+ 增强: 支持static作为返回类型(返回当前类的实例)。

示例:

php

<?php
class MathUtil {
  public static int $count = 0; // 静态属性(共享于所有实例)
  
  // 静态方法(返回 static 实例)
  public static function create(): static {
    self::$count++; // 访问静态属性
    return new static();
  }
  
  public static function add(int $a, int $b): int {
    return $a + $b;
  }
}

// 直接通过类名访问静态方法/属性
echo MathUtil::add(2, 3); // 输出:5
$obj1 = MathUtil::create();
$obj2 = MathUtil::create();
echo MathUtil::$count; // 输出:2(两个实例被创建)
?>
13. Final 关键字

final用于限制继承和重写:

  • final class:类不可被继承;
  • final function:方法不可被子类重写。

示例:

<?php
// final 类:不可被继承
final class FinalClass {
  public function test(): void {
    echo "FinalClass::test()";
  }
}

// class Child extends FinalClass {} // 错误(final 类不可继承)

class ParentClass {
  // final 方法:不可被重写
  final public function finalMethod(): void {
    echo "ParentClass::finalMethod()";
  }
}

class ChildClass extends ParentClass {
  // public function finalMethod(): void {} // 错误(final 方法不可重写)
}
?>
14. 调用父类构造方法

子类构造函数不会自动调用父类构造函数,需显式通过parent::__construct()调用(通常在子类构造函数第一行)。

PHP 8+ 支持命名参数传递:

<?php
class Base {
  public function __construct(public string $name) {
    echo "Base 构造:{$this->name}\n";
  }
}

class Child extends Base {
  public function __construct(string $name, public int $age) {
    // 调用父类构造函数(用命名参数更清晰)
    parent::__construct(name: $name);
    echo "Child 构造:年龄 {$this->age}\n";
  }
}

$obj = new Child(name: "小明", age: 18);
// 输出:
// Base 构造:小明
// Child 构造:年龄 18
?>

(16)PHP 数学运算符

在本教程中,您将学习如何在 PHP 中执行数学运算。PHP 提供了丰富的内置函数和运算符,可帮助您执行从简单的加法、减法到高级数学计算的所有操作。

1. 基本数学运算符

PHP 支持以下基本数学运算符:

运算符描述示例结果
+加法7 + 310
-减法7 - 25
*乘法7 * 214
/除法7 / 23.5
%取模(取余)7 % 21
**幂运算2 ** 38

示例:

<?php
echo 7 + 3;     // 输出:10
echo '<br>';
echo 7 - 2;     // 输出:5
echo '<br>';
echo 7 * 2;     // 输出:14
echo '<br>';
echo 7 / 2;     // 输出:3.5
echo '<br>';
echo 7 % 2;     // 输出:1(7除以2的余数)
echo '<br>';
echo 2 ** 3;    // 输出:8(2的3次方,PHP 5.6+ 支持)
?>
2. 运算优先级与括号

数学运算遵循特定的优先级规则,通常乘法和除法优先于加法和减法。但可以使用括号改变运算顺序,括号内的表达式总是最先计算。

示例:

<?php
echo 5 + 4 * 10;         // 输出:45(先乘后加)
echo '<br>';
echo (5 + 4) * 10;       // 输出:90(先加后乘)
echo '<br>';
echo 5 + 4 * 10 / 2;     // 输出:25(先乘除后加减)
echo '<br>';
echo 8 * 10 / (4 - 2);   // 输出:40(先算括号内)
echo '<br>';
echo (8 + 10) / (4 - 2); // 输出:9(先算两个括号内)
?>
3. 常用数学函数

PHP 提供了许多内置函数用于执行复杂的数学运算。以下是一些最常用的函数:

3.1 绝对值(abs()

返回一个数的绝对值(正值),支持整数和浮点数。

示例:

<?php
echo abs(5) . "<br>";    // 输出:5
echo abs(-5) . "<br>";   // 输出:5
echo abs(4.2) . "<br>";  // 输出:4.2
echo abs(-4.2) . "<br>"; // 输出:4.2
?>
3.2 向上 / 向下取整(ceil()/floor()
  • ceil():向上取整,返回不小于给定数的最小整数。
  • floor():向下取整,返回不大于给定数的最大整数。

示例:

<?php
// 向上取整
echo ceil(4.2) . "<br>";    // 输出:5
echo ceil(9.99) . "<br>";   // 输出:10
echo ceil(-5.18) . "<br>";  // 输出:-5(负数向上取整更接近0)
 
// 向下取整
echo floor(4.2) . "<br>";    // 输出:4
echo floor(9.99) . "<br>";   // 输出:9
echo floor(-5.18) . "<br>";  // 输出:-6(负数向下取整远离0)
?>
3.3 四舍五入(round()

根据指定的精度对浮点数进行四舍五入。

语法:

round(float $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): float
  • $precision:保留的小数位数(默认 0)。

  • $mode
    

    :舍入模式(PHP 5.3+ 支持):

    • PHP_ROUND_HALF_UP:四舍五入(默认)。
    • PHP_ROUND_HALF_DOWN:五舍六入。
    • PHP_ROUND_HALF_EVEN:银行家舍入法(四舍六入五取偶)。
    • PHP_ROUND_HALF_ODD:五取奇。

示例:

<?php
echo round(3.4) . "<br>";       // 输出:3
echo round(3.5) . "<br>";       // 输出:4
echo round(3.6) . "<br>";       // 输出:4
echo round(3.45, 1) . "<br>";   // 输出:3.5(保留1位小数)
echo round(3.44, 1) . "<br>";   // 输出:3.4
echo round(-3.5) . "<br>";      // 输出:-4
echo round(3.5, 0, PHP_ROUND_HALF_DOWN) . "<br>";  // 输出:3(五舍六入)
?>
3.4 平方根(sqrt()

计算一个正数的平方根,负数返回 NAN(非数字)。

示例:

<?php
echo sqrt(9) . "<br>";   // 输出:3
echo sqrt(25) . "<br>";  // 输出:5
echo sqrt(10) . "<br>";  // 输出:3.1622776601684
echo sqrt(-16) . "<br>"; // 输出:NAN(非数字)
?>
3.5 最大值 / 最小值(max()/min()

返回一组数中的最大值或最小值,支持多个参数或数组。

示例:

<?php
// 多个参数形式
echo max(1, 3, 2) . "<br>";       // 输出:3
echo min(1, 3, 2) . "<br>";       // 输出:1

// 数组形式
echo max([1, 3, 2]) . "<br>";     // 输出:3
echo min([1, 3, 2]) . "<br>";     // 输出:1
?>
3.6 随机数生成(rand()/random_int()
  • rand():生成伪随机整数(PHP 7.0+ 推荐使用 random_int())。
  • random_int():生成更安全的加密随机整数(适用于密码学场景)。

语法:

rand(int $min = 0, int $max = getrandmax()): int
random_int(int $min, int $max): int

示例:

<?php
// 生成随机数(默认范围:0 到 getrandmax())
echo rand() . "<br>";
echo rand() . "<br>";

// 生成1到10之间的随机数(包含1和10)
echo rand(1, 10) . "<br>";
echo rand(1, 10) . "<br>";

// 更安全的随机数生成(PHP 7.0+)
echo random_int(100, 999) . "<br>";  // 生成100到999之间的随机数
?>
3.7 幂运算(pow()

计算一个数的指定次幂,等效于 ** 运算符。

示例:

<?php
echo pow(2, 3) . "<br>";    // 输出:8(2的3次方)
echo pow(5, 2) . "<br>";    // 输出:25(5的平方)
echo pow(10, -2) . "<br>";  // 输出:0.01(10的-2次方)
?>
3.8 绝对值(fmod()

返回浮点数除法的余数(模)。

示例:

<?php
echo fmod(5.7, 1.3) . "<br>";  // 输出:0.5(5.7除以1.3的余数)
echo fmod(-5.7, 1.3) . "<br>"; // 输出:-0.5
echo fmod(5.7, -1.3) . "<br>"; // 输出:0.5
?>
4. 进制转换函数

PHP 提供了多种函数用于不同进制数之间的转换:

4.1 十进制与二进制转换
  • decbin():十进制转二进制。
  • bindec():二进制转十进制。

示例:

<?php
// 十进制转二进制
echo decbin(2) . "<br>";    // 输出:10  
echo decbin(12) . "<br>";   // 输出:1100  
echo decbin(100) . "<br>";  // 输出:1100100

// 二进制转十进制
echo bindec(10) . "<br>";       // 输出:2 
echo bindec(1100) . "<br>";     // 输出:12  
echo bindec(1100100);  // 输出:100
?>
4.2 十进制与十六进制转换
  • dechex():十进制转十六进制。
  • hexdec():十六进制转十进制。

示例:

<?php
// 十进制转十六进制
echo dechex(255) . "<br>";  // 输出:ff
echo dechex(196) . "<br>";  // 输出:c4
echo dechex(0) . "<br>";    // 输出:0

// 十六进制转十进制
echo hexdec('ff') . "<br>";  // 输出:255
echo hexdec('c4') . "<br>";  // 输出:196
echo hexdec(0);     // 输出:0
?>
4.3 十进制与八进制转换
  • decoct():十进制转八进制。
  • octdec():八进制转十进制。

示例:

<?php
// 十进制转八进制
echo decoct(12) . "<br>";   // 输出:14
echo decoct(256) . "<br>";  // 输出:400
echo decoct(77) . "<br>";   // 输出:115

// 八进制转十进制
echo octdec('14') . "<br>";   // 输出:12
echo octdec('400') . "<br>";  // 输出:256
echo octdec('115');  // 输出:77
?>
4.4 任意进制转换(base_convert()

base_convert() 函数可将数字在任意进制之间转换,支持 2 到 36 进制。

语法:

base_convert(string $number, int $frombase, int $tobase): string
  • $frombase:当前进制(2-36)。
  • $tobase:目标进制(2-36)。
  • 对于大于 10 的进制,使用字母 a-z 表示 10-35。

示例:

<?php
// 十进制转二进制
echo base_convert('12', 10, 2) . "<br>";  // 输出:1100
// 二进制转十进制
echo base_convert('1100', 2, 10) . "<br>";  // 输出:12

// 十进制转十六进制
echo base_convert('10889592', 10, 16) . "<br>";  // 输出:a62978
// 十六进制转十进制
echo base_convert('a62978', 16, 10) . "<br>";  // 输出:10889592

// 十六进制转八进制
echo base_convert('c2c6a8', 16, 8) . "<br>";  // 输出:60543250
// 八进制转十六进制
echo base_convert('60543250', 8, 16) . "<br>";  // 输出:c2c6a8

// 十进制转36进制(使用字母)
echo base_convert('123456789', 10, 36) . "<br>";  // 输出:21i3v9
// 36进制转十进制
echo base_convert('21i3v9', 36, 10) . "<br>";  // 输出:123456789
?>
5. 其他常用数学函数
函数名描述示例结果
abs()绝对值abs(-5)5
ceil()向上取整ceil(4.3)5
floor()向下取整floor(4.9)4
round()四舍五入round(4.5)5
sqrt()平方根sqrt(16)4
pow()幂运算pow(2, 3)8
max()最大值max(5, 3, 9)9
min()最小值min(5, 3, 9)3
rand()随机数rand(1, 10)1-10 之间的随机数
pi()获取圆周率 πpi()3.1415926535898
log()自然对数(以 e 为底)log(10)2.302585092994
log10()常用对数(以 10 为底)log10(100)2
exp()指数函数(e 的 x 次方)exp(2)7.3890560989307
sin()正弦函数sin(deg2rad(90))1
cos()余弦函数cos(deg2rad(180))-1
tan()正切函数tan(deg2rad(45))1

(17)HTTP GET 和 POST 方法

在 Web 开发中,浏览器通常通过 GETPOST 两种 HTTP 方法与服务器通信,用于发送数据并获取响应。PHP 提供了超全局变量(如 $_GET$_POST)来便捷地处理这些数据,同时 PHP 8.0+ 对安全处理和输入验证有更严格的推荐实践。

1. GET 方法

GET 方法通过 URL query 参数 传递数据,格式为 key=value,多个参数用 & 分隔。例如:
http://example.com/action.php?name=john&age=24

1.1 GET 方法的特点
  • 可见性:数据直接包含在 URL 中,用户可见,且会被记录在浏览器历史、服务器日志中。
  • 长度限制:URL 长度有限(通常取决于浏览器和服务器配置,建议不超过 2048 字符),不适合传递大量数据。
  • 缓存性:GET 请求可被浏览器缓存,适合获取数据(如搜索、分页)。
  • 安全性:不适合传递敏感信息(如密码),存在泄露风险。
1.2 PHP 中处理 GET 数据

PHP 通过超全局变量 $_GET 接收 GET 方法传递的数据($_GET 是一个关联数组,键为参数名,值为参数值)。

示例(基础用法):

<!DOCTYPE html>
<html>
<head>
    <title>PHP GET 方法示例</title>
</head>
<body>
    <?php
    // 检查参数是否存在(PHP 8.0+ 可使用 isset() 或 empty())
    if (isset($_GET['name'])) {
        // 安全输出:使用 htmlspecialchars() 防止 XSS 攻击(PHP 8+ 推荐)
        $name = htmlspecialchars($_GET['name'], ENT_QUOTES);
        echo "<p>Hi, {$name}</p>";
    }
    ?>

    <!-- 表单通过 GET 方法提交 -->
    <form method="get" action="<?php 
        // 安全处理 action:使用 htmlspecialchars() 防止 XSS
        echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES); 
    ?>">
        <label for="name">姓名:</label>
        <input type="text" name="name" id="name">
        <input type="submit" value="提交">
    </form>
</body>
</html>

关键安全提示:

  • 直接输出用户输入(如 $_GET['name'])可能导致 XSS 攻击,需用 htmlspecialchars() 转义特殊字符(ENT_QUOTES 是 PHP 8+ 推荐的引号处理模式)。
  • $_SERVER['PHP_SELF'] 可能被注入恶意代码,必须用 htmlspecialchars() 过滤后再作为表单 action
2. POST 方法

POST 方法通过 HTTP 请求体 传递数据,数据不会显示在 URL 中,而是作为独立的数据包发送给服务器。

2.1 POST 方法的特点
  • 隐蔽性:数据不在 URL 中显示,适合传递敏感信息(如密码、表单提交)。
  • 数据量:无严格长度限制(取决于服务器配置,如 post_max_size),可传递大量数据(包括文件上传)。
  • 缓存性:默认不被浏览器缓存,适合提交数据(如注册、支付)。
  • 安全性:比 GET 更安全,但仍需加密(如 HTTPS)保护传输过程。
2.2 PHP 中处理 POST 数据

PHP 通过超全局变量 $_POST 接收 POST 方法传递的数据(同样是关联数组)。

示例(基础用法):

<!DOCTYPE html>
<html>
<head>
    <title>PHP POST 方法示例</title>
</head>
<body>
    <?php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') { // 检查请求方法(PHP 8+ 推荐)
        // 验证并获取参数(PHP 8+ 可结合 filter_input 增强安全性)
        $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
        if ($email) {
            echo "<p>有效的邮箱:{$email}</p>";
        } else {
            echo "<p>请输入有效的邮箱地址</p>";
        }
    }
    ?>

    <!-- 表单通过 POST 方法提交 -->
    <form method="post" action="<?php 
        echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES); 
    ?>">
        <label for="email">邮箱:</label>
        <input type="email" name="email" id="email">
        <input type="submit" value="提交">
    </form>
</body>
</html>

PHP 8+ 增强实践:

  • 使用 $_SERVER['REQUEST_METHOD'] 严格检查请求类型(如 === 'POST'),避免跨方法调用错误。
  • 推荐使用 filter_input() 函数验证输入(如 FILTER_VALIDATE_EMAIL 验证邮箱格式),替代直接访问 $_POST,增强数据合法性检查。
3. $_REQUEST 变量

$_REQUEST 是一个混合超全局变量,默认包含 $_GET$_POST$_COOKIE 的数据(具体包含范围由 php.ini 中的 request_ordervariables_order 配置决定)。

示例:

<?php
if (isset($_REQUEST['username'])) {
    $username = htmlspecialchars($_REQUEST['username'], ENT_QUOTES);
    echo "<p>用户名:{$username}</p>";
}
?>

<form method="post" action="">
    <input type="text" name="username">
    <input type="submit">
</form>

注意事项(PHP 8+ 重点):

  • 不推荐优先使用$_REQUEST 混合了不同来源的数据(GET/POST/COOKIE),可能导致逻辑混乱(如同名参数覆盖)。
  • 安全风险:若包含 $_COOKIE,可能引入未预期的 cookie 数据,需谨慎处理。
  • 如需使用,建议先通过 $_SERVER['REQUEST_METHOD'] 明确请求类型,再针对性处理。
4. GET 与 POST 的核心区别
维度GET 方法POST 方法
数据位置URL query 参数HTTP 请求体
可见性可见(URL 中)不可见(请求体中)
数据大小有限制(约 2048 字符)无严格限制(取决于服务器配置)
缓存可被缓存默认不缓存
用途获取数据(如搜索、分页)提交数据(如注册、上传)
安全性低(不适合敏感数据)较高(需配合 HTTPS)
PHP 接收变量$_GET$_POST
5. PHP 8+ 输入处理最佳实践
  1. 严格验证输入
    使用 filter_var()filter_input() 验证数据类型(如 FILTER_VALIDATE_INT 验证整数,FILTER_SANITIZE_STRING 过滤字符串)。

    $age = filter_input(INPUT_GET, 'age', FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 18, 'max_range' => 120]
    ]);
    if ($age === false) {
        echo "年龄必须是 18-120 之间的整数";
    }
    
  2. 防止 XSS 攻击
    输出用户输入前,用 htmlspecialchars($data, ENT_QUOTES) 转义 HTML 特殊字符(ENT_QUOTES 确保单双引号都被转义)。

  3. 明确请求方法
    通过 $_SERVER['REQUEST_METHOD'] 判断请求类型,避免逻辑错误:

    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        // 处理 GET 请求
    } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // 处理 POST 请求
    }
    
  4. 避免直接依赖 $_REQUEST
    优先使用 $_GET$_POST 明确区分数据来源,减少混淆。

6.总结

GET 和 POST 是 Web 开发中最常用的 HTTP 方法,PHP 8.0+ 通过 $_GET$_POST 超全局变量便捷处理数据,但需注意安全实践:

  • htmlspecialchars() 防止 XSS 攻击;
  • filter_input() 验证输入合法性;
  • 明确请求方法,避免混合使用 $_REQUEST
  • 敏感数据优先用 POST 方法,并配合 HTTPS 传输。

结语

通过对这份 PHP 教程的学习,我们全面且系统地探索了 PHP 这门强大的服务器端脚本语言。从基础的语法知识,如标准语法结构、注释规范、变量与常量的使用,到数据类型的丰富多样,包括原始类型、复合类型和伪类型,再到字符串处理函数的灵活运用,每一个知识点都如同坚实的基石,构建起了我们对 PHP 的认知大厦。
PHP 以其独特的语法优势,结合了 C、Java、Perl 等多种语言的特点,既易于学习上手,又具备强大的功能和广泛的适用性,尤其在 Web 开发领域,PHP 发挥着不可替代的作用。它能够轻松地与各种数据库相连,处理大量数据,为网站和应用程序提供稳定的数据支持。同时,PHP 的灵活性还体现在其变量作用域的多样性、常量的稳定性以及丰富的数据类型上,这些特性使得开发者能够根据具体的需求,灵活地设计和实现各种复杂的功能。
然而,学习是一个不断深入和持续积累的过程。虽然我们已经掌握了 PHP 的基础知识,但在实际的开发应用中,还有许多高级特性和优化技巧等待我们去探索。例如,PHP 的面向对象编程、与前端技术的深度结合、性能优化以及安全防护等方面,都是我们进一步提升技能的重要方向。
希望每一位学习者都能将所学的知识运用到实际项目中,通过实践不断巩固和拓展自己的能力。在面对各种挑战时,保持积极的学习态度和探索精神,不断寻求创新和突破。相信在未来的编程之路上,PHP 将成为我们手中的有力武器,助力我们开发出更加高效、稳定和富有创意的应用程序。
祝愿大家在 PHP 的学习和实践中取得丰硕的成果,不断攀登编程技术的新高峰!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-曾牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值