Shlex 是一个用 C 语言编写的 PHP 扩展。该扩展在 Python 中实现了 shlex 库的功能。为了让用户更加熟悉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 中一样相互保护)。默认情况下,包括 ASCII 单引号和双引号。
将被视为转义的字符。这将仅在 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');
?>