Skip to content

基础知识

变量知识

定义变量

PHP是弱类型语言,不需要对变量进行类型声明。PHP中以 $ 作为前缀来定义变量,以a~z(大小写)或 _ 下划线、数字(首字符不能为数字)定义变量名。

传值与引用

传值赋值

直接使用 = 将变量的值赋值给另一个变量。

php
$a = 1;
$b = $a;
$b = 2;
echo $a;//结果是1

引用赋值

将一个变量的内存地址赋值给另一个变量的行为即传址赋值。需要在 = 等号前加上 & 引用符号,这样两个变量指向内存中的一个地址,任何一个变量的改变都影响到另一个变量,有点类似于快捷方式的概念。

php
$num = 166;
$math = &$num;  // 声明一个对变量$num的引用$math
echo $math;   // 输出:166
unset($math);   // 取消引用$math
echo $num;  // 输出:166

可变变量

可以变量即使用一个变量的值,作为另一个变量名。

php
$a = 'hello';	//普通变量
$$a = 'world';	//可变变量 相当于:$hello = ‘world’;
echo "$a ${$a}";//输出:hello world
echo "$a $hello";//输出:hello world

变量作用域

超全局变量

可以代码的任何位置都可以访问的变量

变量说明
$_GET地址栏GET提交
$_POST表单POST提交
$_FILES文件上传变量
$_SESSION会话变量
$_COOKIEcookie值变量
$_GLOBALS全局变量
$_REQUEST包含$_GET、$_POST、$_COOKIE
$_SERVER服务器环境变量

全局变量

全局声明(函数外声明)的变量会保存在 $_GLOBALS 中,函数内默认不能访问到全局变量,在函数中访问需要使用 global 关键字。

php
$name = 'PHP';
function show()
{
    //利⽤ global 引入全局变量
    global $name;
    var_dump($name);
    // 或者使用全局$GLOBALS['name'];
    var_dump($GLOBALS['name']);
}

show();

也可以使用全局数组$GLOBALS调用全局变量。 如: $GLOBALS['name'];

变量销毁

php在全部代码执行结束后会删除所有变量,也使用 unset 函数可以在程序运行中删除变量。

全局变量不能在函数中删除

php
$name = 'PHP';
function run()
{
    global $name;
    unset($name);
}

run();
echo $name; // 依然输出 PHP

静态变量

PHP支持声明函数变量为静态的(static)。一个静态变量在所有对该函数的调用之间共享,并且仅在脚本的执行期间函数第一次被调⽤时被初始化。 要声明函数变量为静态的⽤关键字static。通常静态变量的第一次使用时赋予⼀个初始值。

php
function calculate()
{
    static $a = 1;
    return ++$a;
}

calculate();
echo calculate();   // 输出 3
php
$person = 20;
function showPeople()
{
    static $person = 5;
    $person++;
    echo '再增加一位客户, 将会有 ' . $person . ' 位客户。<br>';
}

showPeople();
echo $person . '人员。<br>';
showPeople();

// 输出结果:
// 再增加一位客户, 将会有 6 位客户。
// 20人员。
// 再增加一位客户, 将会有 7 位客户。

数据类型

常用PHP数据类型表:

类型说明
integer整型
float浮点型
string字符串
boolean布尔型
array数组
object对象

整型

整型可以是十进制、八进制、十六进制。

php
$int1 = 2022;     // 十进制整数,输出2022
$int2 = 01223;    // 八进制整数,输出659
$int3 = 0x1223;   // 十六进制整数,输出4643

下面是 777 八进制数转成 十进制数,即逢8进1原则,PHP中使用 octdec() 函数可以将八进制转为十进制。

php
echo octdec(777);   // 78^2+78^1+7*8^0 = 511

下面是十六进制 FAF 转为十进制数,PHP中使用hexde()函数将十六进制转为十进制

php
echo hexdec('FAF');   // 15*16^2+10*16^1+15*16^0 = 4015

浮点型

浮点数表示实数,可理解为有限或无限小数。

php
0.12
-10.98

布尔型

真:非0数字、非0字符串、' '(空格符)、'0.0'、'false' 假:0 0.0 '' null '0' []

以下情况都为false:

  • 布尔值 FALSE
  • 整型值 0(零)
  • 浮点型值 0.0(零)
  • 空白字符串
  • 字符串 "0"
  • 没有成员变量的数组 []
  • 没有单元的对象(仅适用于 PHP 4)
  • 特殊类型 NULL(包括尚未设定的变量)

