基础知识
变量知识
定义变量
PHP是弱类型语言,不需要对变量进行类型声明。PHP中以 $ 作为前缀来定义变量,以a~z(大小写)或 _ 下划线、数字(首字符不能为数字)定义变量名。
传值与引用
传值赋值
直接使用 = 将变量的值赋值给另一个变量。
$a = 1;
$b = $a;
$b = 2;
echo $a;//结果是1引用赋值
将一个变量的内存地址赋值给另一个变量的行为即传址赋值。需要在 = 等号前加上 & 引用符号,这样两个变量指向内存中的一个地址,任何一个变量的改变都影响到另一个变量,有点类似于快捷方式的概念。
$num = 166;
$math = &$num; // 声明一个对变量$num的引用$math
echo $math; // 输出:166
unset($math); // 取消引用$math
echo $num; // 输出:166可变变量
可以变量即使用一个变量的值,作为另一个变量名。
$a = 'hello'; //普通变量
$$a = 'world'; //可变变量 相当于:$hello = ‘world’;
echo "$a ${$a}";//输出:hello world
echo "$a $hello";//输出:hello world变量作用域
超全局变量
可以代码的任何位置都可以访问的变量
| 变量 | 说明 |
|---|---|
| $_GET | 地址栏GET提交 |
| $_POST | 表单POST提交 |
| $_FILES | 文件上传变量 |
| $_SESSION | 会话变量 |
| $_COOKIE | cookie值变量 |
| $_GLOBALS | 全局变量 |
| $_REQUEST | 包含$_GET、$_POST、$_COOKIE |
| $_SERVER | 服务器环境变量 |
全局变量
全局声明(函数外声明)的变量会保存在 $_GLOBALS 中,函数内默认不能访问到全局变量,在函数中访问需要使用 global 关键字。
$name = 'PHP';
function show()
{
//利⽤ global 引入全局变量
global $name;
var_dump($name);
// 或者使用全局$GLOBALS['name'];
var_dump($GLOBALS['name']);
}
show();也可以使用全局数组$GLOBALS调用全局变量。 如: $GLOBALS['name'];
变量销毁
php在全部代码执行结束后会删除所有变量,也使用 unset 函数可以在程序运行中删除变量。
全局变量不能在函数中删除
$name = 'PHP';
function run()
{
global $name;
unset($name);
}
run();
echo $name; // 依然输出 PHP静态变量
PHP支持声明函数变量为静态的(static)。一个静态变量在所有对该函数的调用之间共享,并且仅在脚本的执行期间函数第一次被调⽤时被初始化。 要声明函数变量为静态的⽤关键字static。通常静态变量的第一次使用时赋予⼀个初始值。
function calculate()
{
static $a = 1;
return ++$a;
}
calculate();
echo calculate(); // 输出 3$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 | 对象 |
整型
整型可以是十进制、八进制、十六进制。
$int1 = 2022; // 十进制整数,输出2022
$int2 = 01223; // 八进制整数,输出659
$int3 = 0x1223; // 十六进制整数,输出4643下面是 777 八进制数转成 十进制数,即逢8进1原则,PHP中使用 octdec() 函数可以将八进制转为十进制。
echo octdec(777); // 78^2+78^1+7*8^0 = 511下面是十六进制 FAF 转为十进制数,PHP中使用hexde()函数将十六进制转为十进制
echo hexdec('FAF'); // 15*16^2+10*16^1+15*16^0 = 4015浮点型
浮点数表示实数,可理解为有限或无限小数。
0.12
-10.98布尔型
真:非0数字、非0字符串、' '(空格符)、'0.0'、'false' 假:0 0.0 '' null '0' []
以下情况都为false:
- 布尔值 FALSE
- 整型值 0(零)
- 浮点型值 0.0(零)
- 空白字符串
- 字符串 "0"
- 没有成员变量的数组 []
- 没有单元的对象(仅适用于 PHP 4)
- 特殊类型 NULL(包括尚未设定的变量)
所有其它值都被认为是 TRUE
echo true; // 输出:1
echo false; // 输出:空字符串(浏览器看不到任何信息)
echo '' ? '我是真的' : '我是假的'; // 我是假的
echo ' ' ? '我是真的' : '我是假的'; // 我是真的
echo '0' ? '我是真的' : '我是假的'; // 我是假的
echo '0.0' ? '我是真的' : '我是假的'; // 我是真的
echo 'false' ? '我是真的' : '我是假的'; // 我是真的字符串
引号
字符串可以用双引号 "" 或 '' 号包含,区别是双引号中可以解析变量。
$url = 'php.net';
echo "PHP官网: {$url}";声明utf-8编码格式解决输出中文乱码问题
header("Content-type: text/html; charset=utf-8");定界符
在定界符文本中不需要转义引号,适合输入大量文本。
结束符必须从第一列开始,并且后面除了分号以外不能包含任何其他字符,空格也不可以。
$string = <<<eof
<h1>这是使用定界符输入的内容</h1>
eof;
echo $string;常用函数
strlen — 取得字符串长度传度的函数
echo strlen('www.baidu.com'); // 13mb_strlen — 根据字符编码获取长度
echo mb_strlen('开源中国'); // 4,如果没开启默认utf8,一个汉字代表4个字符,这里会输出:16
echo mb_strlen('开源中国', 'utf8'); // 4
echo mb_strlen('开源中国', 'gbk'); // 7trim — 截去字符串首尾的内容
$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); // 9rtrim从右侧删除、ltrim从左侧删除
strtolower — 字母转为小写
echo strtolower('FOO.COM'); // foo.comstrtoupper — 字母转大写
echo strtoupper('foo.com'); // FOO.COMucfirst — 将字符串的首字母转换为大写
$string = 'hello';
echo ucfirst($string); // Helloucwords — 将字符串中每个单词的首字母转换为大写
$string = 'hello world';
echo ucwords($string); // Hello World
$string = 'hello_world';
echo ucwords($string,'_'); // Hello_World
echo str_replace('_',' ',ucwords($string,'_')); // Hello Worldmd5 — 计算字符串的 MD5 散列值,以 32 字符十六进制数字形式返回散列值
$file = md5('user-1-info') . '.php';
echo $file; // 2c469e8688dca662650f4ed060ecec7f.phpexplode — 使用一个字符串分割另一个字符串
$ids = '1,2,3,4,5,6';
$array = explode(',', $ids);
echo $array[1]; // 2implode — 将一个一维数组的值转化为字符串
$array = ['user', 'admin'];
echo implode(': ', $array); // user: adminsubstr — 返回字符串的子串
$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); // jpmb_substr — 获取部分字符串
echo mb_substr('你好广州', 2, 2); // 广州strstr — 查找字符串的首次出现
echo strstr('admin@foo.com', '@'); // @foo.comstrrchr — 查找指定字符在字符串中的最后一次出现
echo strrchr('foo.tar.gz', '.'); // .gzstrpos — 查找字符串首次出现的位置,如果没找到,将返回 FALSE
echo strpos('foo.com', 'o'); // 1strrpos — 计算指定字符串在目标字符串中最后一次出现的位置
echo strrpos('foo.com', 'o'); // 5str_replace — 子字符串替换
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 - 把字符串重复指定的次数
echo str_repeat("Foo", 3); // FooFooFoonl2br - 将字符串中的换行符转换为HTML中的标签
$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表示大小写不敏感)来指定大小写是否敏感。
// 示例一
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()
const NAME = 'admin';
var_dump(defined('NAME')); // true
var_dump(defined('USER')); // false系统常量
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()
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。
$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() 的用法)
$var = 0;
echo $var ?: 'hello world'; #输出:hello world
$var = 0;
echo $var ?? 'hello world'; #输出:0错误控制运算符
@ 运算符用于屏蔽表达式警告错误
20 / 0; // 报错
@(20 / 0); // 不会报错流程控制
if/else/elseif
# 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为上面条件都不满足时执行的默认代码块。
$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中的语句或语句序列),直到满足一定的条件(表达式的结果为假时)后才停止执行该段程序。
$num = 10;
while ($num > 0) {
echo ($num--) . '<br/>';
}
// 也可以使用以下写法
$num = 10;
while ($num > 0):
echo ($num--) . '<br/>';
endwhile;do...while
与while的差别是条件后判断。(至少执行一次)
$num = 10;
do {
echo ($num--) . '<br/>';
} while ($num > 0);for
for (表达式1; 表达式2; 表达式3) {
语句或语句序列;
}
// 表达式1为循环初始条件
// 表达式2为循环控制条件
// 表达式3为控制变量递增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 循环结构中时,将会使得程序离开该层循环。
do {
if (!isset($num)) {
$num = 10;
}
if ($num == 0) {
break;
}
echo ($num--) . '<br/>';
} while (true);break 在多层循环嵌套使用时,可以指定跳转出层数。
$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 时,之后的语句将直接被略过,而直接执行下一次的循环动作。
for ($num = 10; $num > 0; $num--) {
if (!($num % 2)) continue;
echo $num . '<br/>';
}文件引入
include & require
使用include和require 将文件导入,就像把该文件粘贴到使用函数的地方。
include()与require ()区别在于,错误处理方式,当引入时:
- include()产生一个
- require()则导致一个
include()示例:
include '1.html';
$kw = 'World';
echo $kw; # 文件不存在,或者里面的变量未定义,会报一个warning错误,但是可以输出World<h1>Hello <?php echo $kw; ?></h1>可以使用 @ 屏蔽include加载警告错误
$name = 'World';
if (!@include 'index.html') {
include 'default.html';
}require 加载失败时将终止程序执行
require './foo.php';
echo 'foo'; // 如果foo.php文件不存在会报一个false错误,不可以输出fooinclude_once & require_once
与include()语句及require()区别是如果文件已经加载过,则不会重复加载文件。
// 因为 include 每次都加载所以下面两行代码执行会报错
include './functions.php';
include './functions.php';
// 下面使用 include_once 就不会报错
include_once './functions.php';
include_once './functions.php';日期与时间
时区
时间根据不同国家以时区划分,下面是中国可用的时区。因为我国不区分时区所以以下用哪个都可以。
| 时间 | 说明 |
|---|---|
| PRC | People’s Republic of China,中华人民共和国 |
| Asia/chongqing | 重庆 |
| Asia/shanghai | 上海 |
| Asia/urumqi | 乌鲁木齐 |
设置时区
PHP.ini配置(不推荐使用,因为有些服务器是改不了配置项的)date.timezone = PRC
脚本中修改 (推荐使用)
date_default_timezone_get():取得当前使用时区
date_default_timezone_set():设定当前使用时区
date_default_timezone_set("PRC");
echo date('y-m-d H:i:s');UNIX时间戳
PHP的时间戳开始于1970年1月1日零点,默认为10位整数数值。
time
返回当前Unix 时间戳秒数,1毫秒等于一千分之一秒。
echo time();microtime
返回当前 Unix 时间戳和微秒数。1微秒等于一百万分之一秒。
$microtime = microtime(); // 0.61717500 1629130970;
list($usec, $sec) = explode(" ", $microtime);
echo $sec . '<=>' . $usec;
# 1629130970<=>0.61717500设置参数为TRUE返回浮点数
echo microtime(true); // 1629131067.0081脚本执行时间
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
格式化一个本地时间/日期
echo date('Y-m-d h:i:s'); // 2021-08-17 12:30:26通过第二个参数设置处理的时间
echo date('Y-m-d', time() + 3600 * 24 * 100); // 2021-11-25参数说明
| 参数 | 说明 | 返回值 |
|---|---|---|
| Y | 4 位数字完整表示的年份 | 例如:1999 或 2003 |
| y | 2 位数字表示的年份 | 例如: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
取得日期/时间信息
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 时间戳
// 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时间计算
可以获取计算后的时间格式参数
//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内置对象的开源产品,功能丰富使用简单。
- 简单使用
// 定义时区,当然也可以使用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- 根据时间戳生成时间
$dateTime = new DateTime();
$dateTime->setTimestamp(time());
echo $dateTime->format('Y-m-d H:i:s'); // 2021-08-17 00:53:13- 创建不规则时间
根据给定的格式解析日期时间字符串,用于对不规则日期时间格式处理。
$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- 获取时间差
$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小时。
$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
进一法取整
echo ceil(10.2); // 11floor
向下取整
echo floor(10.2); // 10max
找出最大值
echo max(1, 3); // 3min
找出最小值。
echo min(1, 3);// 1下面是获取页码的逻辑,并对用户参数进行了验证处理,防止出现负数与超过总页码100的数值。
echo min(100, max(1, $_GET['page'] ?? 1));round
对浮点数进行四舍五入处理。
echo round(12.567, 2); // 12.57mt_rand
生成更好的随机数,下面是生成验证码随机数示例。
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); // 71MH6cookie
PHP设置Cookie最常用的方法就是使用setcookie函数,setcookie具有7个可选参数,我们常用到的为前5个:
name( Cookie名)可以通过$_COOKIE['name'] 进行访问
value(Cookie的值)
expire(过期时间)Unix时间戳格式,默认为0,表示浏览器关闭即失效
path(有效路径)如果路径设置为'/',则整个网站都有效
domain(有效域)默认整个域名都有效,如果设置了'www.imooc.com',则只在www子域中有效$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。
setrawcookie('cookie_name', rawurlencode($value), time()+60*60*24*365);因为Cookie是通过HTTP标头进行设置的,所以也可以直接使用header方法进行设置。
header("Set-Cookie:cookie_name=value");cookie的删除与过期时间
php中没有删除Cookie的函数,在PHP中删除cookie也是采用setcookie函数来实现。
setcookie('test', '', time()-1);将cookie的过期时间设置到当前时间之前,则该cookie会自动失效,也就达到了删除cookie的目的。之所以这么设计是因为cookie是通过HTTP的标头来传递的,客户端根据服务端返回的Set-Cookie段来进行cookie的设置,如果删除cookie需要使用新的Del-Cookie来实现,则HTTP头就会变得复杂,实际上仅通过Set-Cookie就可以简单明了的实现Cookie的设置、更新与删除。
了解原理以后,我们也可以直接通过header来删除cookie。
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的读写。
session_start();
$_SESSION['test'] = time();
var_dump($_SESSION);session会自动的对要设置的值进行encode与decode,因此session可以支持任意数据类型,包括数据与对象等。
session_start();
$_SESSION['ary'] = array('name' => 'jobs');
$_SESSION['obj'] = new stdClass();
var_dump($_SESSION);默认情况下,session是以文件形式存储在服务器上的,因此当一个页面开启了session之后,会独占这个session文件,这样会导致当前用户的其他并发访问无法执行而等待。可以采用缓存或者数据库的形式存储来解决这个问题.
删除与销毁session
删除某个session值可以使用PHP的unset函数,删除后就会从全局变量$_SESSION中去除,无法访问。
session_start();
$_SESSION['name'] = 'jobs';
unset($_SESSION['name']);
echo $_SESSION['name']; //提示name不存在如果要删除所有的session,可以使用session_destroy函数销毁当前session,session_destroy会删除所有数据,但是session_id仍然存在。
session_start();
$_SESSION['name'] = 'jobs';
$_SESSION['time'] = time();
session_destroy();值得注意的是,session_destroy并不会立即的销毁全局变量$_SESSION中的值,只有当下次再访问的时候,$_SESSION才为空,因此如果需要立即销毁$_SESSION,可以使用unset函数。
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中,一般的会单独的将一些重要的字段单独存储,然后所有的用户信息独立存储。
$_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的异常基类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信息
}