php手冊中的tokenizer詳細總結,基本看它就夠了
阿新 • • 發佈:2018-12-23
tokenizer - 解析器
簡介:
tokenizer函式提供了一個內嵌在Zend引擎的"PHP tokenizer"的呼叫介面。使用這些函式,你可以寫出你自己的PHP原始碼分析或者修改工具,而無需處理詞法分析級別上的語言規範。僅包含2個函式:
token_get_all(string $source)1.token_get_all() 解析提供的 source 原始碼字元,然後使用 Zend 引擎的語法分析器獲取原始碼中的 PHP 語言的解析器代號
2.$source - 需要解析的php原始碼
3.返回值:返回原始碼解析後的所有token標誌符陣列。
4.每個單獨的token標誌符,有2種形式:
1>單個字元,例如:: ; , .
2>一個包含3個元素的陣列,0-token索引(可呼叫token_name()來獲取字面量) | 1-token原始碼字串 | 2-行號
5.例項:
$tokens = token_get_all('<?php echo "dongxuemin"; echo "zhangrui";?>');
解析後:
Array ( [0] => Array ( [0] => 379 [1] => 1 ) [1] => Array ( [0] => 328 [1] => echo [2] => 1 ) [2] => Array ( [0] => 382 [1] => [2] => 1 ) [3] => Array ( [0] => 323 [1] => "dongxuemin" [2] => 1 ) [4] => ; [5] => Array ( [0] => 382 [1] => [2] => 1 ) [6] => Array ( [0] => 328 [1] => echo [2] => 1 ) [7] => Array ( [0] => 382 [1] => [2] => 1 ) [8] => Array ( [0] => 323 [1] => "zhangrui" [2] => 1 ) [9] => ; [10] => Array ( [0] => 381 [1] => ?> [2] => 1 ) )
token_name(int $token)
1.獲取提供的 PHP 解析器代號的符號名稱
2.$token - 解析器代號的值。接收的是 token_get_all()解析出來的token陣列中的第一個元素(token索引),是個int型別
3.返回值:提供的token的符號名
4.例項:
token_name(328); // 返回 'T_OPEN_TAG'
解析器代號列表
1.PHP 語言的不同部分在內部被表示為類似 T_SR 的型別。PHP 在解析錯誤時輸出這樣的識別符號,例如 "Parse error: unexpected T_SR, expecting ',' or ';' in script.php on line 10."。2.應該知道 T_SR 的含義。對於所有不知道的人,下表列出了這些識別符號,PHP 語法和在手冊中適當位置的參考。
3.注意:T_*常量的使用
所有下面列出的token,也被定義為PHP常量。它們的值是基於PHP底層的解析器,自動生成的。這意味著:在兩個不同的PHP版本間,同樣的token代表的值可能不同。例如:T_FILE常量在PHP5.3是365,在PHP5.4就是369。這也意味著:你的程式碼絕對不能直接依賴具體某個PHP版本的原始 'T_*' token值,去提供PHP跨版本的相容性(就是我們不能使用token值作為版本相容,同一token的值不同版本可能是不同的)。相反你的程式碼應利用自定義的值 (使用大的數字,像 10000)和適當的策略,來實現 'T_*' 的值和PHP版本相容性。(我們得將列表中所有的token的值,重新定義,而不採用系統的)
4.不過這裡有個疑問:常量的值不可重新定義,也不清楚具體該怎麼做,使用變數?主要是不清楚需求...
5.通過解析器代號列表,我們就可以查詢我們通過 token_name() 獲取到的 token名代表的內容。
該列表,並沒有列出token對應的int型別的值,就是因為上面講的:值是自動生成的,不同版本相同的token是不同的值
上面幾點,就是手冊上涉及的幾個重要概念,我們大概也瞭解到了,就是:解析php原始碼,然後我們自己實現自己的邏輯,接下來,寫幾個例項(參照別人的部落格,或其他地方資料):
1.原始碼高亮展示,php自帶的相關方法有 highlight_string(),highlight_file(),我順便對這2個方法進行了檢視,總結,可參照:2.壓縮php程式碼,去除不要的換行、空白以及註釋,轉載別人的部落格,可參照:
有人指出了 'php_strip_whitespace' 可做相同的事情,就研究下這個函式,看了下手冊,裡面有個評論,也寫了一個壓縮php的程式碼,乾脆再寫篇文章了
3.上面部落格有人評論說:可做一個能列出某php檔案所有函式名,和引數表,感覺這個想法不錯,只要和原始碼相關的,我們都可以想著做
4.在stackoverflow.com上查看了個類似的問題,有人回答,參照連結:
tokenizer的一些實用例項:http://stackoverflow.com/questions/5727951/what-are-some-practical-uses-of-php-tokenizer
1>有的框架用tokenizer生成快取檔案或中間class類檔案
2>原始碼格式化、高亮顯示
3>可收集所有定義的class,methods,variables,文件,註釋等
4>一些安全檢測等,保證程式碼更安全。不允許使用的php函式,反正各種安全檢測。。。
5>基本上,能使用php程式碼作為資料的任何地方,我們都可以使用tokennizer。它比使用正則表示式,或其他處理函式,來解析php程式碼都更可靠。
5.如何在php檔案中,檢視是否定義了某個類?上面評論裡的問題,挺有意思:
1>當可以使用include命令時:
$before = get_declared_classes();
include "myfile.php";
$after = get_declared_classes();
$new_classes = array_diff($before, $after); // 取差集
print_r($new_classes); // Outputs all classes defined in myfile.php
對比載入該檔案前後,已經定義的類
2>當不可以使用include命令時(有可能因為該檔案定義了一個同名的類,會報錯!)
可以使用tokenizer分析出該檔案所有的class
總結下:
偶然的在dedecms中看原始碼,看到使用了這個tokenizer函式,就引申出一連串的東西,對手冊等函式,一些擴充套件,稍微底層點的東西,必需都瞭解!與大家共勉!