所有其它值都被认为是 TRUE

php
echo true;  // 输出:1
echo false; // 输出:空字符串(浏览器看不到任何信息)

echo '' ? '我是真的' : '我是假的'; // 我是假的
echo ' ' ? '我是真的' : '我是假的'; // 我是真的

echo '0' ? '我是真的' : '我是假的'; // 我是假的
echo '0.0' ? '我是真的' : '我是假的'; // 我是真的
echo 'false' ? '我是真的' : '我是假的'; // 我是真的

字符串

引号

字符串可以用双引号 "" 或 '' 号包含,区别是双引号中可以解析变量。

php
$url = 'php.net';
echo "PHP官网: {$url}";

声明utf-8编码格式解决输出中文乱码问题

php
header("Content-type: text/html; charset=utf-8");

定界符

在定界符文本中不需要转义引号,适合输入大量文本。

结束符必须从第一列开始,并且后面除了分号以外不能包含任何其他字符,空格也不可以。

php
$string = <<<eof
    <h1>这是使用定界符输入的内容</h1>
eof;
echo $string;

常用函数

strlen — 取得字符串长度传度的函数

php
echo strlen('www.baidu.com'); // 13

mb_strlen — 根据字符编码获取长度

php
echo mb_strlen('开源中国'); // 4,如果没开启默认utf8,一个汉字代表4个字符,这里会输出:16
echo mb_strlen('开源中国', 'utf8'); // 4
echo mb_strlen('开源中国', 'gbk'); // 7

trim — 截去字符串首尾的内容

php
$string = ' www.baidu.com ';
echo strlen($string); // 15

echo strlen(trim($string)); // 13

$new_string = trim($string, ' moc.'); // www.baidu
echo $new_string;

echo strlen($new_string); // 9

rtrim从右侧删除、ltrim从左侧删除

strtolower — 字母转为小写

php
echo strtolower('FOO.COM'); // foo.com

strtoupper — 字母转大写

php
echo strtoupper('foo.com'); // FOO.COM

ucfirst — 将字符串的首字母转换为大写

php
$string = 'hello';
echo ucfirst($string); // Hello

ucwords — 将字符串中每个单词的首字母转换为大写

php
$string = 'hello world';
echo ucwords($string); // Hello World

$string = 'hello_world';
echo ucwords($string,'_'); // Hello_World

echo str_replace('_',' ',ucwords($string,'_')); // Hello World

md5 — 计算字符串的 MD5 散列值,以 32 字符十六进制数字形式返回散列值

php
$file = md5('user-1-info') . '.php';
echo $file; // 2c469e8688dca662650f4ed060ecec7f.php

explode — 使用一个字符串分割另一个字符串

php
$ids = '1,2,3,4,5,6';
$array = explode(',', $ids);
echo $array[1]; // 2

implode — 将一个一维数组的值转化为字符串

php
$array = ['user', 'admin'];
echo implode(': ', $array); // user: admin

substr — 返回字符串的子串

php
$file = 'profile.jpg';
echo substr($file, 7); // .jpg
echo substr($file, 0, 7); // profile
echo substr($file, 0, -4); // profile
echo substr($file, 3, -1); // file.jp
echo substr($file, 3, -5); // fil
echo substr($file, -3, -1); // jp

mb_substr — 获取部分字符串

php
echo mb_substr('你好广州', 2, 2); // 广州

strstr — 查找字符串的首次出现

php
echo strstr('admin@foo.com', '@'); // @foo.com

strrchr — 查找指定字符在字符串中的最后一次出现

php
echo strrchr('foo.tar.gz', '.'); // .gz

strpos — 查找字符串首次出现的位置,如果没找到,将返回 FALSE

php
echo strpos('foo.com', 'o'); // 1

strrpos — 计算指定字符串在目标字符串中最后一次出现的位置

php
echo strrpos('foo.com', 'o'); // 5

str_replace — 子字符串替换

php
echo str_replace('abc', 'xyz', 'abc.com'); // 返回 xyz.com
echo str_replace(['小猫', '小狗'], '*', '我家有一只可爱的小猫和小狗'); // 我家有一只可爱的*和*
echo str_replace(['小猫', '小狗'], ['猫猫', '旺旺'], '我家有一只可爱的小猫和小狗'); // 我家有一只可爱的猫猫和旺旺

