PHP(超文本预处理器,服务器端脚本语言)

PHP基础

PHP功能

  • PHP 可以生成动态页面内容
  • PHP 可以创建、打开、读取、写入、关闭服务器上的文件
  • PHP 可以收集表单数据
  • PHP 可以发送和接收 cookies
  • PHP 可以添加、删除、修改您的数据库中的数据
  • PHP 可以限制用户访问您的网站上的一些页面
  • PHP 可以加密数据

通过 PHP,不再限于输出 HTML,还可以输出图像、PDF 文件,甚至 Flash 电影,还可以输出任意的文本,比如 XHTML 和 XML

PHP语法

PHP 脚本可以放在文档中的任何位置。PHP 脚本以 结束,每个代码行都必须以分号结束,

有两种在浏览器输出文本的基础指令:echoprint,有两种注释方法:**//** 和 /* */

PHP变量

变量以 $ 符号开始,后面跟着变量的名称,变量名只能包含字母、数字以及下划线(A-z、0-9 和 _ ),必须以字母或者下划线字符开始

PHP 没有声明变量的命令,在第一次赋值时就被创建

PHP global 关键字

global 关键字用于函数内访问全局变量,在函数内调用函数外定义的全局变量,我们需要在函数中的变量前加上 global 关键字

PHP 将所有全局变量存储在一个名为 $GLOBALS[index] 的数组中。 index 保存变量的名称。这个数组可以在函数内部访问,也可以直接用来更新全局变量

1
2
3
global $x,$y;  
$y=$x+$y;
//$GLOBALS['y']=$GLOBALS['x']+$GLOBALS['y'];

Static 作用域

在第一次声明变量时使用 static 关键字,可以使得当一个函数完成时,某个局部变量不会被删除

即每次调用函数时,该变量将会保留着函数前一次被调用时的值。

注:该变量仍然是函数的局部变量

PHP echo 和 print 语句

echo于print区别

echo - 可以输出一个或多个字符串,且输出速度比print快

print - 只允许输出一个字符串,返回值总为 1

echo语句

1
2
3
4
5
6
<?php
echo "<h2>PHP 很有趣!</h2>";
echo "Hello world!<br>";
echo "我要学 PHP!<br>";
echo "这是一个", "字符串,", "使用了", "多个", "参数。";
?>
1
2
3
4
5
6
7
8
9
10
11
<?php
$txt1="学习 PHP";
$txt2="RUNOOB.COM";
$cars=array("Volvo","BMW","Toyota");

echo $txt1;
echo "<br>";
echo "在 $txt2 学习 PHP ";
echo "<br>";
echo "我车的品牌是 {$cars[0]}";
?>

print语句

与上述例子基本一致,下例不适用print

1
echo "这是一个", "字符串,", "使用了", "多个", "参数。";

PHP EOF(heredoc)

PHP EOF(heredoc)是一种在命令行shell(如sh、csh、ksh、bash、PowerShell和zsh)和程序语言(像Perl、PHP、Python和Ruby)里定义一个字符串的方法

<<<EOF 开始标记开始,以 EOF 结束标记结束,**结束标识必须顶格独自占一行(即必须从行首开始,前后不能衔接任何空白和字符)**,且在结束标记末尾要有分号

开始标记和结束标记相同,比如常用大写的 EOT、EOD、EOF 来表示,但是不只限于那几个(也可以用:JSON、HTML等),开始标记和结束标记不在正文中出现

开始标识带单引号则不解释内嵌的变量和转义符号

在 heredoc 中,变量不需要用连接符 ., 来拼接

1
2
3
4
5
6
7
<?php
echo <<<EOF
<h1>我的第一个标题</h1>
<p>我的第一个段落。</p>
EOF;
// 结束需要独立一行且前后不能空格
?>
1
2
3
4
5
6
7
8
9
<?php
$name="runoob";
$a= <<<EOF
"abc"$name
"123"
EOF;
// 结束需要独立一行且前后不能空格
echo $a;
?>

PHP数据类型

String(字符串)Integer(整型)Float(浮点型)Boolean(布尔型)Array(数组)Object(对象)NULL(空值)Resource(资源类型)

PHP字符串

一个字符串是一串字符的序列,可以将任何文本放在单引号和双引号中

PHP整型

整数是一个没有小数的数字,整型可以用三种格式来指定:十进制, 十六进制( 以 0x 为前缀)或八进制(前缀为 0)

PHP布尔型

通常用于条件判断

PHP数组

数组可以在一个变量中存储多个值

1
$cars=array("Volvo","BMW","Toyota");

PHP对象(难理解)

对象数据类型也可以用于存储数据

必须使用class关键字声明类对象。类是可以包含属性和方法的结构

PHP NULL值

NULL 值表示变量没有值,可以通过设置变量值为 NULL 来清空变量数据

PHP资源类型

PHP 资源 resource 是一种特殊变量,保存了到外部资源的一个引用

常见资源数据类型有打开文件、数据库连接、图形画布区域等

PHP类型比较

[!IMPORTANT]

  • 松散比较:使用两个等号 == 比较,只比较值,不比较类型。
  • 严格比较:用三个等号 === 比较,除了比较值,也比较类型。

多种类型比较

PHP常量

常量可以用 define() 函数或 const 关键字来定义

一旦定义,其值不能改变,可以在整个脚本的任何地方都可以使用,无需使用 global 关键字

define() 函数

1
bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )

name:必选参数,常量名称,即标志符。

value:必选参数,常量的值。

case_insensitive :可选参数,如果设置为 TRUE,该常量则大小写不敏感,默认是大小写敏感的。

1
define("GREETING", "欢迎访问 Runoob.com", true);

const 关键字

1
const CONSTANT_NAME = "value";

1
const SITE_URL = "https://www.runoob.com";

预定义常量

