搞定PHP面试 - 变量知识点整理
一、变量的定义
1. 变量的命名规则
变量名可以包含字母、数字、下划线,不能以数字开头。
$Var_1 = 'foo'; // 合法
$var1 = 'foo'; // 合法
$_var1 = 'foo'; // 合法
$Var-1 = 'foo'; // 非法,不能包含 -
$1_var = 'foo'; // 非法,不能以数字开头
在此所说的字母是 a-z,A-Z,以及 ASCII 字符从 127 到 255(0x7f-0xff)。
因此实际上使用中文变量名也是合法的。
甚至使用中文的标点符号作为变量名都是合法的。
只是一般都不推荐这样用。
$姓名 = 'foo'; // 合法
$?。…… = 'foo'; // 合法。
变量名区分大小写
$var = 'Bob';
$Var = 'Joe';
echo "$var, $Var"; // 输出 "Bob, Joe"
$this 是一个特殊的变量,它不能被赋值
$this = 'foo'; // Fatal error: Cannot re-assign $this
2. 变量的赋值
变量的引用赋值与传值赋值详情传送门:变量的引用赋值与传值赋值
传值赋值
变量默认总是传值赋值。那也就是说,当将一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量。
这意味着,例如,当一个变量的值赋予另外一个变量时,改变其中一个变量的值,将不会影响到另外一个变量。
$foo = 'Bob'; // 将 'Bob' 赋给 $foo
$bar = $foo; // 通过 $foo 传值赋值给 $bar
$bar = 'Jack'; // 修改 $bar 变量
echo $foo; // $foo 的值未改变,依然是 'Bob'
引用赋值
引用赋值,就是新的变量简单的引用(换言之,“成为其别名” 或者 “指向”)了原始变量。
改动新的变量将影响到原始变量,反之亦然。
使用引用赋值,只需要将一个 &
符号加到将要赋值的变量前(源变量)
$foo = 'Bob'; // 将 'Bob' 赋给 $foo
$bar = &$foo; // 通过 $bar 引用 $foo
$bar = 'Jack'; // 修改 $bar 变量
echo $foo; // $foo 的值也被修改为 'Jack'
只有有名字的变量才可以引用赋值
$foo = 25;
$bar = &$foo; // 合法的赋值
$bar = &(24 * 7); // 非法; 引用没有名字的表达式
function test()
{
return 25;
}
$bar = &test(); // 非法
3.变量的初始化
虽然在 PHP 中并不需要初始化变量,但对变量进行初始化是个好习惯。
未初始化的变量的默认值
未初始化的变量具有其类型的默认值。
- 布尔类型的变量默认值是
FALSE
- 整形和浮点型变量默认值是
0
- 字符串型变量默认值是空字符串
""
- 数组变量的默认值是空数组
array()
4. 可变变量
可变变量是指变量的变量名可以动态的设置和使用。
一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。在下面的例子中 hello 使用了两个美元符号($
)以后,就可以作为一个可变变量的变量了。
$a = 'hello';
$$a = 'world';
这时,两个变量都被定义了:$a
的内容是“hello”并且 $hello 的内容是“world”。
因此,以下语句:
echo "$a ${$a}";
与以下语句输出完全相同的结果:
echo "$a $hello";
它们都会输出:hello world。
可变变量用于数组
要将可变变量用于数组,必须解决一个模棱两可的问题。
这就是当写下 $$a[1]
时,解析器需要知道是想要 $a[1]
作为一个变量呢,还是想要 $ $a
作为一个变量并取出该变量中索引为 [1]
的值。
解决此问题的语法是,对第一种情况用 ${$a[1]}
,对第二种情况用 ${$a}[1]
。
可变变量用于类
类的属性也可以通过可变属性名来访问。可变属性名将在该调用所处的范围内被解析。
例如,对于 $foo->$bar
表达式,则会在本地范围来解析 $bar 并且其值将被用于 $foo 的属性名。
对于 $bar
是数组单元时也是一样。
也可使用花括号{}
来给属性名清晰定界。
最有用是在属性位于数组中,或者属性名包含有多个部分或者属性名包含有非法字符时(例如来自 json_decode()
或 SimpleXML
)。
将一个json格式的字符串转换成php对象:
$string = '{"os-version":"10.3.1","1day":24}';
$obj = json_decode($string);
print_r($obj);
输出结果:
stdClass Object
(
[os-version] => 10.3.1
[1day] => 24
)
此时若想访问对象$obj 中的 os-version
属性或1day
属性,若直接使用 $obj->os-version
,$obj->1day
访问的话一定会报错。
正确的访问方式:
echo $obj->{"os-version"};
echo '<br/>';
echo $obj->{"1day"};
输出结果:
10.3.1
24
二、变量的作用域和静态变量
1. 变量的作用域
变量的作用域也称变量的范围,即它定义的上下文背景(也就是它的生效范围)。
php变量的范围跨度同样包含了include和require引入的文件。
局部变量
在用户自定义函数中,将引入一个局部函数范围。任何用于函数内部的变量的作用域都将被限制在局部函数范围内。例如:
$outer = 'str'; /* 全局范围 */
function myfunc()
{
echo $outer; /* 对局部范围变量的引用 */
}
myfunc();
这个脚本不会有任何输出,因为 echo 语句引用了一个局部版本的变量 $outer
,而且在这个范围内,它并没有被赋值。
全局变量
global关键字
$outer = 'str'; // 全局
function myfunc()
{
global $outer;
echo $outer; // 局部
}
myfunc();
这个脚本会输出 str
。在函数中使用global关键字声明了全局变量 $a
和 $b
之后,对任一变量的所有引用都会指向其全局版本。对于一个函数能够声明的全局变量的最大个数,PHP 没有限制。
$GLOBALS超全局数组
$GLOBALS
— 引用全局作用域中可用的全部变量
$outer = 'str'; // 全局
function myfunc()
{
echo $GLOBALS['outer'];
}
myfunc();
这个脚本会输出 str
。$GLOBALS
是一个关联数组,每一个变量为一个元素,键名对应变量名,值对应变量的内容。$GLOBALS
之所以在全局范围内存在,是因为 $GLOBALS
是一个超全局变量。
PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global $variable; 就可以访问它们。
这些超全局变量是:
$GLOBALS
— 超全局变量是在全部作用域中始终可用的内置变量$_SERVER
— 服务器和执行环境信息$_GET
— HTTP GET 变量$_POST
— HTTP POST 变量$_FILES
— HTTP 文件上传变量$_COOKIE
— HTTP Cookies$_SESSION
— Session 变量$_REQUEST
— HTTP Request 变量。默认情况下包含了 $_GET
,$_POST
和 $_COOKIE
的数组。$_ENV
— 环境变量
2. 静态变量
变量范围的另一个重要特性是静态变量(static variable)。
静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不会消失。
静态变量的特点
1.使用static关键字修饰
2.静态声明是在编译时解析的
3.仅初始化一次
4.初始化时需要赋值
5.每次执行函数该值会保留
6.static修饰的变量是局部的,仅在函数内部有效
7.可以记录函数的调用次数,从而可以在某些条件下终止递归。
function myFunc()
{
static $a = 1;
echo $a++;
}
myFunc(); // 1
myFunc(); // 2
myFunc(); // 3
变量 $a
仅在第一次调用 myFunc()
函数时被初始化,之后每次调用 myFunc()
函数都会输出 $a 的值并加1。
声明静态变量时不能用表达式的结果对其赋值
function foo(){
static $int = 0; // 正确
static $int = 1+2; // 错误 (使用表达式的结果赋值)
static $int = sqrt(121); // 错误 (使用表达式的结果赋值)
echo $int++;
}
静态变量与递归函数
静态变量提供了一种处理递归函数的方法。
递归函数是一种调用自己的函数。写递归函数时要小心,因为可能会无穷递归下去。必须确保有充分的方法来中止递归。
以下这个简单的函数递归计数到 10,使用静态变量 $count 来判断何时停止:
function test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
$count--;
}
3. 实例分析
写出如下程序的输出结果
$count = 5;
function get_count()
{
static $count;
return $count++;
}
echo $count;
++$count;
echo get_count();
echo get_count();
第8行 echo $count;
输出 5
第9行 ++$count;
,此时 $count
的值为 6
第11行 echo get_count();
,第一次调用 get_count()
函数
function get_count()
{
// 声明静态变量 $count,由于为赋值,所以其值为 NULL
static $count;
// $count++,先返回 $count 的值,后自增。因此,返回值为 NULL。
// NULL 自增后的值为 1,因此,自增后的 $count = 1
return $count++;
}
第一次调用 get_count()
的返回值为 NULL,而 echo NULL;
什么都不会输出。
第12行 echo get_count();
,第二次调用 get_count()
函数
function get_count()
{
// 第二次调用时,该行不会执行
static $count;
// 此前 $count = 1,$count++,先返回 $count 的值,后自增。因此,返回值为 1。
return $count++;
}
第一次调用 get_count()
的返回值为 1,而 echo get_count();
输出 1
。
整个程序的输出结果为 51
原文地址:https://segmentfault.com/a/1190000016291982
搞定PHP面试 - 变量知识点整理的更多相关文章
- 搞定PHP面试 - 函数知识点整理
一.函数的定义 1. 函数的命名规则 函数名可以包含字母.数字.下划线,不能以数字开头. function Func_1(){ } //合法 function func1(){ } //合法 func ...
- 搞定PHP面试 - 正则表达式知识点整理
一.简介 1. 什么是正则表达式 正则表达式(Regular Expression)就是用某种模式去匹配一类字符串的一种公式.正则表达式使用单个字符串来描述.匹配一系列匹配某个句法规则的字符串.正则表 ...
- 搞定PHP面试 - 运算符知识点整理
一.算术运算符 1. 概览 例子 名称 结果 $a + $b 加法 $a 和 $b 的和. $a - $b 减法 $a 和 $b 的差. $a * $b 乘法 $a 和 $b 的积. $a / $b ...
- 【Android 面试基础知识点整理】
针对Android面试中常见的一些知识点整理,Max 仅仅是个搬运工.感谢本文中引用文章的各位作者,给大家分享了这么多优秀文章.对于当中的解析,是原作者个人见解,有错误和不准确的地方,也请大家积极指正 ...
- [算法总结] 13 道题搞定 BAT 面试——字符串
1. KMP 算法 谈到字符串问题,不得不提的就是 KMP 算法,它是用来解决字符串查找的问题,可以在一个字符串(S)中查找一个子串(W)出现的位置.KMP 算法把字符匹配的时间复杂度缩小到 O(m+ ...
- 【搞定Jvm面试】 Java 内存区域揭秘附常见面试题解析
本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb ([Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识)如果觉得不错 ...
- 两年经验拿到蚂蚁金服,字节offer,附上金九银十BAT面试核心知识点整理
前言 我自己是本科毕业后在老东家干了两年多,老东家算是一家"小公司"(毕竟这年头没有 BAT 或 TMD 的 title 都不好意思报出身),毕业这两年多我也没有在大厂待过,因此找 ...
- 【搞定Jvm面试】 JVM 垃圾回收揭秘附常见面试题解析
JVM 垃圾回收 写在前面 本节常见面试题 问题答案在文中都有提到 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好 ...
- 【搞定Jvm面试】 面试官:谈谈 JVM 类加载过程是怎样的?
类加载过程 Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚拟机是如何加载这些 Class 文件呢? 系统加载 Class 类型的文件主要三步:加载->连接->初始化.连接过程 ...
随机推荐
- Light oj 1251 - Forming the Council 【2-sat】【推断是否存在可行解 + 反向拓扑输出可行解】
1251 - Forming the Council problem=1251" style="color:rgb(79,107,114)"> PDF (Engli ...
- 设计模式C++实现——组合模式
模式定义: 组合模式同意你将对象组合成树形结构来表现"总体/部分"层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 这个模式可以创建一个树形结构,在同一个结构中处理嵌套 ...
- Ubuntu Tomcat Service
只需要将%TOMCAT_HOME%/bin/catalina.sh文件拷贝到/etc/init.d/文件夹下,稍作编辑,然后注册成系统服务,是否设置自启动均可. 1. 编辑catalina.sh文件c ...
- 设备树学习之(一)GPIO中断【转】
本文转载自:http://blog.csdn.net/lizuobin2/article/details/54563587 开发板:tiny4412SDK + S702 + 4GB Flash 要移植 ...
- 利用Powershell和ceye.io实现Windows账户密码回传
利用Powershell和ceye.io实现Windows账户密码回传 转自:http://www.freebuf.com/articles/system/129068.html 最近在研究Power ...
- 最详细的CentOS 6与7对比(三):性能测试对比
本主题将从3个角度进行对比 常见设置(CentOS 6 vs CentOS 7) 服务管理(Sysvinit vs Upstart vs Systemd) 性能测试(cpu/mem/io/oltp) ...
- Python基础:lambda 匿名函数
格式 lambda argument1, argument2,... argumentN : expression square = lambda x: x**2 print(square(2)) 与 ...
- ps -aux ,ps aux ,ps -ef 的区别
Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...
- Scrapy中的UA池,代理池,以及selenium的应用
UA池 代理池 selenium在Scrapy中的应用 UA池 - 下载中间件: - 下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件. - 作用 ...
- java的重载总结
1.不能以返回值的不同来重载方法,编译都不通过(只有参数类型或者参数个数不同才可以重载方法) 在Java语言中,要重载一个方法,除了要与原方法具有相同的简单名称外,还要求必须拥有一个与原方法不同的(不 ...