PHP美元符和花括号组合那些事—${${}}
双美元符+{}:${${variable}}是一种比较常见的用法,但是它的实现原理是什么呢?今天来探究一下:
提及这种用法,还得先说一下PHP的String类型
php.net上指出,一个字符串可以用4种方式表达:单引号,双引号,heredoc语法结构,nowdoc语法结构
这里heredoc语法结构和双引号形式类似,同样nowdoc结构对应单引号
单引号:单引号包围起来的字符串中,单引号必须转义才能使用(\'),否则会报语法错误;而用于转义的反斜线自身,则要用两个反斜线(\\),即也需要转义. 文档说"其他任何形式的反斜线都被当成反斜线本身:也就是说如果想使用其它转义序列例如 \r 或者 \n,并不代表任何特殊含义,就单纯是这两个字符本身",这就是说单引号包围起来的其他转义序列根本没有实现转义.
反过来说,\是可以直接作为反斜线使用的,因此单引号包围的字符串中\\和\其实都能表示反斜线本身,验证实例如下:
<?php
echo 'You deleted C:\\*.*?';
echo 'You deleted C:\*.*?';
echo 'This will not expand: \n a newline';
echo 'Variables do not $expand $either';
?>
双引号:当字符串包围在双引号中,PHP会对一些特殊字符解析,这里\n,\r,\t都正常解析为转义符,而且反斜线、美元符、双引号都需要转义:\\, \$, \"
heredoc和nowdoc不如引号用起来方便,但是可以实现相同的目的
再说变量解析,文档的说法是当字符串遇到双引号或heredoc结构定义时,其中的变量将会被解析;变量解析有两种语法规则,简单的和复杂的,其中复杂规则的显著标记是用花括号包围的表达式;
对于简单规则而言,当 PHP 解析器遇到一个美元符号($)时,它会和其它很多解析器一样,去组合尽量多的标识以形成一个合法的变量名。可以用花括号来明确变量名的界线。
<?php
$juice = "apple";
echo "He drank some juice made of ${juice}s.";
?>
复杂语法:复杂语法不是因为其语法复杂而得名,而是因为它可以使用复杂的表达式。
任何具有 string 表达的标量变量,数组单元或对象属性都可使用此语法。只需简单地像在 string 以外的地方那样写出表达式,然后用花括号 { 和 } 把它括起来即可。由于 { 无法被转义,只有 $ 紧挨着 { 时才会被识别。可以用 {\$ 来表达 {$。
<?php
$great = 'fantastic'; // 无效,输出: This is { fantastic}
echo "This is { $great}"; // 有效,输出: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
echo "This is the value of the var named $name: {${$name}}";
?>
测试得到以上两条echo变量great的语句输出同样的结果,所以{${$name}}其实和${${name}}也是一样的
另外,php.net的文档中给出了Note:
"函数、方法、静态类变量和类常量只有在 PHP 5 以后才可在 {$} 中使用。然而,只有在该字符串被定义的命名空间中才可以将其值作为变量名来访问。只单一使用花括号 ({}) 无法处理从函数或方法的返回值或者类常量以及类静态变量的值。"
这里说的很清楚,只有单一{}无法处理返回值等,因为像${name}只是得到变量的名字,告诉我们这是变量name,即得到一个$name,假如我需要$name的值,那我就得对他再解析一次
所以像:
<!--
#GOAL: gather some phpinfo(); $str=@(string)$_GET['str'];
eval('$str="'.addslashes($str).'";');
-->
实现的方法是传入参数:str=${${phpinfo()}}
这里如果直接上phpinfo(),由于有addslashes的作用会出现\"的情况使得命令无法执行
${phpinfo()}告诉我们最里面这个是变量,名为phpinfo(),接下来的一层花括号将其解析为字符串"phpinfo()"
另外,{}有时候也可以当[]使用,文档中有说明:"Note: string 也可用花括号访问,比如 $str{42}",这里$str{42}==$str[42]
在《白帽子讲web安全》一书中也提到了同样的应用:
”PHP的curly systax能导致代码执行,它将执行花括号间的代码,并将结果替换回去,如下例:
<?php $var = "I was innocent until ${`ls`}" appeared here; ?>"
ls得到执行,列出本地目录并将结果返回
随机推荐
- SQL中利用DMV进行数据库性能分析
相信朋友对SQL Server性能调优相关的知识或多或少都有一些了解.虽然说现在NOSQL相关的技术非常的火热,但是RMDB(关系型数据库)与NOSQL是并存的,并且适用在各种的项目中.在一般的企业级 ...
- IE条件注释详解
IE条件注释是微软从IE5开始就提供的一种非标准逻辑语句,作用是可以灵活的为不同IE版本浏览器导入不同html元素,如:样式表,html标签等.很显然这种方法的最大好处就在于属于微软官方给出的兼容解决 ...
- ASP.NET 文件下载
using System; using System.Web; using System.IO; public partial class _Default : System.Web.UI.Page ...
- 你必须知道ASP.NET知识------从IIS到httpmodule(第一篇)
一.写在前面 最近有时间,顺便将这系列洗完,接着上文:IIS各个版本知识总结 这篇文章原本计划写到HttpHandler为止,但限于篇幅就写到httpmodule 本文有不足之处,求指正,希望我能将它 ...
- Ionic2学习笔记(4):*号
作者:Grey 原文地址: http://www.cnblogs.com/greyzeng/p/5544479.html 大家常常会在ionic2页面中见到*号 ...
- SQL Server论坛楼层计算触发器
代码: USE suya_dev GO IF EXISTS( SELECT * FROM sys.triggers WHERE name = N'BBS_Post_before_insert' ) D ...
- C语言写的流氓关机程序及破解
记得大二刚开始接触电脑的那个时候,偶尔会弹出一个强制关机的窗口,当时没有办法,如下: 现在看来只是一个小程序而已,用C语言编写的: #include<windows.h> int main ...
- Win10 IoT C#开发 6 - 4x4矩阵键盘扫描
Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我 ...
- WPF的一些总是记不住的Tips
Margin(Left,Top,Right,Bottom); HorizontalAlignment(Height的Opposite,水平对齐方式):VerticalAlignment(Width的反 ...
- 关于VS项目平台的x86,x64,Any CPU以及Debug和Release的区别
相信对于很多刚接触打包程序的同志来说,关于x86,x64,Any CPU这三个项目平台,以及解决方案配置Debug和Release有什么区别?这个问题一定有许多的困惑,甚至不乏一些已经工作了很久的老程 ...