1. 变量的作用域
变量分为局部变量和全局变量,作用域就是变量的生效范围,所以也分为全局作用域和函数作用域(变量在函数内部)。
示例如下:
<?php
error_reporting(E_ALL);
//作用域重要知识点
// 1.作用域是变量的生效范围
// 2.作用域是查找变量的工具
// 1.全局作用域
$brand1 = 'apple';
// 2.函数作用域
function show1(){
$brand2 = 'vivo';
return $brand2;
}
echo $brand1,'<br>'; //会输出结果
echo $brand2,'<br>'; //不会输出结果,因为变量的作用域是函数作用域,只能在函数内部访问
//可以通过调用函数的方式访问
echo show1();
echo '<br>';
// 如果要在函数作用域中访问全部变量,有2种方式
// 1.需使用global关键字,表示调用全局变量
function show2(){
global $brand1;//如果把这行注释,后面也是不会输出结果的
return $brand1;
}
echo show2();
echo '<br>';
// 2.推荐使用超全局变量$GLOBALS来访问
function show3(){
return $GLOBALS['brand1'];
}
echo show3();
// 在全局中创建的变量,会自动成为超全局数组$GLOBALS中的一个元素
// 查看每个脚本中预定义的超全局变量
echo '<pre>'.print_r($GLOBALS,true).'</pre>';
/*
PHP超全局变量列表
1. $GLOBALS
2. $_SERVER
3. $_REQUEST
4. $_POST
5. $_GET
6. $_FILES
7. $_ENV
8. $_COOKIE
9. $_SESSION
*/
2. 常量的定义
常量值被定义后,在脚本的其他任何地方都不能被改变。
常量必须初始化
一个常量由英文字母、下划线、和数字组成,但数字不能作为首字母出现。 (常量名不需要加 $ 修饰符)。
常量在整个脚本中都可以使用,不受作用域限制,属全局变量
定义常量有2种方式:
使用const关键字
使用define()函数
常量除了用户自定义以外,还有预定义常量和魔术常量
2.1 自定义常量示例如下:
<?php
error_reporting(E_ALL);
// 1. 查看当前有哪些可用的常量
// print_r(get_defined_constants(true));
// 2. 查看用户自定义的常量
// print_r(get_defined_constants(true)['user']);
// 使用关键字const定义常量
const WEATHER = 'sunny';
// 使用define()函数定义常量
define('SMOKE','yuxi');
echo '<pre>'.print_r((get_defined_constants(true)['user']),true).'</pre>';
// 注意点:类中的常量只能用const定义
class Body
{
// define('header','head');会报错
const FOOTER = 'foot';
}
echo Body::FOOTER,'<hr>';
// 有时会用到constant('常量名')的方式来输出常量
echo constant('SMOKE'),'<hr>';
// 定义一个特殊常量
// 这个案例可以看出使用常量名的方式不一定能获取到常量值
define('','pink');
echo '','<hr>';
echo constant('');
// 常量推荐全部大写,多个单词之间使用下划线连接
// 例如:const APP_NAME = 'YourFamily';
// 常量必须初始化
// 比如:const AGE; 这样就不行
2.2 预定义和魔术常量:
预定义常量名 | 含义 |
---|---|
PHP_VERSION |
版本号 |
PHP_OS_FAMILY |
操作系统 |
PHP_INT_MAX |
最大整数 |
PHP_FLOAT_MAX |
最大浮点数 |
DIRECTORY_SEPARATOR |
目录分隔符 |
魔术常量 | 含义 |
---|---|
__LINE__ |
文件中的当前行号 |
__FILE__ |
文件的完整路径和文件名 |
__DIR__ |
文件所在目录 |
__FUNCTION__ |
当前的函数名称 |
__CLASS__ |
当前类名称 |
__TRAIT__ |
当前Trait 名称 |
__METHOD__ |
当前类方法名称 |
__NAMESPACE__ |
当前命名空间名称 |
3. 命名空间
使用命名空间的原因:我们知道常量是全局作用域的,其实,还有函数,类,接口也是全局的,这些全局成员有一个共同点就是不能重复定义,但是在实际开发中,可能不得不需要用到同一个名字,这样就会有命名冲突的问题,而命名空间namespace
,就是来解决这一问题的。
示例如下:
<?php
// namespace命名空间代码段需要放在所有代码的第一行
// 下面展示案例二的时候先把案例一注释
// 案例一
// const NAME = 'Jack';
// const NAME = 'Alice'; // 这一行会报错,因为命名冲突
// echo NAME;
// echo '<hr>';
// 案例二:使用命名空间
namespace ns1{
const USER = '张三';
}
namespace ns2{
const USER = '李四';
}
// 访问时在全局空间里面访问
namespace {
echo \ns1\USER,'<br>';
echo \ns2\USER;
}
4. 变量过滤器
PHP 过滤器用于对来自非安全来源的外部数据(比如用户输入)进行验证和过滤。
- 外部数据来源:
序号 | 数据来源 | 描述 |
---|---|---|
1 | 表单 | 来自表音的用户输入数据 |
2 | Cookies | 来自浏览器中的 cookie |
3 | 服务器变量 | 防止伪装的合法访问 |
4 | Web 服务数据 | Web 请求的数据 |
5 | 数据库查询结果 | 数据表中的数据并不可信 |
- 查看当前PHP版本支持的变量过滤器有哪些:
foreach(filter_list() as $filter){
echo $filter.'=>'.filter_id($filter).'<br>';
}
变量过滤器的使用是通过一个Filter函数,然后把相应的参数传到函数里去。
Filter函数:
Filter函数 | 描述 |
---|---|
filter_var() |
获取单个变量,进行过滤 |
filter_var_array() |
获取多个变量,进行过滤 |
filter_list() |
返回一个当前版本支持的所有过滤器的数组 |
filter_id() |
返回当前过滤器的id号 |
filter_input() |
从脚本外部获取单个输入,并进行过滤 |
filter_input_array() |
从脚本外部获取多个输入,并进行过滤 |
filter_has_var() |
检查是否存在指定输入类型的变量 |
- input中的外部变量类型有:
INPUT_GET
,INPUT_POST
,INPUT_COOKIE
,INPUT_SERVER
,INPUT_ENV
过滤器分为:验证过滤器和清理过滤器
验证过滤器:用于数据的类型和格式验证
过滤器函数 | 描述 |
---|---|
FILTER_VALIDATE_INT |
验证整数 |
FILTER_VALIDATE_FLOAT |
浮点点验证 |
FILTER_VALIDATE_BOOLEAN |
验证布尔项 |
FILTER_VALIDATE_EMAIL |
验证邮箱 |
FILTER_VALIDATE_URL |
验证 URL 地址 |
FILTER_VALIDATE_IP |
验证 IP 地址 |
FILTER_VALIDATE_REGEXP |
正则验证 |
- 清理过滤器:去掉非法字符,仅保留指定内容
过滤器函数 | 描述 |
---|---|
FILTER_UNSAFE_RAW |
保持原始数据 |
FILTER CALLBACK |
自定义函数过滤数据 |
FILTER_SANITIZE_STRING |
去除标签以及特殊字符:strip_tags() |
FILTER_SANITIZE_STRIPPED |
“string” 过滤器别名 |
FILTER_SANITIZE_ENCODED |
URL-encode 字符串,去除或编码特殊字符 |
FILTER_SANITIZE_SPECIAL_CHARS |
HTML 转义字符, 等价于 htmlspecialchars() |
FILTER_SANITIZE_EMAIL |
仅保留邮箱地址的合法字符 |
FILTER_SANITIZE_URL |
仅保留合法的 URL, 必须从协议开始http/https |
FILTER_SANITIZE_NUMBER_INT |
仅保留合法的数字和正负号+- |
FILTER_SANITIZE_NUMBER_FLOAT |
仅保留合法的数字和正负号+- 以及指数 .,eE |
FILTER_SANITIZE_MAGIC_QUOTES |
等价于函数: addslashes() |
- 示例1,检查用户输入的邮箱是否合法:
<?php
// 实例一:检查邮箱输入是否合法
// 先拿到邮箱
$email = $_POST['email'];
// 输出邮箱看看
echo $email.'<br>';
// 对邮箱过滤
if (filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL))
{
echo "您的邮箱验证通过!";
}
else
{
echo "邮箱输入有误,请重新输入!";
}
- 示例二,检查用户输入的年龄是否在有效范围内:
<?php
// 示例二:检测用户输入的年龄是否在有效范围内(18-99岁)
// 先拿到年龄
$age = $_POST['age'];
// 输出看看
echo $age,'<br>';
// 过滤,设置范围
$options = ['options'=>['min_range' => 18,'max_range' => 99]];
if(!filter_input(INPUT_POST,'age',FILTER_VALIDATE_INT,$options)){
echo '你的年龄不合适!';
}
else{
echo '年龄符合条件!';
}
- 示例三,对用户名,年龄和邮箱同时过滤:
<?php
// 示例三,对用户名,年龄和邮箱同时过滤
// 先拿到所有变量
$username = $_POST['username'];
$age = $_POST['age'];
$email = $_POST['email'];
// 设置过滤规则
$args = [
'username' => FILTER_SANITIZE_STRING,
'age' => [ 'filter' => FILTER_VALIDATE_INT,'options' => ['min_range' => 18,'max_range' => 99] ],
'email' => FILTER_VALIDATE_EMAIL
];
echo '<pre>'.print_r(filter_input_array(INPUT_POST,$args),true).'</pre>';
//如果有变量的值不符合过滤器规则,可以看到最终输出结果没有那个变量的值
- 示例四:去除标签以及特殊字符
<?php
$str = '<h1 style="color:red;">我正在学习PHP编程</h1>';
// 没有增加过滤器时,会打印出原样字体
var_dump($str);
// 添加过滤器之后,h3标签失效,样式也失效了
var_dump(filter_var($str,FILTER_SANITIZE_STRING));
- 示例五:过滤一个数组
<?php
$arr = ['num' => '1.2a','age' => 66,'bool' => 1];
echo '<pre>'.print_r($arr,true).'</pre>';
$args = [
'num' => FILTER_SANITIZE_NUMBER_FLOAT,
'age' => [ 'filter' => FILTER_VALIDATE_INT, 'options' => [ 'min_range' => 18,'max_range' => 99 ] ],
'bool' => FILTER_VALIDATE_BOOLEAN
];
var_dump(filter_var_array($arr,$args));
echo '<pre>'.print_r(filter_var_array($arr,$args),true).'</pre>';
5. 总结
了解了变量的作用域外,还要知道如何在函数中访问全局变量
学会自定义常量的2中方式以及constant()函数的用法
自己练习并且掌握常用的预定义常量和魔术常量
了解使用命名空间的原因,并且学会如何访问(在全局空间里访问)
变量过滤器用法,首先要记忆它的语法,然后针对不同的环境使用不同的过滤器函数,函数里面的参数有时还会用到选项或标志,来进一步过滤