PHP 提供了一些预定义常量,可以在脚本中直接使用。这些常量通常用于获取 PHP 的配置信息、版本信息等

  • PHP_VERSION:当前 PHP 解析器的版本。
  • PHP_OS:服务器的操作系统。
  • PHP_INT_MAX:最大的整数值。
  • E_ERRORE_WARNINGE_PARSE 等:错误报告级别

PHP字符串变量

字符串变量用于存储并处理文本

PHP 中的字符串变量

当赋一个文本值给变量时,记得给文本值加上单引号或者双引号。

1
2
3
4
<?php
$txt="Hello world!";
echo $txt;
?>

PHP 并置运算符

并置运算符 (.) 用于把两个字符串值连接起来

1
2
3
4
5
<?php
$txt1="Hello world!";
$txt2="What a nice day!";
echo $txt1 . " " . $txt2;
?>

上面的代码中,我们已经使用了两次并置运算符。这是由于我们需要在两个字符串之间插入一个空格

PHP strlen() 函数

strlen() 函数返回字符串的长度(字节数)

PHP strpos() 函数

strpos() 函数用于在字符串内查找一个字符或一段指定的文本。

如果在字符串中找到匹配,该函数会返回第一个匹配的字符位置。如果未找到匹配,则返回 FALSE。

PHP 5 String 函数

PHP运算符

算术运算符

运算符 名称 描述 实例 结果
x + y x 和 y 的和 2 + 2 4
x - y x 和 y 的差 5 - 2 3
x * y x 和 y 的积 5 * 2 10
x / y x 和 y 的商 15 / 5 3
x % y 模(除法的余数) x 除以 y 的余数 5 % 2 10 % 8 10 % 2 1 2 0
-x 设置负数 取 x 的相反符号 <?php $x = 2; echo -$x; ?> -2
~x 取反 x 取反,按二进制位进行”取反”运算。运算规则:~1=-2; ~0=-1; <?php $x = 2; echo ~$x; ?> -3
a . b 并置 连接两个字符串 “Hi” . “Ha” HiHa

整除运算符 **intdiv()**,该函数返回值为第一个参数除于第二个参数的值并取整(向下取整)

var_dump(intdiv(10, 3));会输出int(3)

[!IMPORTANT]

var_dump() 是一个非常有用的调试函数,用于输出变量的详细信息,包括数据类型和值

赋值运算符

运算符 等同于 描述
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 模(除法的余数)
a .= b a = a . b 连接两个字符串

递增/递减运算符

运算符 名称 描述
++ x 预递增 x 加 1,然后返回 x
x ++ 后递增 返回 x,然后 x 加 1
– x 预递减 x 减 1,然后返回 x
x – 后递减 返回 x,然后 x 减 1

比较运算符

运算符 名称 描述 实例
x == y 等于 如果 x 等于 y,则返回 true 5==8 返回 false
x === y 绝对等于 如果 x 等于 y,且它们类型相同,则返回 true 5===”5” 返回 false
x != y 不等于 如果 x 不等于 y,则返回 true 5!=8 返回 true
x <> y 不等于 如果 x 不等于 y,则返回 true 5<>8 返回 true
x !== y 不绝对等于 如果 x 不等于 y,或它们类型不相同,则返回 true 5!==”5” 返回 true
x > y 大于 如果 x 大于 y,则返回 true 5>8 返回 false
x < y 小于 如果 x 小于 y,则返回 true 5<8 返回 true
x >= y 大于等于 如果 x 大于或者等于 y,则返回 true 5>=8 返回 false
x <= y 小于等于 如果 x 小于或者等于 y,则返回 true 5<=8 返回 true

逻辑运算符

运算符 名称 描述 实例
x and y 如果 x 和 y 都为 true,则返回 true x=6 y=3 (x < 10 and y > 1) 返回 true
x or y 如果 x 和 y 至少有一个为 true,则返回 true x=6 y=3 (x==6 or y==5) 返回 true
x xor y 异或 如果 x 和 y 有且仅有一个为 true,则返回 true x=6 y=3 (x==6 xor y==3) 返回 false
x && y 如果 x 和 y 都为 true,则返回 true x=6 y=3 (x < 10 && y > 1) 返回 true
x || y 如果 x 和 y 至少有一个为 true,则返回 true x=6 y=3 (x==5 || y==5) 返回 false
! x 如果 x 不为 true,则返回 true x=6 y=3 !(x==y) 返回 true

数组运算符

运算符 名称 描述
x + y 集合 x 和 y 的集合
x == y 相等 如果 x 和 y 具有相同的键/值对,则返回 true
x === y 恒等 如果 x 和 y 具有相同的键/值对,且顺序相同类型相同,则返回 true
x != y 不相等 如果 x 不等于 y,则返回 true
x <> y 不相等 如果 x 不等于 y,则返回 true
x !== y 不恒等 如果 x 不等于 y,则返回 true

三元运算符

1
(expr1) ? (expr2) : (expr3) 

以下实例中通过判断 $_GET 请求中含有 user 值,如果有返回 $_GET[‘user’],否则返回 nobody:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
// 普通写法
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
echo $username, PHP_EOL;

// PHP 5.3+ 版本写法
$username = $_GET['user'] ?: 'nobody';
echo $username, PHP_EOL;

// PHP 7+ 版本写法
$username = $_GET['user'] ?? 'nobody';
echo $username, PHP_EOL;
?>

注:PHP_EOL 是一个换行符

组合比较符(PHP7+)

符号为 **<=>**。组合比较运算符可以轻松实现两个变量的比较,不仅限于数值类数据的比较

1
$c = $a <=> $b;

如果 $a > $b, 则 $c 的值为 1

如果 $a == $b, 则 $c 的值为 0

如果 $a < $b, 则 $c 的值为 -1

运算符优先级

下表按照优先级从高到低列出了运算符

说明:左 = 从左到右,右 = 从右到左

