PHP变量作用域实例详解
什么是变量作用域?
- 变量在使用是,要符合变量的定义规则。变量必须在有效的范围使用,如果变量超出了有限范围,变量也就没有意义了,就好比公司老总,在公司内可以发挥自己做大的作用,到了别的地方就很难发挥作用,除非另起炉灶,我们的PHP程序也是在一个作用域中申明了变量,变量可以在作用域中发挥作用。
- PHP的变量由于作用域不同,分为:局部变量,全局变量和静态变量,如下表:
作用域 | 说明 |
---|---|
局部变量 | 在函数的内部定义的变量,作用域就是所在的函数范围 |
全局变量 | 在被定义所有的函数以外的变量,作用域是整个PHP文件,但是在用户自定义函数内部是不能使用的。如果希望用户在用户自定义函数内部使用全局变量,则使用global关键字声明全局变量 |
静态变量 | 能够在函数调用结束后仍保留变量值,当再次回到其作用域,又可以继续使用原来的值。而一般变量是在函数调用后,其存储的数据值会被清除,所占用的内存空间也会被释放。使用静态变量时,先要用关键字static来声明变量,把关键字static放在要定义的变量之前 |
在函数内部定义的变量,其作用域为所在的函数,如果在函数外赋值,将被认为是完全不同的另一个变量。在退出声明变量的函数时,该变量及相应的值就会被清除。
<?php
$username= "史泰龙"; //什么一个全局变量
function actors(){
$username = "杰森斯坦森"; //与全局变量同样的变量名申明一个局部变量
echo $username; //在函数中打印变量
}
actors(); //调用函数
echo "<br>"; //换行
echo $username; //打印全局变量
- 静态变量在很多地方都能用到。例如,在博客中使用静态变量记录浏览者的人数,每一次用户访问和离开时,都能够保留目前浏览者的人数。在聊天室中也可以使用静态变量来记录用户的聊天内容。
<?php
function zdy0(){ //定义函数zdy0
static $message = 0; //初始化静态变量
$message+=1; //变量=变量+1
echo $message." "; // 输出变量链接一个空格
}
function zdy1(){ //定义函数zdy1
$message = 0; //初始化变量
$message+=1; //变量=变量+1
echo $message." "; // 输出变量链接一个空格
}
for ($i=0;$i<10;$i++) zdy0();
echo "<br>";
for ($i=0;$i<10;$i++) zdy1();
echo "<br>";
示例中在函数内分别定义了一个静态变量,和一个局部变量,分别对两个函数进行10次的循环输出,函数zdy0中由于设置了静态变量$message的值未被初始化,zdy1中的$message的值循环一次被初始化一次。详情见示例图
示例图
<?php
$username = "杰森斯坦森";
$username1 = "史泰龙";
function actors(){
$oles = "动作演员";
global $username;
$site = "好莱坞";
echo $username."与".$username1."是".$oles."他的片场在".$site;
}
actors();
- 示例中定义了两个全局变量,在自定义函数中同时调用了两个全局变量,由于$username1没有在函数中使用global来声明,在输出的时只显示了$username。
常量的定义,访问与命名空间
常量
- 特点: 不能修改,不能销毁,不能删除,声明常量后,该常量可以在页面的任意处使用
- 声明常量的方法:const 、define、static
- 命名规范:和变量一样,但是全部大写
申明常量的方法 | 说明 |
---|---|
define | define是函数,不能在对象中定义,但可在类中定义使用, |
const | const是一个语言结构,编译时要比define快,是为全局常量,可在对象里定义,类中使用,可理解为类常量 |
、
define
- 常量前面没有美元符号($);
- 常量只能用 define() 函数定义,而不能通过赋值语句;
- 常量可以不用理会变量的作用域而在任何地方定义和访问;
- 常量一旦定义就不能被重新定义或者取消定义;
- 常量的值只能是标量。
- 使用 define() 函数它使用三个参数,true表示大小写不敏感,默认为false;
define示例
<?php
define("CONSTANT", "Hello world.",true);
define("CONSTANT1","PhP");
//第一个参数常量名CONSTANT
//第二个参数常量值
//第三个参数不区分大小写,默认是false,
echo CONSTANT; // 输出 "Hello world."并发出一个提示级别错误信息
echo "<br>";
echo Constant; // 输出 "Hello world" 并发出一个提示级别错误信息
echo "<hr>";
echo CONSTANT1; //输出"PHP"没有任何报错
echo "<br>";
echo Constant1; // 输出 "Constant1" 并发出一个提示级别错误信息
//由于define只能使用大写字母来定义,输出小写只显示错误的变量名和错误信息
- 在示例中定义了两个常量CONSTANT与CONSTANT1第三个参数分别使用了默认的false和修改的true.可以看出,默认的define对大小写不敏感,修改后的define提示错误信息。
- define示例图
- define示例图
const
- 使用 const 关键字定义常量必须处于最顶端的作用区域,因为用此方法是在编译时定义的。这就意味着不能在函数内,循环内以及 if 语句之内用 const 来定义常量。
- const简单易读,编译时要比define快很多。
- const可在类中使用,用于类成员常量定义,定义后不可修改;define不能在类中使用,可用于全局变量
- const只能用普通的常量名
- const定义的常量只能是静态常量
const示例
<?php
define("SHOWDEFINE","这是define常量值"); //定义全局常量
class MyClass
{
const CONS = '这是CONS常量值'; //定义类常量define在类中不能定义
// const默认static静态
function showConstant() {
echo self::CONS; //输出const常量
echo "<br>";
echo constant('SHOWDEFINE'); //输出define常量
}
}
$class = new MyClass(); //实例化
$class -> showConstant();
echo "<br>";
echo "<hr>";
echo "<br>";
echo $class::CONS; //输出const常量
echo "<br>";
echo constant('SHOWDEFINE'); //输出define常量
在示例中定义了define常量和const常量,define常量在类中不能定义,const在类中定义在全局使用。
示例图
命名空间
- 一、命名空间是什么?
- 从广义上来说,命名空间是一种封装事物的方法。
PHP 命名空间(namespace)是在PHP 5.3中加入的,如果你学过C#和Java,那命名空间就不算什么新事物。 不过在PHP当中还是有着相当重要的意义。 - PHP 命名空间可以解决以下两类问题:
- 从广义上来说,命名空间是一种封装事物的方法。
- 解决用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
- 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
- PHP 命名空间提供了一种将相关的类、函数和常量组合到一起的途径。
定义命名空间
- 默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样。
- 命名空间通过关键字 namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间。语法格式如下;
<?php
namespace MyProject; //定义命名空间MyProject
const A = 1; //定义一个常量
function MyFunc(){ //定义函数
$Func = "我是函数"; //定义一个字符串
return $Func; // 返回定义的变量
}
class MyClass{ //定义一个类
public $clas; //定义一个类的共用变量
static function MyMethod(){ //定义一个静态函数
$clas = "我是类"; //为变量赋值
return $clas; //返回定义的变量
}
}
?>
- 以上demo.php,
<?php
include ("demo.php"); //引入demo.php文件
echo MyProject\A."<br>"; // 输出命名空间conts的值
echo MyProject\MyFunc()."<br>"; // 输出命名空间函数的返回值:我是函数
echo MyProject\MyClass::MyMethod(); // 输出命名空间类返回值:我是类
?>
以上demo1.php
在demo.php中定义了命名空间MyProject,在命名空间中分别创建了一个常量A,一个函数MyFunc并返回值”我是函数”,一个类MyClass并返回值”我是类”。
在demo1.php中引用了demo.php文件,调用并输出命名空间。
示例图
常用的变量过滤器
什么是 PHP 过滤器?
- PHP 过滤器用于验证和过滤来自非安全来源的数据。
- 测试、验证和过滤用户输入或自定义数据是任何 Web 应用程序的重要组成部分。
PHP 的过滤器扩展的设计目的是使数据过滤更轻松快捷。
为什么使用过滤器?
几乎所有的 Web 应用程序都依赖外部的输入。这些数据通常来自用户或其他应用程序(比如 web 服务)。通过使用过滤器,您能够确保应用程序获得正确的输入类型。您应该始终对外部数据进行过滤!
输入过滤是最重要的应用程序安全课题之一。
什么是外部数据?- 来自表单的输入数据
- Cookies
- Web services data
- 服务器变量
- 数据库查询结果
函数和过滤器
如需过滤变量,请使用下面的过滤器函数之一:
- filter_var() - 通过一个指定的过滤器来过滤单一的变量
- filter_var_array() - 通过相同的或不同的过滤器来过滤多个变量
- filter_input - 获取一个输入变量,并对它进行过滤
- filter_input_array - 获取多个输入变量,并通过相同的或不同的过滤器对它们进行过滤
示例:filter_var()
<?php
$int = 123; //定义一个整数变量
if(!filter_var($int, FILTER_VALIDATE_INT)){ //判断是否为整数
echo("不是一个合法的整数"); // 不是就输出
}else{
echo("是个合法的整数"); // 是就输出
}
//重点是FILTER函数用来过滤所需
- 示例对一个整数的判断是否是整数。
示例图:
验证输入
试着验证来自表单的输入。我们需要做的第一件事情是确认是否存在我们正在查找的输入数据。
示例:
<?php
if(!filter_has_var(INPUT_GET, "email")){
//判断email是否是GET传过来的
//如果定义了$email,同样的是报没有email参数
echo("没有 email 参数");
}else{
if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL)){
//使用filter_input过滤器对email判断是否合法
echo "不是一个合法的 E-Mail";
}else{
echo "是一个合法的 E-Mail";
}
}
示例中采用filter_has_var对email进行判断是否GET传送的值,如果是定义了$email就直接输出没有email参数,在运行代码的时候在demo.php后加入?email=ynde@126.com,代码正常运行。后使用了filter_input对get传值的email进行判断是否合法。
示例图:
过滤多个输入
表单通常由多个输入字段组成。为了避免对 filter_var 或 filter_input 函数重复调用,我们可以使用 filter_var_array 或 filter_input_array 函数。
- 示例:
<?php
$filters = array //定义一个filters的多维数组
(
"name" => array // 定义一个name的数组
(
"filter"=>FILTER_SANITIZE_STRING //对filter字符串的标签及特殊字符剔除
),
"age" => array //定义一个数组
(
"filter"=>FILTER_VALIDATE_INT, //对数组中filter符号和数字外的特殊字符剔除
"options"=>array //定义一个数组
(
"min_range"=>1, //为options['min_range']赋值
"max_range"=>120 //为options['max_range']赋值
)
),
"email"=> FILTER_VALIDATE_EMAIL //对filters['email'] 赋值
);
print_r("<pre>");
print_r($filters);
print_r("<pre>");
echo"<hr>";
$result = filter_input_array(INPUT_GET, $filters);
//对GET传值进行过滤
var_dump($result["age"]); //过滤出的age
echo "<br>";
var_dump($result["email"]); //过滤出的email
echo "<br>";
if (!$result["age"]){
echo("年龄必须在 1 到 120 之间。<br>");
}elseif(!$result["email"]){
echo("E-Mail 不合法<br>");
}else{
echo("输入正确");
}
在代码中我们使用了多维数组做了一个URL使用filter_var_array对URL进行过滤,对数组中的数值进行验证。
示例图
- 示例中的filter一个数整数一个是字符串,在URL中没有赋值,不清楚值是多少。但是成像没有报错。在通过filter_input_array对数组进行了过滤,将URL的值分别都过滤完后赋值给数组。