0

(名前付きprintfスタイルのパラメーターを持つSQLクエリと連想配列が与えられた場合)名前付きパラメーターを(SQL準備済みステートメントの)疑問符に置き換え、配列を再配置できるPHP関数を作成しようとしています。クエリに表示される順序で。

動作する次のコードを作成しましたが、コメント内に表示される名前付きパラメーターを無視するようにこのコードを拡張したいと思います。

function sqlprintfn($sql, array $args = array()) {
    $ordered_args = array();
    static $formats = array('b','c','d','e','E','u','f','F','g','G','o','s','x','X');
    $regex = sprintf('/(\?\(([a-zA-Z_]\w*)\)([%s]))/', implode('', $formats));

    // Find the next named argument. Each search starts at the end of the previous replacement
    for ($pos = 0; preg_match($regex, $sql, $match, PREG_OFFSET_CAPTURE, $pos);) {
        $arg_pos = $match[0][1];
        $arg_len = strlen($match[0][0]);
        $arg_key = $match[2][0];
        $arg_format = $match[3][0];

        // Programmer did not supply a value for the named argument found in the format string
        if (!array_key_exists($arg_key, $args)) {
            trigger_error(sprintf('%s(): Missing argument \'%s\'', __FUNCTION__, $arg_key), E_USER_WARNING);
            return false;
        }
        array_push($ordered_args, $args[$arg_key]);

        // Replace the named argument with a question mark
        $sql = substr_replace($sql, $replace = '?', $arg_pos, $arg_len);
        $pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration
    }

    return array_merge((array) $sql, $ordered_args);
}

私が達成しようとしているものの例として:

$sql = 'SELECT id FROM users WHERE username = ?(username)s AND type = ?(type)s';
$params = array('type' => 'admin', 'username' => 'bob', email => 'bob@domain.com');
print_r(sqlprintfn($sql, $params));

出力する必要があります:

Array
(
    [0] => 'SELECT id FROM users WHERE username = ? AND type = ?',
    [1] => 'bob',
    [2] => 'admin'
)

と:

$sql = 'SELECT id FROM users WHERE /* email = ?(email)s AND */ username = ?(username)s AND type = ?(type)s';
$params = array('type' => 'admin', 'username' => 'bob', email => 'bob@domain.com');
print_r(sqlprintfn($sql, $params));

出力する必要があります:

Array
(
    [0] => 'SELECT id FROM users WHERE /* email = ?(email)s AND */ username = ? AND type = ?',
    [1] => 'bob',
    [2] => 'admin'
)

また、$sql 変数は複数行である可能性があることに注意してください。

4

0 に答える 0