结合方向 运算符 附加信息
clone new clone 和 new
[ array()
++ – ~ (int) (float) (string) (array) (object) (bool) @ 类型和递增/递减
instanceof 类型
! 逻辑运算符
* / % 算术运算符
+ – . 算术运算符和字符串运算符
<< >> 位运算符
== != === !== <> 比较运算符
& 位运算符和引用
^ 位运算符
| 位运算符
&& 逻辑运算符
|| 逻辑运算符
? : 三元运算符
= += -= *= /= .= %= &= |= ^= <<= >>= => 赋值运算符
and 逻辑运算符
xor 逻辑运算符
or 逻辑运算符
, 多处用到
1
2
3
4
5
6
7
8
9
10
11
<?php
// 优先级: && > = > and
// 优先级: || > = > or

$a = 3;
$b = false;
$c = $a or $b;
var_dump($c); // 这里的 $c 为 int 值3,而不是 boolean 值 true;输出int(3)
$d = $a || $b;
var_dump($d); //这里的 $d 就是 boolean 值 true ;输出bool(true)
?>

PHP 条件语句

if 语句 - 在条件成立时执行代码

if…else 语句 - 在条件成立时执行一块代码,条件不成立时执行另一块代码

if…elseif….else 语句 - 在若干条件之一成立时执行一个代码块

switch 语句 - 在若干条件之一成立时执行一个代码块

PHP数组

在 PHP 中,array() 函数用于创建数组

1
2
3
4
<?php
$cars=array("Volvo","BMW","Toyota");
echo "I like " . $cars[0] . ", " . $cars[1] . " and " . $cars[2] . ".";
?>

获取数组的长度

count() 函数用于返回数组的长度(元素的数量)

遍历数值数组

遍历并打印数值数组中的所有值,您可以使用 for 循环

PHP 关联数组

关联数组是使用分配给数组的指定的键的数组

1
2
3
4
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
echo "Peter is " . $age['Peter'] . " years old.";
?>

遍历关联数组

遍历并打印关联数组中的所有值,您可以使用 foreach 循环

1
2
3
4
5
6
7
8
9
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");

foreach($age as $x=>$x_value)
{
echo "Key=" . $x . ", Value=" . $x_value;
echo "<br>";
}
?>

[!IMPORTANT]

foreach

在 PHP 中,foreach 循环是一种专门用于遍历数组或对象的结构

相比于 forwhile 循环,foreach 能更自然地处理复杂数据结构,如关联数组或对象

基本语法

遍历数组
1
2
3
foreach ($array as $value) {
// 循环体
}

**$array**:需要遍历的数组。

**$value**:当前循环中数组的值。

遍历数组的键值对
1
2
3
foreach ($array as $key => $value) {
// 循环体
}

**$key**:当前元素的键。

**$value**:当前元素的值。

实例

简单数组
1
2
3
4
5
6
7
<?php
$x=array("Google","Runoob","Taobao");
foreach ($x as $value)
{
echo $value . PHP_EOL;
}
?>
关联数组
1
2
3
4
5
6
7
<?php
$x=array(1=>"Google", 2=>"Runoob", 3=>"Taobao");
foreach ($x as $key => $value)
{
echo "key 为 " . $key . ",对应的 value 为 ". $value . PHP_EOL;
}
?>
嵌套数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$users = [
["name" => "John", "age" => 30],
["name" => "Jane", "age" => 25],
["name" => "Doe", "age" => 40]
];

foreach ($users as $user) {
foreach ($user as $key => $value) {
echo "$key: $value, ";
}
echo "\n";
}
?>
遍历对象
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class Car {
public $brand = "Toyota";
public $model = "Corolla";
public $year = 2022;
}

$car = new Car();

foreach ($car as $property => $value) {
echo "$property: $value\n";
}
?>

数组排序

数组中的元素可以按字母或数字顺序进行降序或升序排列

sort()

对数组进行升序排列

rsort()

对数组进行降序排列

asort()

根据数组的值,对关联数组进行升序排列

1
2
3
4
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
asort($age);
?>
arsort()

根据数组的值,对关联数组进行降序排列

ksort()

根据数组的键,对关联数组进行升序排列

krsort()

根据数组的键,对关联数组进行降序排列

PHP 超级全局变量

超级全局变量在一个脚本的全部作用域中都可用

PHP 超级全局变量列表:

  • $GLOBALS
  • $_SERVER
  • $_REQUEST
  • $_POST
  • $_GET
  • $_FILES
  • $_ENV
  • $_COOKIE
  • $_SESSION

PHP $GLOBALS

$GLOBALS 是一个包含了全部变量的全局组合数组。变量的名字就是数组的键。

PHP $_SERVER

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。

PHP $_REQUEST

PHP $_REQUEST 用于收集HTML表单提交的数据

PHP $_POST

PHP $_POST 被广泛应用于收集表单数据,在HTML form标签的指定该属性:”method=”post”。

PHP $_GET

PHP $_GET 同样被广泛应用于收集表单数据,在HTML form标签的指定该属性:”method=”get”

$_GET 也可以收集URL中发送的数据

假定我们有一个包含参数的超链接HTML页面:

1
2
3
4
5
6
7
<html>
<body>

<a href="test_get.php?subject=PHP&web=runoob.com">Test $GET</a>

</body>
</html>

当用户点击链接 “Test $GET”, 参数 “subject” 和 “web” 将发送至”test_get.php”,你可以在 “test_get.php” 文件中使用 $_GET 变量来获取这些数据。以下为 “test_get.php” 文件的代码:

1
2
3
4
5
6
7
8
9
<html> 
<body>

<?php
echo "Study " . $_GET['subject'] . " @ " . $_GET['web'];
?>

</body>
</html>

PHP循环

  • while - 只要指定的条件成立,则循环执行代码块
  • do…while - 首先执行一次代码块,然后在指定的条件成立时重复这个循环
  • for - 循环执行代码块指定的次数
  • foreach - 根据数组中每个元素来循环代码块

PHP面向对象(难理解)

面向对象(Object-Oriented,简称 OO)是一种编程思想和方法,它将程序中的数据和操作数据的方法封装在一起,形成”对象”,并通过对象之间的交互和消息传递来完成程序的功能

关键概念

概念 说明
类(class) 对象的模板,定义属性和方法
对象(object) 通过类实例化的具体对象
属性(property) 类中的变量(也叫成员变量)
方法(method) 类中的函数
构造方法(__construct) 实例化对象时自动执行
析构方法(__destruct) 对象销毁时自动执行
继承(extends) 子类继承父类的方法和属性
多态(polymorphism) 不同类可以实现相同的方法
封装(encapsulation) 限制属性和方法的访问权限
接口(interface) 定义类必须实现的方法
抽象类(abstract) 不能实例化的类,必须被子类继承

类(class)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person {
// 定义属性:属性是类中定义的变量,用于存储对象的状态
public $name;
public $age;

// 构造方法
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}

// 定义方法:方法是类中定义的函数,用于定义对象的行为
public function sayHello() {
return "Hello, my name is " . $this->name;
}
}

