变量
7. 作用域
- 变量作用域,也叫“变量范围”,即定义变量时的上下文环境,通俗说就是变量能使用的范围。类似“身份证”,中国的身份证在中国境内有效,在美国却不能用。
- 一个变量必须属于一个作用域。除开PHP运行环境中的几个超级VIP(超全局变量)。
- php中的作用域只有函数作用域和全局作用域。函数之外的代码都在全局空间中。
序号 |
作用域 |
描述 |
1 |
函数作用域 |
使用function 关键字创建的作用域 |
2 |
全局作用域 |
函数之外的作用域 |
<?php
# 变量作用域
// 在函数之外定义,所以是全局作用域
$siteName = 'php中文网';
echo $siteName . '<br>';
function getInfo(): string {
// 函数作用域
$siteName = 'php.cn';
return $siteName
}
echo getInfo();
序号 |
变量类型 |
描述 |
1 |
私有变量 |
函数中定义的变量 |
2 |
全局变量 |
函数之外定义的变量 |
3 |
超全局变量 |
也叫预定义变量,访问不受作用域限制,哪都能访问 |
- 超全局变量,也叫超全局数组,随系统加载,因此在所有脚本中均有定义,全局和函数中都可以访问
序号 |
变量名 |
描述 |
1 |
$GLOBALS |
引用全局作用域中可用的全部变量 |
2 |
$_SERVER |
服务器和执行环境信息 |
3 |
$_GET |
HTTP GET 请求:通过 URL 参数传递给当前脚本的变量的数组 |
4 |
$_POST |
HTTP POST 请求: 将变量以关联数组形式传入当前脚本 |
5 |
$_FILES |
HTTP 文件上传变量,保存着上传文件的全部信息 |
6 |
$_COOKIE |
通过 HTTP Cookies 方式传递给当前脚本的变量的数组 |
7 |
$_SESSION |
当前脚本可用 SESSION 变量的数组 |
8 |
$_REQUEST |
默认情况下包含了 $_GET ,$_POST 和 $_COOKIE 的数组 |
9 |
$_ENV |
通过环境方式传递给当前脚本的变量的数组 |
8. 静态变量
- 在函数中用
static
关键字定义静态变量。 - 静态变量定义时必须初始化,且只能初始化一次,默认值为’0’.无论函数被调用多少次,静态变量定义的语句都只在第一次函数被调用时执行,之后的调用均不执行。
- 函数执行完后,静态变量的值保持不变,下次调用该函数时,静态变量的值会保留上次函数执行结束后的值。
- 函数中的静态变量也是私有变量,全局不可访问。
- 使用场景:在多次调用函数时,共享数据时使用。
function callMe():void {
static $sum = 0;
$sum += 1;
echo '现在是第' . $sum . '次调用callMe()函数<br>';
}
callMe();
callMe();
callMe();
callMe();
callMe();
变量过滤器
如果我们对变量的取值有要求,就可以用变量过滤器来验证某个变量的值是否符合要求。
- 使用filter_var()验证单个变量的值是否符合要求。
- filter_var_array()验证变量数组的值是否符合要求。
- 使用场景:验证web请求中的参数值的有效性。
变量过滤器使用:
<?php
# 变量过滤器
## 遍历当前系统中的所有过滤器
/* foreach (filter_list() as $filter) {
echo $fileter . '===>' . filter_id($filter), '<br>';
} */
## 1. 过滤单个变量filter_var(变量, 验证器常量/验证器id, 值域), 即验证某个变量的值是不是某种数据类型
$age = 30;
$age = '30';
var_dump(filter_var($age, FILTER_VALIDATE_INT));
echo '<br>';
#### tips: FILTER_VALIDATE_INT可以验证数字字符串.
## 1.1. 既验证某个变量的值是不是某种数据类型, 又验证数值在指定的范围里
$age = '30';
$age = 200;
// 验证$age的值是否是数字/数字字符串, 且数值在18-60之间.
var_dump(filter_var($age, FILTER_VALIDATE_INT, ['options' => ['min_range' => 18, 'max_range' => 60]]));
## 1.2. 过滤邮箱(过滤器id=274)
$email = 'admin@qq.com';
$email = 'aaaa';
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
echo '<br>';
// 跟上面同样效果
var_dump(filter_var($email, 274));
echo '<br>';
## 2. 过滤多个变量(数组):filter_var_array(数组, 验证器常量/验证器id)
var_dump(filter_var_array([50, 'hello'], FILTER_VALIDATE_INT));
## 3. 检测是否存在指定的外部变量
// 如:url中的参数字符串(给访问本脚本的url中加上:?p=100)
// INPUT_GET: 表示要验证在get请求参数值中是否存在xx参数
// 其他参数: INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV
var_dump(filter_has_var(INPUT_GET, 'p'));
echo '<br>';
/* $_GET[param]的方式获取数据很容易早到跨站攻击 */
## 4. 验证外部变量是否存在的过滤器
var_dump(filter_input(INPUT_GET, 'p'));
echo '<br>';
### 4.1. 验证get请求中p参数是否存在, 若存在, 数值是否大于等于1
var_dump(filter_input(INPUT_GET, 'p', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]));
## 5. 同时验证多个外部变量filter_input_array()
// $args = ['paramName1' => FILTER_NAME1, 'paramName2' => ['filter'=>FILTER_NAME2, 'flags'=>FILTER_REQUIRE_SCALAR, 'options' => ...], ...]
$args = [
'username' => FILTER_SANITIZE_STRING,
'email' => FILTER_SANITIZE_EMAIL,
'age' => [
'filter' => FILTER_VALIDATE_INT,
'flags' => FILTER_REQUIRE_SCALAR,
'options' => ['min_range' => 18, 'max_range' => 60]
], 'blog' => FILTER_SANITIZE_URL
];
// 测试url1: http://php.edu/0416/demo3.php?username=<p>zhangsan</p>&email=test@&age=1&blog=blog.admin.cn
// 测试url2: http://php.edu/0416/demo3.php?username=zhangsan&email=test@php.cn&age=19&blog=http://blog.admin.cn
var_dump(filter_input_array(INPUT_GET, $args));
常量
1. 特征
序号 |
特征 |
1 |
常量前面没有美元符号$ |
2 |
常量创建时必须初始化 |
3 |
常量禁止更新和删除 |
4 |
常量不受作用域限制 |
5 |
推荐使用大写字母加下划线命名 |
2. 函数/关键字
序号 |
定义方式 |
描述 |
1 |
get_defined_constants() |
查看系统所有常量 |
2 |
defined() |
检测常量是否存在 |
3 |
define() |
创建常量 |
4 |
const 关键字 |
创建常量 |
5 |
constant() |
获取常量值 |
get_defined_constants(true)
: 常量分组打印,自定义常量在user
分组defined()
: 返回布尔值
定义常量:
<?php
# 定义常量
## 1. 方法1:使用define()函数定义
define('LECTURE', '朱老师');
## 2. 方法2:用const关键字
const COURSE = 'PHP';
## 3. 常量不受作用域限制
function test1()
{
echo LECTURE . '教' . COURSE . '<br>';
}
test1();
## 4. 在函数体中可以用define()定义常量, const不行.
function test2()
{
define('HELLO', 'hello');
// 用const会报错
/* const HELLO = 'hello'; */
}
test2();
echo HELLO;
## 5. 在流程控制语句中, define能用, const不能用
if (true) {
define('TEST', 'test');
// 用const会报错
/* const TEST = 'test'; */
echo TEST;
}
## 6. 在类中声明常量成员, 要用const, 不能用define()
class Demo
{
const CONST1 = 'hello!';
}
echo Demo::CONST1 . '<br>';
## 7. 常量通常只允许用标量进行初始化: 单值变量, 字符串, 数值, 布尔值, NULL
## 8. PHP7.0+支持数组初始化常量
const DB_LINKS = [
'host' => 'localhost',
'username' => 'root',
'password' => 'root',
'charset' => 'utf8'
];
echo '<pre>';
echo print_r(DB_LINKS, true);
echo '</pre>';
常量相关函数
<?php
# 常量相关函数
## 1. 查看系统中有哪些常量
// 1.1.get_defined_constants():查看所有常量
print_r(get_defined_constants());
// 1.2.入参true表示分组查看
print_r(get_defined_constants(true));
// 1.3.查看自定义常量
/* 先定义一个自定义常量DIY */
define('DIY', '我是自定义常量');
/* 自定义常量在key='user'的值数组中 */
print_r(get_defined_constants(true)['user']);
## 2. defined(常量名字符串):判断某个常量是否已定义
function checkConst($constName):void {
if(defined($constName)) {
echo '常量' . $constName . '的值:' . constant($constName) . '<br>';
} else {
echo '常量' . $constName . '未定义<br>';
}
}
define('CONST1', '我是一个常量');
$constName = 'CONST2';
checkConst($constName);
$constName = 'CONST1';
checkConst($constName);
## 3. constant(常量名字符串)函数:获取[常量名]为[入参字符串值]的[常量值].
echo constant('CONST1') . '<br>';
$constantName = DB_LINKS;
print_r(constant($constantName));
/* 使用constant()函数获取隐藏常量值 */
define('', '我看你怎么获取到我');
print_r(constant(''));
3. 预定义常量
预定义常量非常多,有许多与具体扩展相关,如 PDO
, 这里仅列出系统级常用的:
序号 |
预定义常量 |
描述 |
1 |
PHP_VERSION |
PHP 版本 |
2 |
PHP_MAXPATHLEN |
PHP 路径最大长度:1024 |
3 |
PHP_OS_FAMILY |
操作系统:Windows/Darwin/Linux |
4 |
PHP_SAPI |
web 服务器与 php 之间接口: apache2handler |
5 |
PHP_EOL |
行尾结束符 |
6 |
PHP_INT_MAX |
最大整数: 9223372036854775807 |
7 |
PHP_INT_MIN |
最小整数: -9223372036854775808 |
8 |
PHP_INT_SIZE |
整数宽度: 8 |
9 |
PHP_FLOAT_MAX |
最大浮点数:1.7976931348623E+308 |
10 |
PHP_FLOAT_MIN |
整小浮点数: 2.2250738585072E-308 |
11 |
DEFAULT_INCLUDE_PATH |
默认 PHP 命令路径 |
12 |
PHP_EXTENSION_DIR |
默认 PHP 扩展路径 |
13 |
E_ERROR |
运行时错误: 致命中断 |
14 |
E_PARSE |
语法解析错误: 致命中断 |
15 |
E_NOTICE |
运行时提示: 不中断 |
16 |
E_WARNING |
运行时警告: 不中断 |
17 |
E_ALL |
所有级别错误(除E_STRICT ) |
18 |
E_STRICT |
更加严格的错误处理机制,高于E_ALL |
19 |
TRUE |
布尔真 |
20 |
FALSE |
布尔假 |
21 |
NULL |
空 |
22 |
DIRECTORY_SEPARATOR |
目录分隔符 |
<?php
# 预定义常量直接用就好
echo PHP_OS_FAMILY;
// ...
4. 魔术常量
- 魔术常量也属于”预定义常量”, 比较特殊所有单独列出
- 所谓”魔术”, 是指常量的值, 会随它们在代码中的位置改变而改变
- 魔术常量不区分大小写, 但是推荐全部大写
序号 |
魔术常量 |
描述 |
1 |
__LINE__ |
文件中的当前行号 |
2 |
__FILE__ |
文件的完整路径和文件名 |
3 |
__DIR__ |
文件所在目录 |
4 |
__FUNCTION__ |
当前的函数名称 |
5 |
__CLASS__ |
当前类名称 |
6 |
__TRAIT__ |
当前Trait 名称 |
7 |
__METHOD__ |
当前类方法名称 |
8 |
__NAMESPACE__ |
当前命名空间名称 |
<?php
namespace const_demo\magic_const;
## 查看当前行号:__LINE__
echo '当前行号:' . __LINE__ . '<br>';
## 查看当前文件:__FILE__
echo '当前文件(绝对地址):' . __FILE__ . '<br>';
## 查看当前文件所在的目录:__DIR__
echo '当前文件所在的目录(不包括文件名):' . __DIR__ . '<br>';
## 查看当前命名空间名称
echo '当前命名空间名称是:' . __NAMESPACE__ . '<br>';
## 查看当前函数名: __FUNCTION__
function getCurrentFuncName()
{
echo '当前函数名是:' . __FUNCTION__;
}
trait Trait1 {
public function hello() {
echo '当前trail名称是:' . __TRAIT__;
}
}
class Demo
{
use Trait1;
public function index()
{
## 查看当前方法名: __METHOD__
echo '我的方法名是:' . __METHOD__ . '<br>';
## 查看当前类名: __CLASS__
echo '我的类名是:' . __CLASS__ . '<br>';
$this->hello();
}
}
(new Demo)->index();
?>
学习心得
- 变量的作用域就是在哪能用这个变量。函数要使用全局作用域的变量,需要一个“介绍人”。全局作用域要使用函数中的变量,需要在函数中将该变量”return”出来。
- 超全局变量可以理解为不受作用域约束的变量,都是数组。
- 静态变量可以认为是多次方法调用中共享数据用的量,只能一次创建,永久存在,不随方法调用结束而被销毁。
- 常量就是某个固定值的标签,使用这个标签,就能获得这个固定值,且这个标签只要跟这个值绑定,就不能再解绑。类似钞票,假设它印出来是十块钱,就相当于这张钞票跟十元产生了绑定,并且不能把这张钞票当一百元来使用(解绑)。
- 变量过滤器是之前没有接触过的概念,它类似海关,合法的东西可以入关;非法的东西,将不能入关(返回false)。过滤器可以验证数据类型、数据格式(email格式,url格式等)和数据范围;可以验证单变量,也可以验证数组。