查找printf()语句中使用的参数数量

时间:2009-12-04 06:01:48

标签: php variables printf

鉴于一些未知输入,您如何判断哪些变量被替换为(s)printf语句?

printf("%s %s", "a", "b");     // both used
printf("%s",    "a", "b");     // only the first one used
printf('%1$s %1$s', "a", "b"); //      "        "
printf('%s %1$s', "a", "b");    //     "        "
printf('%1$s %s %1$s', "a", "b");   // "        "
printf('%2$s', "a", "b");      // only the second one used.

检查结果字符串是否存在第一个或第二个变量将无济于事,因为它们可能具有相同的值。

在我自己的情况下,只有2个变量可以被替换,我需要知道是否使用了第二个变量。

3 个答案:

答案 0 :(得分:2)

自己解析格式字符串并查看它预期的args数量。

编辑:一个伪代码示例(没有错误检查):

bool arg1used = false;
bool arg2used = false;
int unspecifiedscount = 0;
for (int i = 0; i < s.length; i++) {
    if s[i] != '%' continue;
    switch s[i+1] {
        case '%':
            i++;
            break;
        case 's':
            if unspecifiedscount == 0 arg1used = true;
            if unspecifiedscount == 1 arg2used = true;
            break;
        case '1':
            if s[i+2] == '$' && s[i+3] == 's' {
                arg1used = true;
                i+=3;
                true;
            }
            break;
        case '2':
            if s[i+2] == '$' && s[i+3] == 's' {
                arg2used = true;
                i+=3;
                true;
            }
            break;
    }
}

答案 1 :(得分:1)

我想出了一种适用于这种情况的kludgey方式,但是有兴趣听听更通用的更好的解决方案。

if (($result = @sprintf($input, "a")) === false) {
    // need two arguments
    $result = sprintf($input, "a", "b");
} else {
    // only needed one argument
}

基本上,它只是用一个参数尝试它,如果这不起作用,那么你知道它需要两个。

答案 2 :(得分:1)

这是一个有点hackish功能:

function printf_and_return_min_args_required(/* var args */) {
    $old_track = ini_set('track_errors', '1');
    $args = func_get_args();
    $args2 = array();
    $required = 100;    
    foreach ($args as $arg) {
        $args2[] = $arg;
        if (@call_user_func_array("printf", $args2)) {
            $required = count($args2) - 1;
            break;
        }
    }
    ini_set('track_errors', $old_track);
    return $required;
}

对于sprintf(),如果您不希望函数打印array($result, $required),则可能需要返回$result