类是对象的模板,定义属性和方法,类使用 class 关键字后加上类名定义,类名后的一对大括号({})内可以定义变量和方法,类的变量使用 var 来声明, 变量也可以初始化值

[!CAUTION]

类,对象,当前对象的关系

是一种模板或蓝图。比如,class Car { ... } 是一个汽车的模板。

对象 是从类生成的具体实例。比如,$car1 = new Car(); 是一辆具体的汽车。

当前对象 是某一时刻你正在操作的对象。如果你正在对 $car1 调用方法,那么 $car1 就是当前对象,$this 就是指当前对象,在方法里用 $this 来访问或修改它的属性和方法。

对象(object)

对象是类的实例。通过 new 关键字可以创建一个类的实例。

1
2
$person1 = new Person("Alice", 25);
echo $person1->sayHello(); // 输出: Hello, my name is Alice

访问控制/封装(encapsulation)

PHP 提供 3 种访问控制属性或方法的修饰符:

修饰符 作用
public 公开,类内外都能访问
private 私有,只有定义它的类内部能访问,在子类中也无法直接访问,不能重定义
protected 受保护,类内部和子类能访问,类的外部无法直接访问
属性的访问控制

类属性必须定义为公有,受保护,私有之一。如果用 var 定义,则被视为公有

方法的访问控制

类中的方法可以被定义为公有,私有或受保护。如果没有设置这些关键字,则该方法默认为公有

继承(extends)

子类(Child Class) 可以继承 父类(Parent Class) 的方法和属性,用 extends 关键字实现,PHP 不支持多继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Animal {
public $name;

public function __construct($name) {
$this->name = $name;
}

public function speak() {
return "🗣 叫声未知";
}
}

class Dog extends Animal {
public function speak() {
return "🐶 汪汪!";
}
}

$dog = new Dog("旺财");
echo $dog->speak(); // 🐶 汪汪!

Dog 继承 Animal,但重写了 speak() 方法,让狗狗可以发出「汪汪」的叫声

方法重写

允许子类重写(覆盖)父类的方法

关键点
  • 子类 继承 父类
  • 子类 使用相同的方法名 覆盖父类的方法
  • 方法的 访问权限 放宽(protected 方法可以被 public 重写)
基本用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Animal {
public function speak() {
return "🐾 这是一个动物的声音";
}
}

class Dog extends Animal {
public function speak() {
return "🐶 汪汪!";
}
}

$dog = new Dog();
echo $dog->speak(); // 🐶 汪汪!

子类 Dog 重写了 speak() 方法,不再继承父类 Animal 的默认实现

parent:: 关键字调用父类方法

如果子类需要调用父类的同名方法,可以使用 parent::方法名()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Animal {
public function speak() {
return "🐾 这是一个动物的声音";
}
}

class Dog extends Animal {
public function speak() {
return parent::speak() . " 🐶 但狗会汪汪叫!";
}
}

$dog = new Dog();
echo $dog->speak();
// 🐾 这是一个动物的声音 🐶 但狗会汪汪叫!

parent::speak() 调用了父类 Animalspeak(),然后追加了 "🐶 但狗会汪汪叫!"

Final 关键字

用于防止继承(类)和方法重写(方法),不能用于属性

多态(polymorphism)

不同的类可以用相同的方法名,但实现不同的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Animal {
public function makeSound() {
return "🐾 这是一个动物的声音";
}
}

class Dog extends Animal {
public function makeSound() {
return "🐶 汪汪!";
}
}

class Cat extends Animal {
public function makeSound() {
return "🐱 喵喵!";
}
}

// 创建对象
$dog = new Dog();
$cat = new Cat();

echo $dog->makeSound(); // 🐶 汪汪!
echo $cat->makeSound(); // 🐱 喵喵!

不同的类(DogCat)继承了 Animal,但重写了 makeSound() 方法,实现不同的功能

抽象类(abstract)

抽象类只适合作为「模板」不能被实例化(创建对象),必须由子类继承并实现其方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
abstract class Shape {
abstract public function area();
}

class Circle extends Shape {
public $radius;

public function __construct($radius) {
$this->radius = $radius;
}

public function area() {
return pi() * pow($this->radius, 2);
}
}

$c = new Circle(5);
echo $c->area(); // 78.54

Shape 是抽象类,不能直接创建对象Circle 继承它并实现 area() 方法

接口(interface)

接口 定义了「必须实现」的方法,确保不同类有相同的行为

接口是通过 interface 关键字来定义的,接口中定义的所有方法都必须是公有

要实现一个接口,使用 implements 操作符

1
2
3
4
5
6
7
8
9
10
11
12
13
//定义接口
interface Logger {
public function log($message);
}
//实现接口
class FileLogger implements Logger {
public function log($message) {
echo "📁 记录日志到文件:" . $message;
}
}