// 把 \n 替换成 <br/>
$content = '\n';
$str1 = str_replace('\n', '<br/>', $content); // 替换成功
$str2 = str_replace("\n", '<br/>', $content); // 替换失败

str_repeat - 把字符串重复指定的次数

php
echo str_repeat("Foo", 3); // FooFooFoo

nl2br - 将字符串中的换行符转换为HTML中的标签

php
$original = "This is the first line.
This is the second line.";
$new = nl2br($original);
echo $new;
// This is the first line.<br> This is the second line.

empty()和isset()的区别

  • isset检测变量是否设置,并且不是 NULL
  • empty检查一个变量是否为空
以下的东西被认为是空的:

"" (空字符串)
0 (作为整数的0)
0.0 (作为浮点数的0)
"0" (作为字符串的0)
NULL
FALSE
array() (一个空数组)
$var; (一个声明了,但是没有值的变量)

常量

两种方式定义:函数define()、语言结构const

const 常量

(1) 在定义时必须被初始值
(2) 前面不加任何修饰符
(3) 变量名字母一般都大写
(4) 常量可以被子类继承
(5) 一个常量是属于一个类的,而不是某个对象的

const与define()区别

  • const用于类成员变量,一经定义不可修改
  • define用于全局常量,不可用于类成员变量的定义
  • const可在类中使用,define不能
  • const定义的常量大小写敏感,而define可通过第三个参数(为true表示大小写不敏感)来指定大小写是否敏感。
php
// 示例一
define('NAME', 'admin');
define('account', 'root', false); // 第三个参数:true 不区分大小写 false 严格区分大小写
echo account; // root
echo ACCOUNT; // undefined
define('DATA', [1, 2, 3]);
print_r(DATA); // Array ( [0] => 1 [1] => 2 [2] => 3 )

// 示例二
const NAME = 'admin';
function show()
{
    echo NAME;
}
show(); // admin

常量检测:defined()

php
const NAME = 'admin';
var_dump(defined('NAME')); // true
var_dump(defined('USER')); // false

系统常量

php
echo __FILE__;  // D:\www\index.php
echo PHP_VERSION; // 7.3.4
echo PHP_OS; // WINNT | Linux

// TRUE FALSE true false

class Demo
{
    public function show()
    {
        echo __CLASS__; // Demo
        echo __FUNCTION__; // show
        echo __LINE__;  // 15
    }
}

(new Demo)->show();

查看系统常量get_defined_constants()

php
echo '<pre>';
// 示例一
print_r(get_defined_constants());
print_r(get_defined_constants(true)); // 分组显示

// 示例二
echo '<pre>';
define('NAME', 'admin');
const URL = 'http://foo.com';
print_r(get_defined_constants(true)['user']);

运算符

逻辑运算符

运算符说明
$a and $b逻辑与 TRUE,如果 $a 与 $b 都为 TRUE
$a or $b逻辑或 TRUE,如果 $a 或 $b 任一为TRUE
!$a逻辑非 TRUE,如果 $a 不为 TRUE
$a && $b逻辑与 TRUE,如果 $a 与 $b 都为TRUE
$a || $b逻辑或 TRUE,如果 $a 或 $b 任一为TRUE
$a <=> $b如果$a 小于、等于或大于 $b 时,它分别返回 -1 0 1

and与&& 、or与||是同一逻辑运算符的两种写法,但优先级不同。

这四个符号的优先允许从高到低是:&&、||、AND、OR。

php
$a = 7; // 7的二进制代码是 111
$b = 4; // 4的二进制代码是 100
echo '$a & $b = ' . ($a & $b) . '<br/>';    // 运算结果为二进制代码100,即4
echo '$a | $b = ' . ($a | $b) . '<br/>';    // 运算结果为二进制代码111,即7
echo '$a ^ $b = ' . ($a ^ $b) . '<br/>';    // 运算结果为二进制代码011,即3

三元表达式

?:(PHP7新特性)

只判断 true 或 false

不判断变量是否存在,注意变量不存在,会报错的情况

??(null合并操作符)(PHP7新特性)

判断变量存在,并且值不为null。(等同于 isset() 的用法)

php
$var = 0;
echo $var ?: 'hello world'; #输出:hello world

$var = 0;
echo $var ?? 'hello world'; #输出:0

错误控制运算符

@ 运算符用于屏蔽表达式警告错误

php
20 / 0; // 报错

