Shlex 是一個用 C 語言編寫的 PHP 擴充功能。為了讓使用者更熟悉Shlex擴展,此擴充實作的類別在屬性和方法名稱上與python shlex函式庫基本相同。介面文檔也是從python shlex庫介面文檔修改而來。
Shlex 可以輕鬆地為類似 Unix shell 的簡單語法編寫詞法分析器。這對於編寫迷你語言或解析引用的字串通常很有用。
phpize
./configure
make && make install
目前不支援Windows系統。
使用類似 shell 的語法分割字串 s。
array shlex_split( string|resource|null $s [, bool $comments = false [, bool $posix = true ]] )
使用類似 shell 的語法分割字串 s。
Note:
Since the shlex_split() function instantiates a shlex instance, passing null for s will read the string to split from standard input.
如果 comments 為 false(預設值),則將停用給定字串中註解的解析(將 shlex 實例的 commenters 屬性設為空字串)。
此函數預設在 POSIX 模式下執行,但如果 posix 參數為 false,則使用非 POSIX 模式。
傳回分割字串的陣列。
<?php
$s = "foo#bar";
$ret = shlex_split($s, true);
var_dump($ret);
?>
上面的例子將會輸出:
array(1) {
[0] =>
string(3) "foo"
}
傳回字串 s 的 shell 轉義版本。
string shlex_quote( string $s )
要轉義的字串。
傳回值是一個字串,在無法使用清單的情況下,可以安全地將其用作 shell 命令列中的一個標記。
<?php
// If the output is executed, it will cause the index.php file to be deleted.
$filename = "somefile; rm -rf index.php";
$command = sprintf("ls -l %s", $filename);
echo $command;
echo "n";
// shlex_quote() blocked the vulnerability
$command = sprintf("ls -l %s", shlex_quote($filename));
echo $command;
echo "n";
// remote connection
$remoteCommand = sprintf("ssh home %s", shlex_quote($command));
echo $remoteCommand;
echo "n";
?>
上面的例子將會輸出:
ls -l somefile; rm -rf index.php
ls -l 'somefile; rm -rf index.php'
ssh home 'ls -l '"'"'somefile; rm -rf index.php'"'"''
Shlex 實例或子類別實例是詞法分析器物件。
Shlex implements Iterator {
/* Properties */
public resource|null $instream = null;
public string|null $infile = null;
private bool|null $posix = null;
public string|null $eof = null;
public string $commenters = '#';
public string $wordchars = 'abcdfeghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_';
public string $whitespace = " trn";
public bool $whitespaceSplit = false;
public string $quotes = ''"';
public string $escape = '\';
public string $escapedquotes = '"';
private string $state = ' ';
private array $pushback = [];
public int $lineno = 1;
public int $debug = 0;
public string $token = '';
private array $filestack = [];
public string|null $source = null;
public string|null $punctuationChars = null;
private array|null $_punctuationChars = null;
/* Methods */
public void function __construct( [ string|resource|null $instream = null [, string|null $infile = null [, bool $posix = false [, string|bool|null $punctuationChars = false ]]]]);
public void function __destruct( void );
public void function key( void );
public void function next( void );
public void function rewind( void );
public string|null function current( void );
public bool function valid( void );
public void function pushToken( string $tok );
public void function pushSource( string|resource $newstream, string|null $newfile = null );
public void function popSource( void );
public string|null|ShlexException function getToken( void );
public string|null|ShlexException function readToken( void );
public array function sourcehook( string $newfile );
public string function errorLeader( string $infile = null, int|null $lineno = null );
}
此 Shlex 實例從中讀取字元的輸入流。
目前輸入檔案的名稱,最初在類別實例化時設定或由以後的來源請求堆疊。在構造錯誤訊息時檢查這一點可能很有用。
用於確定文件結尾的令牌。在非 POSIX 模式下,該值將設定為空字串 ('');在 POSIX 模式下,該值將設為 null。
被識別為評論初學者的字串。從註解開頭到行尾的所有字元都將被忽略。預設僅包含“#”。
將累積成多字元標記的字串。預設情況下,包括所有 ASCII 字母數字和底線。在 POSIX 模式中,也包含 Latin-1 集中的重音字元。如果punctuationChars 不為空,則可以出現在文件名規範和命令列參數中的字元~-./*?= 也將包含在此屬性中,並且出現在punctuationChars 中的任何字元如果出現在wordchars 中,將從wordchars 中刪除存在於那裡。
將被視為空白並被跳過的字元。空格限制標記。預設情況下,包括空格、製表符、換行符和回車符。
如果為 true,則標記將僅以空格分割。這很有用,例如,對於使用 Shlex 解析命令列,以與 shell 參數類似的方式取得標記。如果此屬性為 true,punctuationChars 將無法運作,並且僅在空格上進行分割。當使用 punctuationChars 時,其目的是提供更接近 shell 實作的解析,建議將 whitespaceSplit 保留為 false(預設值)。
將被視為字串引號的字元。標記會累積,直到再次遇到相同的引號(因此,不同的引號類型會像在 shell 中一樣相互保護)。
將被視為轉義的字元。這將僅在 POSIX 模式下使用,並且預設僅包含 ''。
引號中的字元將解釋轉義中定義的轉義字元。這僅在 POSIX 模式下使用,並且預設僅包含 '"'。
來源行號(到目前為止看到的換行符號計數加一)。
如果此屬性是數字且為 1 或更大,則 Shlex 實例將列印其行為的詳細進度輸出。如果您需要使用它,可以閱讀模組原始碼以了解詳細資訊。
令牌緩衝區。在捕獲異常時檢查這一點可能很有用。
該屬性預設為空。如果您為其指派字串,則字串將被辨識為詞法級包含請求,類似於各種 shell 中的 source 關鍵字。也就是說,緊接而來的標記將作為檔案名稱打開,並且將從該流中獲取輸入,直到 EOF,此時將呼叫該流的 fclose() 方法,並且輸入來源將再次成為原始輸入流。來源請求可以堆疊任意層深。
將被視為標點符號的字元。標點符號字元將作為單一標記傳回。但是,請注意,不會執行任何語義有效性檢查:例如,「>>>」可以作為標記返回,即使 shell 可能無法識別它。
建構函數
public void function Shlex::__construct( [ string|resource|null $instream = null [, string|null $infile = null [, bool $posix = false [, string|bool|null $punctuationChars = false ]]]])
instream 參數(如果存在)指定要從何處讀取字元。它必須是一個資源類型變數(可以透過fread()讀取),或一個字串。如果未給予參數,將從 php://stdin 取得輸入。
第二個可選參數是檔案名稱字串,它設定 infile 屬性的初始值。如果 instream 參數為 null,則此 infile 參數始終為 null。
posix 參數定義操作模式:當 posix 為 false(預設)時,Shlex 實例將以相容模式操作。當在 POSIX 模式下執行時,Shlex 會嘗試盡可能接近 POSIX shell 解析規則。
punctuationChars 參數提供了一種使行為更接近真實 shell 解析方式的方法。這可以採用多個值:預設值 false。如果設定為 true,則字元 ();<>|& 的解析將發生變更:這些字元(視為標點符號字元)的任何運行都會以單一標記傳回。如果設定為非空字串,這些字元將用作標點符號。 wordchars 屬性中出現在 punctuationChars 中的任何字元都將從 wordchars 中刪除。
沒有回傳值。
<?php
$instance = new Shlex("a && b || c", null, false, "|");
$list = [];
foreach ($instance as $value) {
$list[] = $value;
}
var_dump($list);
?>
上面的例子將會輸出:
array(6) {
[0] =>
string(1) "a"
[1] =>
string(1) "&"
[2] =>
string(1) "&"
[3] =>
string(1) "b"
[4] =>
string(2) "||"
[5] =>
string(1) "c"
}
析構函數
public void function Shlex::__destruct( void )
用於釋放Shlex物件所持有的資源物件。在內部,呼叫 fclose() 來關閉檔案句柄。
無參數。
沒有回傳值。
沒有例子。
Iterator介面的關鍵方法沒有實際用途。
public void function Shlex::key( void )
無參數。
沒有回傳值。
沒有例子。
Iterator 介面的 next 方法沒有實際用途。
public void function Shlex::next( void )
無參數。
沒有回傳值。
沒有例子。
Iterator 介面的 rewind 方法沒有實際用途。
public void function Shlex::rewind( void )
無參數。
沒有回傳值。
沒有例子。
傳回 Shlex 本次迭代讀取的令牌值。
public string|null function Shlex::current( void )
無參數。
傳回 Shlex 本次迭代讀取的令牌值。
沒有例子。
確定本次迭代是否有效。
public bool function Shlex::valid( void )
無參數。
傳回 true 則有效, false 則無效。
Note:
Due to the implementation of this class, iteratively reading the next element is also called inside the method. So the next() method is invalid.
沒有例子。
將參數推入令牌堆疊。
public void function Shlex::pushToken( string $tok )
被推送的參數。
沒有回傳值。
沒有例子。
將輸入源流推入輸入堆疊。
public void function Shlex::pushSource( string|resource $newstream, string|null $newfile = null );
正在推送的輸入來源流。
如果指定了檔案名稱參數,它將稍後可在錯誤訊息中使用。這與 sourcehook() 方法內部所使用的方法相同。
沒有回傳值。
沒有例子。
從輸入堆疊中彈出最後推送的輸入來源。這與詞法分析器在堆疊輸入流上到達 EOF 時內部使用的方法相同。
public void function Shlex::popSource( void )
無參數。
沒有回傳值。
沒有例子。
返回一個令牌。
public string|null|ShlexException function Shlex::getToken( void )
無參數。
如果已使用pushToken() 堆疊令牌,則從堆疊中彈出令牌。否則,從輸入流中讀取一個。如果讀取遇到立即檔案結束,則傳回 eof(非 POSIX 模式下為空字串 (''),POSIX 模式下為 null)。
沒有例子。
讀取原始令牌。
public string|null|ShlexException function Shlex::readToken( void )
讀取原始令牌。忽略推回堆疊,並且不解釋來源請求。 (這通常不是一個有用的切入點,在這裡記錄只是為了完整性。)
無參數。
回傳一個原始令牌。
沒有例子。
public array function Shlex::sourcehook( string $newfile )
當 Shlex 偵測到來源請求(請參閱下方的來源)時,此方法將被賦予以下標記作為參數,並期望傳回一個檔案名稱陣列和一個開啟的類似檔案的物件。
通常,此方法會先刪除參數中的所有引號。如果結果是絕對路徑名,或沒有有效的先前來源請求,或者先前來源是流(例如 php://stdin),則結果將保持不變。否則,如果結果是相對路徑名,則來源包含堆疊上緊鄰該檔案之前的檔案名稱的目錄部分將被新增至前面(此行為類似於 C 預處理器處理 #include "file.h" 的方式)。
操作的結果被視為檔名,並作為元組的第一個元件返回,並調用 fopen() 來產生第二個元件。 (注意:這與實例初始化中參數的順序相反!)
這個鉤子是公開的,以便您可以使用它來實現目錄搜尋路徑、添加檔案副檔名和其他命名空間駭客。沒有對應的「close」鉤子,但 shlex 實例在傳回 EOF 時將呼叫來源輸入流的 fclose() 方法。
若要更明確控制來源堆疊,請使用pushSource() 和popSource() 方法。
文件路徑。
傳回一個檔案名稱數組和一個開啟的類別文件物件。
沒有例子。
以 Unix C 編譯器錯誤標籤的格式傳回錯誤訊息前導符。
public string function Shlex::errorLeader( string $infile = null, int|null $lineno = null )
此方法以 Unix C 編譯器錯誤標籤的格式產生錯誤訊息前導符;格式為 '"%s", line %d: ',其中 %s 替換為目前來源檔案的名稱,%d 替換為目前輸入行號(可選參數可用於覆寫這些) 。
提供這種便利是為了鼓勵 Shlex 使用者以 Emacs 和其他 Unix 工具所理解的標準、可解析格式產生錯誤訊息。
目前來源檔案的名稱。
目前輸入行號。
以 Unix C 編譯器錯誤標籤的格式傳回錯誤訊息前導符。
沒有例子。
Shlex的異常類
該類別主要用於Shlex類別內部執行錯誤時拋出的異常。
ShlexException extends Exception {}
<?php
throw new ShlexException('No escaped character');
?>