$logger = new FileLogger();
$logger->log("系统错误"); // 📁 记录日志到文件:系统错误

静态成员(Static)

静态方法和属性属于类本身,不需要实例化就可直接访问

静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)

1
2
3
4
5
6
7
8
9
10
11
12
<?php
class Math {
public static $pi = 3.1416;

public static function square($num) {
return $num * $num;
}
}

echo Math::$pi; // 3.1416
echo Math::square(5); // 25
?>

静态成员:: 访问

魔术方法

魔术方法 是 PHP 预定义的特殊方法

方法 作用
__construct() 构造函数,创建对象时自动调用
__destruct() 析构函数,销毁对象时调用
__get($name) 访问不存在的属性
__set($name, $value) 给不存在的属性赋值
__call($name, $arguments) 调用不存在的方法
__toString() 对象被当作字符串时调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class MyDestructableClass {
function __construct() {
print "构造函数\n";
$this->name = "MyDestructableClass";
}

function __destruct() {
print "销毁 " . $this->name . "\n";
}
}

$obj = new MyDestructableClass();
?>

输出为

1
2
构造函数
销毁 MyDestructableClass

PHP表单

PHP表单和用户输入

PHP 中的 $_GET 和 $_POST 变量用于检索表单中的信息,比如用户输入

PHP 表单处理

当处理 HTML 表单时,PHP 能把来自 HTML 页面中的表单元素自动变成可供 PHP 脚本使用

PHP 获取下拉菜单的数据

PHP 下拉菜单单选

以下实例我们设置了下拉菜单三个选项,表单使用 GET 方式获取数据,action 属性值为空表示提交到当前脚本,我们可以通过 select 的 name 属性获取下拉菜单的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$q = isset($_GET['q'])? htmlspecialchars($_GET['q']) : '';
if($q) {
if($q =='RUNOOB') {
echo '菜鸟教程<br>http://www.runoob.com';
} else if($q =='GOOGLE') {
echo 'Google 搜索<br>http://www.google.com';
} else if($q =='TAOBAO') {
echo '淘宝<br>http://www.taobao.com';
}
} else {
?>
<form action="" method="get">
<select name="q">
<option value="">选择一个站点:</option>
<option value="RUNOOB">Runoob</option>
<option value="GOOGLE">Google</option>
<option value="TAOBAO">Taobao</option>
</select>
<input type="submit" value="提交">
</form>
<?php
}
?>

[!IMPORTANT]

htmlspecialchars($_GET['q']) 是一种防止 跨站脚本攻击XSS 的安全措施

htmlspecialchars()函数会对用户输入的数据进行转义处理,将特殊的 HTML 字符转换为 HTML 实体,以防止它们被解释为 HTML 或 JavaScript 代码

将以下字符转换为 HTML 实体:

  • &&amp;

  • <&lt;

  • >&gt;

  • "&quot;

  • '&#039;(仅在使用 ENT_QUOTES 时)

    1
    2
    3
    4
    5
    <?php
    // 假设 URL 为:http://example.com/?q=<script>alert('XSS')</script>
    $q = $_GET['q'];
    echo "您输入的内容是:$q";
    //输出:您输入的内容是:<script>alert('XSS')</script>
    1
    2
    3
    4
    5
    <?php
    // 假设 URL 为:http://example.com/?q=<script>alert('XSS')</script>
    $q = htmlspecialchars($_GET['q']);
    echo "您输入的内容是:$q";
    //输出:您输入的内容是:&lt;script&gt;alert('XSS')&lt;/script&gt;

[!NOTE]

php与html切换

1
2
3
4
5
6
7
if (条件) {
// 执行一些 PHP 代码
} else {
?>
<!-- 这里是 HTML 代码 -->
<?php
}
PHP 下拉菜单多选

如果下拉菜单是多选的( multiple=”multiple”),我们可以通过将设置 select name=”q[]” 以数组的方式获取,以下使用 POST 方式提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
$q = isset($_POST['q'])? $_POST['q'] : '';
if(is_array($q)) {
$sites = array(
'RUNOOB' => '菜鸟教程: http://www.runoob.com',
'GOOGLE' => 'Google 搜索: http://www.google.com',
'TAOBAO' => '淘宝: http://www.taobao.com',
);
foreach($q as $val) {
// PHP_EOL 为常量,用于换行
echo $sites[$val] . PHP_EOL;
}

} else {
?><form action="" method="post">
<select multiple="multiple" name="q[]">
<option value="">选择一个站点:</option>
<option value="RUNOOB">Runoob</option>
<option value="GOOGLE">Google</option>
<option value="TAOBAO">Taobao</option>
</select>
<input type="submit" value="提交">
</form><?php
}
?>

单选按钮表单

PHP 单选按钮表单中 name 属性的值是一致的,value 值是不同的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$q = isset($_GET['q'])? htmlspecialchars($_GET['q']) : '';
if($q) {
if($q =='RUNOOB') {
echo '菜鸟教程<br>http://www.runoob.com';
} else if($q =='GOOGLE') {
echo 'Google 搜索<br>http://www.google.com';
} else if($q =='TAOBAO') {
echo '淘宝<br>http://www.taobao.com';
}
} else {?><form action="" method="get">
<input type="radio" name="q" value="RUNOOB" />Runoob
<input type="radio" name="q" value="GOOGLE" />Google
<input type="radio" name="q" value="TAOBAO" />Taobao
<input type="submit" value="提交">
</form><?php
}
?>

checkbox 复选框

PHP checkbox 复选框可以选择多个值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$q = isset($_POST['q'])? $_POST['q'] : '';
if(is_array($q)) {
$sites = array(
'RUNOOB' => '菜鸟教程: http://www.runoob.com',
'GOOGLE' => 'Google 搜索: http://www.google.com',
'TAOBAO' => '淘宝: http://www.taobao.com',
);
foreach($q as $val) {
// PHP_EOL 为常量,用于换行
echo $sites[$val] . PHP_EOL;
}

} else {?><form action="" method="post">
<input type="checkbox" name="q[]" value="RUNOOB"> Runoob<br>
<input type="checkbox" name="q[]" value="GOOGLE"> Google<br>
<input type="checkbox" name="q[]" value="TAOBAO"> Taobao<br>
<input type="submit" value="提交">
</form><?php
}
?>