@(20 / 0); // 不会报错

流程控制

if/else/elseif

php
# if else
if (true) {
    echo '真';
} else {
    echo '假';
}

// 也可以使用以下写法
if (true) :
    echo '真';
else :
    echo '假';
endif;

# if elseif
$age = 10;
if ($age <= 15) {
    echo '儿童';
} elseif ($age <= 30) {
    echo '青年';
} elseif ($age <= 50) {
    echo '中年';
} else {
    echo '尊敬的老人';
}

// 也可以使用以下写法
$age = 10;
if ($age <= 15) :
    echo '儿童';
elseif ($age <= 30) :
    echo '青年';
elseif ($age <= 50) :
    echo '中年';
else :
    echo '尊敬的老人';
endif;

switch

switch设置多个执行代码块,break指令终止向下执行,default为上面条件都不满足时执行的默认代码块。

php
$status = 'warning';

switch ($status) {
    case 'success':
        echo '成功';
        break;
    case 'error':
        echo '错误';
        break;
    case 'warning':
        echo '警告';
        break;
    default:
        echo '默认';
        break;
}

// 也可以使用以下写法
switch ($status) :
    case 'success':
        echo '成功';
        break;
    case 'error':
        echo '错误';
        break;
    case 'warning':
        echo '警告';
        break;
    default:
        echo '默认';
        break;
endswitch;

当然 case 也可以使用 比较运算符: > < >= <= != 这些,跟 if elseif 等同(不推荐)

while

当while循环语句中表达式(循环控制语句)的结果为真时,程序将反复执行同一段程序:循环体( while中的语句或语句序列),直到满足一定的条件(表达式的结果为假时)后才停止执行该段程序。

php
$num = 10;
while ($num > 0) {
    echo ($num--) . '<br/>';
}

// 也可以使用以下写法
$num = 10;
while ($num > 0):
    echo ($num--) . '<br/>';
endwhile;

do...while

与while的差别是条件后判断。(至少执行一次)

php
$num = 10;
do {
    echo ($num--) . '<br/>';
} while ($num > 0);

for

text
for (表达式1; 表达式2; 表达式3) {
	语句或语句序列;
}
// 表达式1为循环初始条件
// 表达式2为循环控制条件
// 表达式3为控制变量递增
php
for ($num = 10; $num > 0; $num--) {
    echo $num . '<br/>';
}

// 也可以使用以下写法
for ($num = 10; $num > 0; $num--) :
    echo $num . '<br/>';
endfor;

break

break 使用在 for、while 或 do-while 循环结构中时,将会使得程序离开该层循环。

php
do {
    if (!isset($num)) {
        $num = 10;
    }
    if ($num == 0) {
        break;
    }
    echo ($num--) . '<br/>';
} while (true);

break 在多层循环嵌套使用时,可以指定跳转出层数。

php
$num = 0;
while (true):
    $num++;
    switch ($num) {
        case $num % 2 == 0:
            echo $num . "<br/>";
            break;
        case $num % 15 == 0:
            echo $num . "<br/>";
            break 2;
    }
endwhile;

continue

continue 的作用与 break 有点类似,continue 若使用在 for、while 或 do-while循环结构中,当程序执行至 continue 时,之后的语句将直接被略过,而直接执行下一次的循环动作。

php
for ($num = 10; $num > 0; $num--) {
    if (!($num % 2)) continue;
    echo $num . '<br/>';
}

文件引入

include & require

使用include和require 将文件导入,就像把该文件粘贴到使用函数的地方。

include()与require ()区别在于,错误处理方式,当引入时:

  • include()产生一个
  • require()则导致一个

include()示例:

php
include '1.html';
$kw = 'World';
echo $kw; # 文件不存在,或者里面的变量未定义,会报一个warning错误,但是可以输出World
html
<h1>Hello <?php echo $kw; ?></h1>

可以使用 @ 屏蔽include加载警告错误

php
$name = 'World';
if (!@include 'index.html') {
    include 'default.html';
}

require 加载失败时将终止程序执行

php
require './foo.php';
echo 'foo'; // 如果foo.php文件不存在会报一个false错误,不可以输出foo

include_once & require_once

与include()语句及require()区别是如果文件已经加载过,则不会重复加载文件。

php
// 因为 include 每次都加载所以下面两行代码执行会报错
include './functions.php';
include './functions.php';

// 下面使用 include_once 就不会报错
include_once './functions.php';
include_once './functions.php';

