灵活的字符串。
因为$表达的灵活性,我们可以用“映射”的方法,调出字符串或者函数。
<?php
$a = 'b';
$b = '123';
echo $$a; // 这可以输出123。不过比较好的习惯是echo ${$a},这样更清楚明了。
$c = 'd';
echo $c();
function d() {return '321';} // $c()调用的是d函数
?>
php的字符串和javascript和python类似,在单引号中不用把双引号写成\",在双引号中也不用转义单引号。但是,因为php中有有趣的$存在,所以双引号要复杂一些。看例子。
<?php
$aa = 'abc';
echo "'$aa'";
echo "\{$aa}"; // 这样写 PHP5.1.1以前后会显示不同的结果
echo "\\{{$aa}}"; // 这样写就没问题
?>
双引号中可以有变量,可以用"$a"或"{$a}"形式来表现,个人建议大家多用后面的写法,第一编辑器会高亮,第二能写更复杂的式子。要注意,虽然"'{$a}'"的结果和"'".$a."'"的结果一样,但是{并非'"的简写,echo "'{__FILE__}'"和echo "'".__FILE__."'"结果是不同的。因为双引号中的封闭区间是以 {$ xxxx } 这种结构(或${xxxx}结构,不过这个和双引号外面的结构不一样,我不太喜欢)。所以可以写{$this->func()},不能写{self::func()},或{常量}。
<?php
function demo() {return 'abc';}
function abc() {return '123';}
$func = function() {return 'function';}; // 需要php5.3以上版本
$abc = 'abc';
$abc1 = 'abc--one::';
echo ${demo().'1'};
echo ${demo('}}')}();
echo "\{{${demo()}()}:::{$func()}\}{\$";
$test = 'Test';
echo ":::<br/>{$test::func()}:::";
class Test
{
static public function func()
{
return 'static func';
}
}
?>
虽然php的双引号很强大,但很多场合并不太需要, 要生成页面,很多时候可以这样写:
$form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value, $name).'" />'."\n";
这个是CI框架中form_helper.php的form_hidden的一行代码。
要输出的单引号多时,用双引号括字符串。反之用单位引号。单引号和双引号相比,用来括字符串效率并不会高多少,虽然单引号只需要转义\\和\',双引号的有
Sequence | Meaning |
\n | 换行 (LF or 0x0A (10) in ASCII) |
\r | 回车 (CR or 0x0D (13) in ASCII) |
\t | 水平方向的 tab(HT or 0x09 (9) in ASCII) |
\v | 竖直方向的 tab (VT or 0x0B (11) in ASCII) (since PHP 5.2.5) |
\f | 换页 (FF or 0x0C (12) in ASCII) (since PHP 5.2.5) |
\\ | 反斜线 |
\$ | 美金dollar标记 |
\" | 双引号 |
\[0-7]{1,3} | 符合该表达式顺序的字符串是一个八进制的字符 |
\x[0-9A-Fa-f]{1,2} | 符合该表达式顺序的字符串是一个十六进制的字符 |
这么多要转义,但我想程序在遍历每一个字符时,实际上它最初只需要判断 \ " $ ,可能还有 {。
那么双引号和单引号一样多时应该怎么输出呢?我们先看一下别的语言的解决方案。
Python 可以用 ''' 或者 """ 来闭合字符串,这之中并不需转义"和',有需要的话,可以写成这样 '''这样'''+"'''"。
因为php是一个模版语言,所以想直接输出的话(最好写大引用的模版文件里),直接写html就可以了。
不直接输出的话, php 用的是 heredoc语法结构和nowdoc(语法结构自PHP 5.3.0以后) 。
Heredoc是以 <<<xxxx 开头, 以 xxxx; 结尾;Nowdoc,是以 <<<'xxxx' 开头, 以 xxxx;结尾。注意xxxx;结尾要在回车后且和回车语句之间不能有别的字符。
<?php
$a = 'abc';
$b = 'html';
$c = <<<html
'{$b}'
html;
$d = "'{$b}'
";
if ($c === $d)
{
echo <<<abc
\$c === \$d:::'{$a}' {$c}
abc<br/>
abc;
echo <<<'test'
\$c === \$d:::'{$a}' {$c}
'test'
test<br/>
test;
}
?>
Javascript没有原生的方法,但是依靠html,还是可以解决问题。
下面写个iframe异步提交的例子。
<?php
/* iframe_test.php */
if (isset($_POST['cmd']))
{
// 正规的写法是引用模版文件。
?>
<textarea id="show-div"><?php
echo $_POST['textarea'];
?></textarea>
<script>
var a = document.getElementById("show-div").value;
parent.show(document.getElementById("show-div").value);
</script>
<?php
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Welcome to CodeIgniter</title>
</head>
<body>
<iframe name="iframe_show" width="0" height="0" scrolling="no" style="display:none">
</iframe>
<h1>js在文件后面!</h1>
<form name="mainform" target="iframe_show" method="post" enctype="multipart/form-data">
<textarea name="textarea"><script>alert(123)</script></textarea>
<input type="submit" name="cmd" value="提交" />
<input type="reset" value="撤消" />
</form>
<div id="show">Hello World</div>
</body>
<style type="text/css">
</style>
<script>
//<![CDATA[
function show(str) {
alert(str);
document.getElementById("show").innerHTML = str;
}
//]]>
</script>
</html><?php /* iframe_test.php */
作为数组的键的字符串:
php的数组的键只有两种类型,整数和字符串,'0'~'9'会被认是整数或转成整数。见下例。
<?php
$arr_type = array(
0x34 => '0x34',
1 => '1',
'1' => "'1'",
1.99 => '1.99',
true => 'true',
0 => '0',
false => 'false',
'0' => "'0'",
0.0 => '0.0',
0.01 => '0.01',
.99 => '0.99',
-1 => '-1',
'1.99' => "''1.99'
'",
);
var_dump($arr_type, json_encode($arr_type), json_encode($arr_type));
if (1 !== true)
{
echo count($arr_type),'<br/>';
echo $arr_type[1.99],'<br/>';
echo $arr_type[false],'<br/>';
echo $arr_type['1.99'],'<br/>';
echo $arr_type[-1],'<br/>';
echo $arr_type[0x34],'<br/>';
}
?>
上例的数组只有五行,多少可以预见,但下面的echo 却能用false 1.99这样的非整数键正常输出。编程是一种严格的事,我们不希望出现许多意外的结果;而且这种转义一定程度上影响效率。别的语言的这种数据结构,会有严格模式和宽松模式,比如lisp有这两种模式,python只有严格模式(如hash={'1': 1}; print(hash[1]);#这个会报错——话说python虽然说是脚本语言,但是最开始设计时,比别的脚本语言要严格的多,所以测试性比别的脚本语言好。如果你哪天想设计一个自己的语言,先要向严格方向设计,以后留个ini让别人配置;写好了的程序,由严格向宽松转容易,宽松转到严格模式,很多时候完全地不可能或目测上不可能)。但php的数组,只有这种宽松模式,希望php5.6能出点新东西。
Javascript也差不多,不过键都是字符串。写的代码如果键是负数,不会转成字符串。ture和flase会被转成'true'和'flase'.。
<script>
var arr = {
a: '47a',
'b': 12,
1: '1',
/* -1: '-1', */
1.99: '1.99',
'-1': '-1',
false: 'false',
0: '0',
'0': 'char0',
};
var i;
var str = '';
for (i in arr) {
str += typeof(i)+': '+i+' => '+arr[i]+'\n';
}
if (1 !== true) {
alert([
arr['1'],
arr[1.99],
arr[-1],
arr['a'],
arr[false],
arr[0],
arr['0'],
str,
]);
}
</script>
Dart和Javascript差不多,也是只能用字符串作键,但是并不会转义。下面例子会报错。个人并不看好dart的前景,只是写东西时一时兴起,拿来测测看下。果然语言不同,便有各种微差别,想到自己很多时候php用多了,用js时便想当然以为也如此,便好笑了。下面的Dart代码会报错
void main() {
print("Hello, World!");
var a = {'1': 1};
var b = {1: 1}; // 报错原因
print(a['1']);
print(a[1]); // 报错原因
}
在有的配置下,php能这样写,$arr = array('key' => 'val'); echo $arr[key]; 但是这种写法,php会首先看key是不是常量(php自带的常量都有上千个),如果不是常量,就作字符串。所以这种写法效率很低下,比$arr['key']慢几倍(常量多的项目,还要更慢)。echo "$arr[key]"则和echo "{$arr['key']}的效率差不多,因为双引号中不需要考虑常量。一般来说$arr[key]这种写法少打字又清晰,但多打两个' 会使你的程序环保一些,通用一些,也是不难做到的。
如果php的常量像变量一样,前面有个前缀,如#,反正有//代替#。一般写$arr[key]就不用考虑常量,效率高又方便程序员。写$arr[#key]的情况不多,有需要时写成$arr['#key']。或者学erlang的(我比较不喜欢erlang那种从prolog那继承的语法, 更习惯看c或lisp那种语法),使“变量”只能使用大写和下划线命名,非纯大写和下划线用于“原子”的命名;php自带的常量都是大写的,我见过的php项目,常量都是用大写字母和下划线命名,可能有极少不是,而表单的name值在大部分项目中都是小写,这样多数数组就只用非纯大写和下划线就可以了。如果5.6能出这个功能,改个ini就实现的话,多数公司的php新项目,估计都会用这个功能。
本文链接http://www.cxybl.com/html/wlbc/Php/20130729/39380.html