PHP 表单验证

$_SERVER[“PHP_SELF”] 变量

是一个超全局变量,用于返回当前执行脚本的文件路径(相对于网站根目录)

通常用于:表单的自提交(self-submitting form)动态生成页面链接

基本使用
1
2
3
<?php
echo $_SERVER["PHP_SELF"];
?>

假设访问路径:URL: http://www.example.com/test/form.php

输出结果($_SERVER["PHP_SELF"] 的值为):

1
/test/form.php
表单自提交

通过 $_SERVER["PHP_SELF"] 实现表单提交到当前页面

1
2
3
4
5
6
7
8
9
10
11
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = htmlspecialchars($_POST['name']);
echo "你好, $name!";
}
?>

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
姓名: <input type="text" name="name">
<input type="submit" value="提交">
</form>

htmlspecialchars($_SERVER["PHP_SELF"])避免XSS

使用 PHP 验证表单数据

首先我们对用户所有提交的数据都通过 PHP 的 htmlspecialchars() 函数处理。

当我们使用 htmlspecialchars() 函数时,在用户尝试提交以下文本域:

1
<script>location.href('http://www.runoob.com')</script>

该代码将不会被执行,因为它会被保存为HTML转义代码,如下所示:

1
&lt;script&gt;location.href('http://www.runoob.com')&lt;/script&gt;

以上代码是安全的,可以正常在页面显示或者插入邮件中。

当用户提交表单时,我们将做以下两件事情:

  1. 使用 PHP trim() 函数去除用户输入数据中不必要的字符 (如:空格,tab,换行)。
  2. 使用PHP stripslashes()函数去除用户输入数据中的反斜杠 (\)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
// 定义变量并默认设置为空值
$name = $email = $gender = $comment = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST")
{
$name = test_input($_POST["name"]);
$email = test_input($_POST["email"]);
$website = test_input($_POST["website"]);
$comment = test_input($_POST["comment"]);
$gender = test_input($_POST["gender"]);
}

function test_input($data)
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>

PHP 表单 - 必需字段

PHP - 必需字段

字段 验证规则
名字 必需。 + 只能包含字母和空格
E-mail 必需。 + 必需包含一个有效的电子邮件地址(包含”@”和”.”)
网址 可选。 如果存在,它必需包含一个有效的URL
备注 可选。多行字段(文本域)。
性别 必需。必需选择一个。
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
// 定义变量并默认设为空值
$nameErr= "";
$name= "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["name"])) {
$nameErr = "名字是必需的。";
} else {
$name = test_input($_POST["name"]);
}
}
?>

PHP - 显示错误信息

1
2
3
4
5
6
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>"> 
名字: <input type="text" name="name">
<span class="error">* <?php echo $nameErr;?></span>
<br><br>
<input type="submit" name="submit" value="Submit">
</form>

[!IMPORTANT]

<span class="error">* <?php echo $nameErr;?></span> 是用来在 HTML 页面中动态显示表单验证的错误提示消息的

如果 $nameErr 为空,则此部分不会显示内容。

如果 $nameErr 包含错误消息,会在页面中显示,例如:名字是必填项

PHP 表单 - 验证邮件和URL

PHP - 验证名称

以下代码将通过简单的方式来检测 name 字段是否包含字母和空格,如果 name 字段值不合法,将输出错误信息:

1
2
3
4
$name = test_input($_POST["name"]);
if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
$nameErr = "只允许字母和空格";
}

[!IMPORTANT]

preg_match

进行正则表达式匹配

1
int preg_match ( string $pattern , string $subject [, array $matches [, int $flags ]] )
正则表达式

preg_replace()可用于删除所有 HTML 标签

1
2
3
4
5
<?php
$html = "<h1>Title</h1><p>Content</p>";
$plainText = preg_replace("/<[^>]+>/", "", $html); // 替换所有 HTML 标签
echo $plainText; // 输出 "TitleContent"
?>

PHP - 验证邮件

1
2
3
4
$email = test_input($_POST["email"]);
if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) {
$emailErr = "非法邮箱格式";
}

\w匹配任意字母、数字或下划线([a-zA-Z0-9_])

PHP - 验证 URL

以下代码将检测URL地址是否合法 (以下正则表达式运行URL中含有破折号:”-“), 如果 URL 地址不合法,将输出错误信息

1
2
3
4
$website = test_input($_POST["website"]);
if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {
$websiteErr = "非法的 URL 的地址";
}

PHP $GET和$POST变量

$_GET 变量

预定义的 $_GET 变量用于收集来自 method=”get” 的表单中的值

从带有 GET 方法的表单发送的信息,对任何人都是可见的(会显示在浏览器的地址栏),并且对发送信息的量也有限制

在 HTML 表单中使用 method=”get” 时,所有的变量名和值都会显示在 URL 中,,因此可以在收藏夹中收藏该页面,但在发送密码或其他敏感信息时,不应该使用这个方法

1
http://www.runoob.com/welcome.php?fname=Runoob&age=3

$_POST 变量

预定义的 $_POST 变量用于收集来自 method=”post” 的表单中的值

从带有 POST 方法的表单发送的信息,对任何人都是不可见的(不会显示在浏览器的地址栏),并且对发送信息的量也没有限制

注释:然而,默认情况下,POST 方法的发送信息的量最大值为 8 MB(可通过设置 php.ini 文件中的 post_max_size 进行更改)

变量不显示在 URL 中,所以无法把页面加入书签

1
http://www.runoob.com/welcome.php

$_REQUEST 变量