日期与时间

时区

时间根据不同国家以时区划分,下面是中国可用的时区。因为我国不区分时区所以以下用哪个都可以。

时间说明
PRCPeople’s Republic of China,中华人民共和国
Asia/chongqing重庆
Asia/shanghai上海
Asia/urumqi乌鲁木齐

设置时区

  • PHP.ini配置(不推荐使用,因为有些服务器是改不了配置项的)date.timezone = PRC

  • 脚本中修改 (推荐使用)

date_default_timezone_get():取得当前使用时区

date_default_timezone_set():设定当前使用时区

php
date_default_timezone_set("PRC");
echo date('y-m-d H:i:s');

UNIX时间戳

PHP的时间戳开始于1970年1月1日零点,默认为10位整数数值。

time

返回当前Unix 时间戳秒数,1毫秒等于一千分之一秒。

php
echo time();

microtime

返回当前 Unix 时间戳和微秒数。1微秒等于一百万分之一秒。

php
$microtime = microtime(); // 0.61717500 1629130970;
list($usec, $sec) = explode(" ", $microtime);
echo $sec . '<=>' . $usec;
# 1629130970<=>0.61717500

设置参数为TRUE返回浮点数

php
echo microtime(true); // 1629131067.0081

脚本执行时间

php
function runtime($start = null, $end = null)
{
    static $cache = [];
    if (is_null($start)) {
        return $cache;
    } elseif (is_null($end)) {
        return $cache[$start] = microtime(true);
    } else {
        $end = $cache[$end] ?? microtime(true);
        return $end - $cache[$start];
    }
}

//record
runtime('for');
for ($i = 0; $i < 20000000; $i++):
    $i++;
endfor;

//record
runtime('while');
$n = 0;
while ($n < 20000000):
    $n++;
endwhile;

echo runtime('for', true);
echo '<hr/>';
echo runtime('while', true);

date

格式化一个本地时间/日期

php
echo date('Y-m-d h:i:s'); // 2021-08-17 12:30:26

通过第二个参数设置处理的时间

php
echo date('Y-m-d', time() + 3600 * 24 * 100); // 2021-11-25

参数说明

参数说明返回值
Y4 位数字完整表示的年份例如:1999 或 2003
y2 位数字表示的年份例如:99 或 03
m数字表示的月份,有前导零01 到 12
n数字表示的月份,没有前导零1 到 12
d月份中的第几天,有前导零的 2 位数字01 到 31
j月份中的第几天,没有前导零1 到 31
H小时,24 小时格式,有前导零00 到 23
h小时,12 小时格式,有前导零01 到 12
i有前导零的分钟数00 到 59
s秒数,有前导零00 到 59

getdate

取得日期/时间信息

php
echo '<pre>';
print_r(getdate(strtotime("+1 day"))); // 获取1天后的时间数据
/**
 * Array
 * (
 * [seconds] => 46
 * [minutes] => 34
 * [hours] => 0
 * [mday] => 18
 * [wday] => 3
 * [mon] => 8
 * [year] => 2021
 * [yday] => 229
 * [weekday] => Wednesday
 * [month] => August
 * [0] => 1629218086
 * )
 */

strtotime

将任何字符串的日期时间描述解析为 Unix 时间戳

php
// ISO格式时间转为时间戳
echo strtotime('2021-08-17 00:37:36'); // 1629131856
echo '<br/>';
echo date("Y-m-d h:i:s", 1629131878); // 2021-08-17 12:37:58
echo '<br/>';
// 当前时间戳
echo strtotime('NOW'); // 1629131890
echo '<br/>';
echo date("Y-m-d H:i:s", strtotime('NOW')); // 2021-08-17 00:38:10

时间计算

可以获取计算后的时间格式参数

php
//1年加1天后的时间戳
echo strtotime('+1 day +1 year'); // 1660754663
echo '<br/>';
echo date("Y-m-d H:i:s", strtotime('+1 day +1 year')); // 2022-08-18 00:44:23
echo '<br/>';
//下周五
echo date("Y-m-d H:i:s", strtotime('next friday')); // 2021-08-20 00:00:00

对象操作

PHP提供了面向对象的操作日期时间的方式,Carbon就是基于PHP内置对象的开源产品,功能丰富使用简单。

  • 简单使用
