靈活的字串。
因為$表達的靈活性,我們可以用“映射”的方法,調出字串或者函數。
<?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