预定义的 $_REQUEST 变量包含了 $_GET、$_POST 和 $_COOKIE 的内容。

$_REQUEST 变量可用来收集通过 GET 和 POST 方法发送的表单数据

PHP 高级教程

PHP 包含文件

用于将一个文件的内容插入到另一个文件中

PHP include 和 require 语句

include 和 require 语句用于在执行流中插入写在其他文件中的有用的代码

include 和 require 除了处理错误的方式不同之外,在其他方面都是相同的:

require 生成一个致命错误(E_COMPILE_ERROR),在错误发生后脚本会停止执行。

include 生成一个警告(E_WARNING),在错误发生后脚本会继续执行。

因此,如果您希望继续执行,并向用户输出结果,即使包含文件已丢失,那么请使用 include。否则,在框架、CMS 或者复杂的 PHP 应用程序编程中,请始终使用 require 向执行流引用关键文件。

1
2
3
include 'filename';
或者
require 'filename';

实例

1

假设有一个标准的页头文件,名为 “header.php”。如需在页面中引用这个页头文件,请使用 include/require

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<?php include 'header.php'; ?>
<h1>欢迎来到我的主页!</h1>
<p>一些文本。</p>

</body>
</html>
2

假设我们有一个在所有页面中使用的标准菜单文件。

“menu.php”:

1
2
3
echo '<a href="/">主页</a>
<a href="/html">HTML 教程</a>
<a href="/php">PHP 教程</a>';

网站中的所有页面均应引用该菜单文件。以下是具体的做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<div class="leftmenu">
<?php include 'menu.php'; ?>
</div>
<h1>欢迎来到我的主页!</h1>
<p>一些文本。</p>

</body>
</html>
3

假设我们有一个定义变量的包含文件(”vars.php”):

1
2
3
4
<?php
$color='red';
$car='BMW';
?>

这些变量可用在调用文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<h1>欢迎来到我的主页!</h1>
<?php
include 'vars.php';
echo "I have a $color $car"; // I have a red BMW
?>

</body>
</html>

PHP 文件处理

打开文件

fopen() 函数用于在 PHP 中打开文件

1
2
3
<?php
$file=fopen("welcome.txt","r");
?>

此函数的第一个参数含有要打开的文件的名称,第二个参数规定了使用哪种模式来打开文件

模式 描述
r 只读。在文件的开头开始。
r+ 读/写。在文件的开头开始。
w 只写。打开并清空文件的内容;如果文件不存在,则创建新文件。
w+ 读/写。打开并清空文件的内容;如果文件不存在,则创建新文件。
a 追加。打开并向文件末尾进行写操作,如果文件不存在,则创建新文件。
a+ 读/追加。通过向文件末尾写内容,来保持文件内容。
x 只写。创建新文件。如果文件已存在,则返回 FALSE 和一个错误。
x+ 读/写。创建新文件。如果文件已存在,则返回 FALSE 和一个错误。

如果 fopen() 函数无法打开指定文件,则返回 0 (false),可通过下例生成一段消息

1
2
3
<?php
$file=fopen("welcome.txt","r") or exit("Unable to open file!");
?>

关闭文件

fclose() 函数用于关闭打开的文件

1
2
3
4
5
<?php
$file = fopen("test.txt","r");
//执行一些代码
fclose($file);
?>

检测文件末尾(EOF)

feof() 函数检测是否已到达文件末尾(EOF)

1
if (feof($file)) echo "文件结尾";

在 w 、a 和 x 模式下,无法读取打开的文件

逐行读取文件

fgets() 函数用于从文件中逐行读取文件,在调用该函数之后,文件指针会移动到下一行

1
2
3
4
5
6
7
8
9
<?php
$file = fopen("welcome.txt", "r") or exit("无法打开文件!");
// 读取文件每一行,直到文件结尾
while(!feof($file))
{
echo fgets($file). "<br>";
}
fclose($file);
?>

逐字符读取文件

fgetc() 函数用于从文件中逐字符地读取文件,在调用该函数之后,文件指针会移动到下一个字符

1
2
3
4
5
6
7
8
<?php
$file=fopen("welcome.txt","r") or exit("无法打开文件!");
while (!feof($file))
{
echo fgetc($file);
}
fclose($file);
?>

PHP 文件上传

创建一个文件上传表单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>

</body>
</html>

[!IMPORTANT]

enctype

在 HTML 表单中,enctype 属性用于指定表单数据在发送到服务器时的编码类型。这个属性主要在使用 POST 方法时生效,决定了表单中数据如何被格式化。下面是常用的enctype值:

描述
application/x-www-form-urlencoded 默认值。表单数据会被编码为键值对(键和值通过 = 连接,不同键值对通过 & 连接)以 URL 编码的形式发送到服务器。适用于普通表单(比如文本输入)
multipart/form-data 用于上传文件时。数据会以分段形式进行编码,每段包含一个表单控件的数据。必须在表单中使用 method="post"enctype="multipart/form-data" 才能上传文件
text/plain 表单数据以纯文本形式进行编码(键值对以 = 连接,不同键值对通过换行符分隔)不会对特殊字符进行编码

<input> 标签的 type=”file” 属性规定了应该把输入作为文件来处理。举例来说,当在浏览器中预览时,会看到输入框旁边有一个浏览按钮。

创建上传脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if ($_FILES["file"]["error"] > 0)
{
echo "错误:" . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"];
}
?>

通过使用 PHP 的全局数组 $_FILES,可以从客户计算机向远程服务器上传文件

[!IMPORTANT]

$_FILES

第一个参数是表单的 input name,第二个下标可以是 “name”、”type”、”size”、”tmp_name” 或 “error”