php
// 定义时区,当然也可以使用date_default_timezone_set函数的
$prc = new DateTimeZone('PRC');
$dateTime = new DateTime();
$dateTime->setTimezone($prc);
echo $dateTime->format('Y-m-d H:i:s'); // 2021-08-17 00:51:05
echo '<br>';

// 直接设置时间
$dateTime = new DateTime('2049-11-11 12:12:12');
echo $dateTime->format('Y-m-d H:i:s'); // 2049-11-11 12:12:12
echo '<br>';

// 输出时间戳
echo $dateTime->format('U'); // 2520216732
echo '<br>';

// 重新时期与时间
$dateTime->setDate(2020, 10, 1);
$dateTime->setTime(10, 22, 12);
echo $dateTime->format('Y-m-d H:i:s'); // 2020-10-01 10:22:12
  • 根据时间戳生成时间
php
$dateTime = new DateTime();
$dateTime->setTimestamp(time());
echo $dateTime->format('Y-m-d H:i:s'); // 2021-08-17 00:53:13
  • 创建不规则时间

根据给定的格式解析日期时间字符串,用于对不规则日期时间格式处理。

php
$dateTime = DateTime::createFromFormat('Y/m-d His', '2020/12-13 081253');
echo $dateTime->format('Y-m-d H:i:s'); // 2020-12-13 08:12:53
  • 获取时间差
php
$dateTime1 = new DateTime();
$dateTime2 = new DateTime('2021-9-17');
$interval = $dateTime1->diff($dateTime2);
$format = '距离生日还有 <span style="color:red">%m个月%d天%h小时%i分钟%s秒</span> <br/>共%R%a天';
echo $interval->format($format); // 共+30天
# 说明 %R 显示+或-表示大于或小于,%a相差天数。
  • 添加时间

格式以字母P开始后面跟着一个周期指示器。如果包含时间元素则以字母T开始。比如 P2DT3H表示间隔2天3小时。

php
$date = new DateTime();
$interval = new DateInterval('P2DT2H5M');
echo $date->format('Y-m-d H:i') . "<br/>"; // 2021-08-17 00:56

//增加时间
$date->add($interval);
echo $date->format('Y-m-d H:i'); // 2021-08-19 03:01

//减少时间
echo "<br/>";
echo (new DateTime())->sub($interval)->format('Y-m-d H:i'); // 2021-08-14 22:51

数学函数

PHP提供了丰富的数学操作函数,下面我们介绍常用的函数使用,其他函数使用请参考手册

ceil

进一法取整

php
echo ceil(10.2); // 11

floor

向下取整

php
echo floor(10.2); // 10

max

找出最大值

php
echo max(1, 3); // 3

min

找出最小值。

php
echo min(1, 3);// 1

下面是获取页码的逻辑,并对用户参数进行了验证处理,防止出现负数与超过总页码100的数值。

php
echo min(100, max(1, $_GET['page'] ?? 1));

round

对浮点数进行四舍五入处理。

php
echo round(12.567, 2); // 12.57

mt_rand

生成更好的随机数,下面是生成验证码随机数示例。

php
function code(int $len = 5): string
{
    $str = 'abcdefghknm12345678';
    $code = '';
    for ($i = 0; $i < $len; $i++) {
        $index = mt_rand(0, strlen($str) - 1);
        $code .= strtoupper($str[$index]);
    }
    return $code;
}

echo code(5); // 71MH6

PHP设置Cookie最常用的方法就是使用setcookie函数,setcookie具有7个可选参数,我们常用到的为前5个:

text
name( Cookie名)可以通过$_COOKIE['name'] 进行访问
value(Cookie的值)
expire(过期时间)Unix时间戳格式,默认为0,表示浏览器关闭即失效
path(有效路径)如果路径设置为'/',则整个网站都有效
domain(有效域)默认整个域名都有效,如果设置了'www.imooc.com',则只在www子域中有效
php
$value = 'test';
setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600);  //有效期一小时
setcookie("TestCookie", $value, time()+3600, "/path/", "imooc.com"); //设置路径与域

PHP中还有一个设置Cookie的函数setrawcookie,setrawcookie跟setcookie基本一样,唯一的不同就是value值不会自动的进行urlencode,因此在需要的时候要手动的进行urlencode。

php
setrawcookie('cookie_name', rawurlencode($value), time()+60*60*24*365);

因为Cookie是通过HTTP标头进行设置的,所以也可以直接使用header方法进行设置。

php
header("Set-Cookie:cookie_name=value");

