主要内容:
- 变量的作用域及访问(全局vs函数,超全局)
- 常量、预定义常量、魔术常量、命名空间
- 变量过滤器(单变量、多变量,外部变量)
1. 变量的作用域及访问
(1)作用域(全局 vs 函数)
- 作用域是变量的生效范围。作用域是查找变量的工具。
- 作用域分为全局作用域、函数作用域。
- 超全局变量
error_reporting(E_ALL);
// 1.全局作用域: 写到了函数的外部的变量
$siteName = 'php中文网';
// 2. 函数作用域:
function getInfo()
{
// 访问函数外部的变量(全局变量)
// 在php,函数会创建出一个独立的作用域,不能直接访问外部的变量。例如下面如果直接发挥$siteName就不行。
// 私有变量
$local = 'hello php.cn';
// return $local;
}
echo getInfo();
(2)超全局变量
超全局变量,在每个脚本中都有预定义,例如$GLOBALS。若有变量都是超全局变量$GLOBALS这个数组array中的一个item。
// 超全局变量,在每个脚本中都有预定义
echo '<pre>'.print_r($GLOBALS,true).'</pre>';
// 通过上面的方式可以让现实出来的数组更具有结构性
// 在全局中创建的变量,会自动成为超全局数组$GLOBALS中的一个元素
echo $GLOBALS['siteName'];
// 超全局变量, 不受作用域限制,可以在函数中直接访问。
(3)函数访问全局变量的三种方式
- 第一种:函数中直接用global直接声明需要到外部去寻找
- 第二种:通过$GLOBALS数组来访问
- 第三种:用常量const的方式来体现。这种方式其实不算是一种直接的访问方式。仅仅是达到部分的效果而已。
const SITE_NAME = 'php中文网2';
function getInfo()
{
// 1. 在函数中做一个声明
global $siteName;
return $siteName;
// 2. 通过超全局变量$GLOBALS来访问
return $GLOBALS['siteName'];
// 3. 通过常量来实现
return SITE_NAME;
}
echo getInfo();
(4)文件路径查询
echo $_SERVER['REQUEST_URL'];
echo $_SERVER['SCRIPT_FILENAME'];
2. 常量
(1)常量的查看方式
(2)常量的两种创建方式
//关键字: const
const APP_PATH = '/phpstudy_pro';
// 函数define
define('APP_NAME', '客户管理系统');
//类常量只允许用const
class User
{
const NATION = 'CHINA';
}
(3)常量的定义规则
- 常量前没有$
- 常量必须初始化,变量则可以不用初始化赋值
- 常量不让删除,eg,unset(SEX);无效
- 常量不受作用域限制
- 常量推荐全部大写,多个单词之间使用下划线连接
const SEX = 'famale';
(4)常量的调取
echo APP_NAME;
echo '<hr>';
echo constant('APP_PATH');
echo '<hr>';
$name = 'APP_NAME';
echo constant($name);
echo '<hr>';
//两种还是有一些区别的:例如“空”作为常量名称是
//constant方式可以调取。但直接的那种方式无法调取。
// 定义一个特殊常量
// define('EMAIL', 'admin@php.cn');
define('', 'admin@php.cn');
// echo '';
echo constant('');
3. 预定义常量、魔术常量、命名空间
(1)预定义常量
echo '版本号: ' . PHP_VERSION . '<br>';
echo '操作系统: ' . PHP_OS_FAMILY . '<br>';
echo '最大整数: ' . PHP_INT_MAX . '<br>';
echo '最大浮点数: ' . PHP_FLOAT_MAX . '<br>';
echo '目录分隔符: ' . DIRECTORY_SEPARATOR . '<hr>';
(2)魔术常量
值是可以由系统变的,但用户自己是变不了的
echo '当前文件: ' . __FILE__ . '<br>';
echo '当前目录: ' . __DIR__ . '<br>';
echo '当前行号: ' . __LINE__ . '<br>';
序号 |
魔术常量 |
描述 |
1 |
__LINE__ |
文件中的当前行号 |
2 |
__FILE__ |
文件的完整路径和文件名 |
3 |
__DIR__ |
文件所在目录 |
4 |
__FUNCTION__ |
当前的函数名称 |
5 |
__CLASS__ |
当前类名称 |
6 |
__TRAIT__ |
当前Trait 名称 |
7 |
__METHOD__ |
当前类方法名称 |
8 |
__NAMESPACE__ |
当前命名空间名称 |
(3)命名空间
- 命名空间: 解决了全局成员 的命名冲突问题
- 在全局中常量需要具有唯一性。但在不同命名空间中,常量是一个用同一个名字的。
- 有点类似:二个班级, 都有一个叫张三的。一班的张三, 二班的张三。
- 针对的对象不限于常量,包括:常量、类(接口)、函数。这三(四)个就属于全局对象。
// error_reporting(E_ALL); 这个会和命名空间冲突。命名空间也需要放到第一行。
// 全局空间中的成员, 不允许重复定义
// const APP_PATH = '/phpstudy_pro';
// const APP_PATH = '/public';
//其实类与函数也是全局成员, 也不允许重复定义
namespace ns1 {
const APP_PATH = '/phpstudy_pro';
}
namespace ns2 {
const APP_PATH = '/public';
echo \ns1\APP_PATH, "<br>";
}
// 全局空间: 匿名空间
namespace {
echo \ns1\APP_PATH, "<br>";
echo \ns2\APP_PATH, "<br>";
}
4. 变量过滤器
- 变量过滤器感觉就是一个验证器,但变量的赋值不符合的时候就给于false反馈。例如验证年龄范围、性别范围、邮箱是否正确等。
- 可以用系统原生的底层过滤,也可以用一些外部已经封装好的东西。
- 具体内容还是挺多的,具体如下:
(4-1)查看当前php版本支持的预定义过滤器有哪些
foreach (filter_list() as $filter) {
echo $filter . ' => ' .filter_id($filter) . '<br>';
}
结果如下:
(4-2)过滤单个变量
filter_var(要过滤的变量, 过滤器常量)
$age = '130'; // 改成这个试试$age = 'abc';
$options = ['options'=>['min_range'=> 18, 'max_range'=> 60]];
var_dump(filter_var($age, FILTER_VALIDATE_INT, $options));
echo '<hr>';
$email = 'admin@php.cn';
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
var_dump(filter_var($email, 274));
//如果能找到代码,直接用代码进行验证也行。
- 也可以通过在浏览器域名的后面敲入“?age=..”的方式进行验证。如下图:
(4-3)验证多个变量 filter_var_array()
$a = 10;
$b = '90';
$arr = [$a, $b]; //变成一个数组。
var_dump(filter_var_array($arr, FILTER_VALIDATE_INT));
echo '<hr>';
(4-4)验证外部变量
- 通常通过 http请求发送过来的,表单,get,post
- 使用GET参数来演示外部变量的获取与验证/过滤
- filter_input(输入类型get/post, 变量名, 过滤器, 参数)
echo 'id = ' .$_GET['id'];
$options = ['options'=>['min_range'=> 1]];
var_dump(filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, $options));
// 同时验证多个外部变量
$args = [
'username'=> FILTER_SANITIZE_STRING,
'email'=>FILTER_VALIDATE_EMAIL,
'age'=> ['filter'=>FILTER_VALIDATE_INT, 'options'=>['min_range'=> 18, 'max_range'=> 60]],
'blog'=> FILTER_VALIDATE_URL
];
var_dump(filter_input_array(INPUT_GET, $args));
- 简洁操作方法(在浏览器域名输入框中直接输入)如下图:
(4-5)变量过滤器汇总
- PHP 过滤器用于验证和过滤来自非安全来源的外部数据
- 外部数据来源:
序号 |
数据来源 |
描述 |
1 |
表单 |
来自表音的用户输入数据 |
2 |
Cookies |
来自浏览器中的 cookie |
3 |
服务器变量 |
防止伪装的合法访问 |
4 |
Web 服务数据 |
Web 请求的数据 |
5 |
数据库查询结果 |
数据表中的数据并不可信 |
序号 |
函数 |
描述 |
1 |
filter_list() |
|
2 |
filter_id() |
|
3 |
filter_var() |
过滤单个变量 |
4 |
filter_var_array() |
过滤多个变量 |
5 |
filter_has_var() |
检测是否存在某个外部变量 |
6 |
filter_input() |
过滤单个外部变量 |
7 |
filter_input_array() |
过滤多个外部变量 |
- 外部变量类型:
INPUT_GET
, INPUT_POST
, INPUT_COOKIE
, INPUT_SERVER
, INPUT_ENV
- 过滤器主要分为二类: 验证过滤器, 清理过滤器
4-5-1 验证过滤器常量
- 验证过滤器: 又叫”验证器”, 主要用于数据的类型和格式验证
序号 |
过滤器函数 |
描述 |
1 |
FILTER_VALIDATE_INT |
验证整数 |
2 |
FILTER_VALIDATE_FLOAT |
浮点点验证 |
3 |
FILTER_VALIDATE_BOOLEAN |
验证布尔项 |
4 |
FILTER_VALIDATE_EMAIL |
验证邮箱 |
5 |
FILTER_VALIDATE_URL |
验证 URL 地址 |
6 |
FILTER_VALIDATE_IP |
验证 IP 地址 |
7 |
FILTER_VALIDATE_REGEXP |
正则验证 |
FILTER_VALIDATE_BOOLEAN
: 布尔选项的返回值类型
序号 |
返回值 |
描述 |
1 |
true |
“1”, “true”, “on” 和 “yes” |
2 |
false |
“0”, “false”, “off”, “no”, “” |
3 |
null |
除以上情形外 |
4-5-2 清理过滤器常量
序号 |
过滤器函数 |
描述 |
1 |
FILTER_UNSAFE_RAW |
保持原始数据 |
2 |
FILTER CALLBACK |
自定义函数过滤数据 |
3 |
FILTER_SANITIZE_STRING |
去除标签以及特殊字符:strip_tags() |
4 |
FILTER_SANITIZE_STRIPPED |
“string” 过滤器别名 |
5 |
FILTER_SANITIZE_ENCODED |
URL-encode 字符串,去除或编码特殊字符 |
6 |
FILTER_SANITIZE_SPECIAL_CHARS |
HTML 转义字符, 等价于 htmlspecialchars() |
7 |
FILTER_SANITIZE_EMAIL |
仅保留邮箱地址的合法字符 |
8 |
FILTER_SANITIZE_URL |
仅保留合法的 URL, 必须从协议开始http/https |
9 |
FILTER_SANITIZE_NUMBER_INT |
仅保留合法的数字和正负号+- |
10 |
FILTER_SANITIZE_NUMBER_FLOAT |
仅保留合法的数字和正负号+- 以及指数 .,eE |
11 |
FILTER_SANITIZE_MAGIC_QUOTES |
等价于函数: addslashes() |
4-5-3 选项与标志
- 可以对过滤器设置选项和标志, 对数据进行更加精准的过滤处理
- 选项与标志使用数组键名表示:
'options'=>[...], 'flags'=>...
(复数)
5. 自己的实战
(5-1)变量作用域
$aUserName = 'ZhangSan';
const AUSERNAME = 'LiSi';
function showName(){
return $GLOBALS['aUserName'];
}
echo showName();
(5-2)常量的定义,访问与命名空间
define ('AUSERNAME', 'LiSi');
echo constant ('AUSERNAME');
(5-3)常用的变量过滤器,不少于五个
//① 查询所有的过滤器
foreach (filter_list() as $filter) {
echo $filter . ' => ' .filter_id($filter) . '<br>';}
echo '<hr>';
//② int范围验证
$income = '1000000000';
$options = ['options'=>['min_range'=> 10000, 'max_range'=> 99999999]];
echo '第一个验证结果:';
var_dump(filter_var($income, FILTER_VALIDATE_INT, $options));
echo '<hr>';
//③ email格式验证
$email = 'abc@abc.com';
echo '第二个验证结果:';
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
echo '<hr>';
//④ ip地址验证
$ip = '126.1.0';
echo '第三个验证结果:';
var_dump(filter_var($ip, FILTER_VALIDATE_IP));
echo '<hr>';
//⑤ 仅保留合法的数字和正负号+-
$rawdata = 'rt576';
echo '第四个验证结果:';
var_dump(filter_var($rawdata, FILTER_SANITIZE_NUMBER_INT));
echo '<hr>';
//⑥ 验证多个外部变量
$loginInfo = [
'username'=> FILTER_SANITIZE_STRING,
'email'=>FILTER_VALIDATE_EMAIL,
'age'=> ['filter'=>FILTER_VALIDATE_INT, 'options'=>['min_range'=> 18, 'max_range'=> 60]],
'website'=> FILTER_VALIDATE_URL
];
echo '第五个验证结果:';
var_dump(filter_input_array(INPUT_GET, $args));
echo '<hr>';
Correcting teacher:Guanhui
Correction status:qualified
Teacher's comments:实战打印结果图?