字段 说明 示例
$_FILES['file']['name'] 上传文件的原始名称(包括扩展名) example.jpg
$_FILES['file']['type'] 上传文件的 MIME 类型(例如 image/jpegtext/plain image/jpeg
$_FILES['file']['size'] 上传文件的大小,以字节为单位 102400 (100 KB)
$_FILES['file']['tmp_name'] 文件上传后存储在服务器上的临时文件名 /tmp/phpY9k1b9
$_FILES['file']['error'] 上传过程中发生的错误代码 UPLOAD_ERR_OK (0)
常见的error错误代码
错误代码 说明 错误数字
UPLOAD_ERR_OK 文件上传成功 0
UPLOAD_ERR_INI_SIZE 上传的文件超过了 PHP 配置文件 upload_max_filesize 的限制 1
UPLOAD_ERR_FORM_SIZE 上传的文件超过了 HTML 表单设置的 MAX_FILE_SIZE 的限制 2
UPLOAD_ERR_PARTIAL 文件部分上传(可能由于网络中断等原因) 3
UPLOAD_ERR_NO_FILE 没有文件被上传 4
UPLOAD_ERR_NO_TMP_DIR PHP 缺少临时文件夹 6
UPLOAD_ERR_CANT_WRITE PHP 无法写入文件到磁盘 7
UPLOAD_ERR_EXTENSION 上传被 PHP 扩展程序阻止 8

上传限制

限制文件上传的格式(如.gif、.png)及上传文件的大小

保存被上传的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
// 允许上传的图片后缀
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
echo $_FILES["file"]["size"];
$extension = end($temp); // 获取文件后缀名
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 204800) // 小于 200 kb
&& in_array($extension, $allowedExts))
{
if ($_FILES["file"]["error"] > 0)
{
echo "错误:: " . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>";

// 判断当前目录下的 upload 目录是否存在该文件
// 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " 文件已经存在。 ";
}
else
{
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
}
}
}
else
{
echo "非法的文件格式";
}
?>

[!IMPORTANT]

in_array($extension, $allowedExts)

用于检查文件扩展名是否在允许的扩展名列表中

$extension,即文件扩展名,$allowedExts,即允许的扩展名列表

cookie 常用于识别用户

cookie 是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时,这台计算机将会发送 cookie

创建Cookie

setcookie() 函数用于设置 cookie,setcookie() 函数必须位于 <html> 标签之前

1
setcookie(name, value, expire, path, domain);
实例

创建名为 “user” 的 cookie,并为它赋值 “runoob”,规定了此 cookie 在一小时后过期

1
2
3
4
5
6
<?php
setcookie("user", "runoob", time()+3600);
?>

<html>
.....

[!CAUTION]

在发送 cookie 时,cookie 的值会自动进行 URL 编码,在取回时进行自动解码(为防止 URL 编码,请使用 setrawcookie() 取而代之)

[!TIP]

可以通过另一种方式设置 cookie 的过期时间(比使用秒表示的方法简单)

1
2
3
4
<?php
$expire=time()+60*60*24*30;
setcookie("user", "runoob", $expire);
?>

在上面的实例中,过期时间被设置为一个月(60 秒 * 60 分 * 24 小时 * 30 天

取回Cookie的值

PHP 的 $_COOKIE 变量用于取回 cookie 的值

在下面的实例中,我们取回了名为 “user” 的 cookie 的值,并把它显示在了页面上:

1
2
3
4
5
6
7
<?php
// 输出 cookie 值
echo $_COOKIE["user"];

// 查看所有 cookie
print_r($_COOKIE);
?>

在下面的实例中,我们使用 isset() 函数来确认是否已设置了 cookie:

1
2
3
4
5
6
<?php
if (isset($_COOKIE["user"]))
echo "欢迎 " . $_COOKIE["user"] . "!<br>";
else
echo "普通访客!<br>";
?>

删除Cookie

当删除 cookie 时,应当使过期日期变更为过去的时间点

1
2
3
4
<?php
// 设置 cookie 过期时间为过去 1 小时
setcookie("user", "", time()-3600);
?>

浏览器不支持Cookie

一种解决方式是通过表单传递数据

PHP Session

PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置。Session 变量存储单一用户的信息,并且对于应用程序中的所有页面都是可用的

与 Cookie 不同,Session 的数据存储在服务器

Session 的工作机制是:为每个访客创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。

开始PHP Session

把用户信息存储到 PHP session 中之前,首先必须启动会话。

注:session_start() 函数必须位于 <html> 标签之前:

1
2
3
4
5
6
7
<?php session_start(); ?>

<html>
<body>

</body>
</html>

上面的代码会向服务器注册用户的会话,以便可以开始保存用户信息,同时会为用户会话分配一个 UID

存储和读取 Session 数据

使用 PHP $_SESSION 变量

1
2
3
4
5
6
7
8
9
10
<?php
session_start();

// 读取 Session 数据
if (isset($_SESSION['username'])) {
echo "用户名: " . $_SESSION['username']; // 输出: 用户名: Alice
} else {
echo "用户名未设置。";
}
?>

销毁Session

可以使用 unset() 或 session_destroy() 函数删除某些 session 数据

unset()

删除 $_SESSION 里的指定数据

1
2
3
4
5
6
7
<?php
session_start();
if(isset($_SESSION['views']))
{
unset($_SESSION['views']);
}
?>
session_unset()

清空所有会话数据但保留会话本身(即不会删除 Session ID 或终止会话)

session_destroy()

终止会话并删除服务器端的会话数据(如存储在 $_SESSION 中的所有数据)然而,它不会立即清空 $_SESSION 数组中的数据,也不会删除客户端的 Session ID Cookie

1
2
3
<?php
session_destroy();
?>

[!TIP]

如果 session_destroy() 后还需要删除客户端的会话 Cookie

1
setcookie(session_name(), '', time() - 3600); // 删除客户端 Cookie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
session_start(); // 开启会话

// 清空所有 Session 数据
session_unset();

// 销毁会话
session_destroy();

// 删除客户端的 Session ID Cookie
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 3600,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}

echo "会话已销毁,客户端的 Session Cookie 已删除。";
?>

PHP 数据库