cookie的删除与过期时间

php中没有删除Cookie的函数,在PHP中删除cookie也是采用setcookie函数来实现。

php
setcookie('test', '', time()-1);

将cookie的过期时间设置到当前时间之前,则该cookie会自动失效,也就达到了删除cookie的目的。之所以这么设计是因为cookie是通过HTTP的标头来传递的,客户端根据服务端返回的Set-Cookie段来进行cookie的设置,如果删除cookie需要使用新的Del-Cookie来实现,则HTTP头就会变得复杂,实际上仅通过Set-Cookie就可以简单明了的实现Cookie的设置、更新与删除。

了解原理以后,我们也可以直接通过header来删除cookie。

php
header("Set-Cookie:test=1393832059; expires=".gmdate('D, d M Y H:i:s \G\M\T', time()-1));

这里用到了gmdate,用来生成格林威治标准时间,以便排除时差的影响。

session

在PHP中使用session非常简单,先执行session_start方法开启session,然后通过全局变量$_SESSION进行session的读写。

php
session_start();
$_SESSION['test'] = time();
var_dump($_SESSION);

session会自动的对要设置的值进行encode与decode,因此session可以支持任意数据类型,包括数据与对象等。

php
session_start();
$_SESSION['ary'] = array('name' => 'jobs');
$_SESSION['obj'] = new stdClass();
var_dump($_SESSION);

默认情况下,session是以文件形式存储在服务器上的,因此当一个页面开启了session之后,会独占这个session文件,这样会导致当前用户的其他并发访问无法执行而等待。可以采用缓存或者数据库的形式存储来解决这个问题.

删除与销毁session

删除某个session值可以使用PHP的unset函数,删除后就会从全局变量$_SESSION中去除,无法访问。

php
session_start();
$_SESSION['name'] = 'jobs';
unset($_SESSION['name']);
echo $_SESSION['name']; //提示name不存在

如果要删除所有的session,可以使用session_destroy函数销毁当前session,session_destroy会删除所有数据,但是session_id仍然存在。

php
session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
session_destroy();

值得注意的是,session_destroy并不会立即的销毁全局变量$_SESSION中的值,只有当下次再访问的时候,$_SESSION才为空,因此如果需要立即销毁$_SESSION,可以使用unset函数。

php
session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
unset($_SESSION);
session_destroy(); 
var_dump($_SESSION); //此时已为空

如果需要同时销毁cookie中的session_id,通常在用户退出的时候可能会用到,则还需要显式的调用setcookie方法删除session_id的cookie值。

使用session来存储用户的登录信息

session可以用来存储多种类型的数据,因此具有很多的用途,常用来存储用户的登录信息,购物车数据,或者一些临时使用的暂存数据等。

用户在登录成功以后,通常可以将用户的信息存储在session中,一般的会单独的将一些重要的字段单独存储,然后所有的用户信息独立存储。

php
$_SESSION['uid'] = $userinfo['uid'];
$_SESSION['userinfo'] = $userinfo;

一般来说,登录信息既可以存储在sessioin中,也可以存储在cookie中,他们之间的差别在于session可以方便的存取多种数据类型,而cookie只支持字符串类型,同时对于一些安全性比较高的数据,cookie需要进行格式化与加密存储,而session存储在服务端则安全性较高。

异常处理之异常处理类

PHP具有很多异常处理类,其中Exception所有异常处理的基类

Exception具有几个基本属性与方法,其中包括了:

message 异常消息内容
code 异常代码
file 抛出异常的文件名
line 抛出异常在该文件的行数

其中常用的方法有:

getTrace 获取异常追踪信息
getTraceAsString 获取异常追踪信息的字符串
getMessage 获取出错信息

如果必要的话,可以通过继承Exception类来建立自定义的异常处理类。

php
//自定义的异常类,继承了PHP的异常基类Exception
class MyException extends Exception
{
    function getInfo()
    {
        return '自定义错误信息';
    }
}

try {
    //使用异常的函数应该位于 "try"  代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
    throw new MyException('error');//这里规定如何触发异常。注意:每一个 "throw" 必须对应至少一个 "catch",当然可以对应多个"catch"
} catch (Exception $e) {//"catch" 代码块会捕获异常,并创建一个包含异常信息的对象
    echo $e->getInfo();//获取自定义的异常信息
    echo $e->getMessage();//获取继承自基类的getMessage信息
}
最近更新