Example #1
0
function sql_placeholder_ex($tmpl, $args, &$errormsg)
{
    // Запрос уже разобран?.. Если нет, разбираем.
    if (is_array($tmpl)) {
        $compiled = $tmpl;
    } else {
        $compiled = sql_compile_placeholder($tmpl);
    }
    list($compiled, $tmpl, $has_named) = $compiled;
    // Если есть хотя бы один именованный placeholder, используем
    // первый аргумент в качестве ассоциативного массива.
    if ($has_named) {
        $args = @$args[0];
    }
    // Выполняем все замены в цикле.
    $p = 0;
    // текущее положение в строке
    $out = '';
    // результирующая строка
    $error = false;
    // были ошибки?
    foreach ($compiled as $num => $e) {
        list($key, $type, $start, $length) = $e;
        // Pre-string.
        $out .= substr($tmpl, $p, $start - $p);
        $p = $start + $length;
        $repl = '';
        // текст для замены текущего placeholder-а
        $errmsg = '';
        // сообщение об ошибке для этого placeholder-а
        do {
            // Это placeholder-константа?
            if ($type === '#') {
                $repl = @constant($key);
                if (NULL === $repl) {
                    $error = $errmsg = "UNKNOWN_CONSTANT_{$key}";
                }
                break;
            }
            // Обрабатываем ошибку.
            if (!isset($args[$key])) {
                $error = $errmsg = "UNKNOWN_PLACEHOLDER_{$key}";
                break;
            }
            // Вставляем значение в соответствии с типом placeholder-а.
            $a = $args[$key];
            if ($type === '') {
                // Скалярный placeholder.
                if (is_array($a)) {
                    $error = $errmsg = "NOT_A_SCALAR_PLACEHOLDER_{$key}";
                    break;
                }
                $repl = preg_match('/^\\d+$/', $a) ? $a : "'" . addslashes($a) . "'";
                break;
            }
            // Иначе это массив или список.
            if (!is_array($a)) {
                $error = $errmsg = "NOT_AN_ARRAY_PLACEHOLDER_{$key}";
                break;
            }
            if ($type === '@') {
                // Это список.
                foreach ($a as $v) {
                    $repl .= ($repl === '' ? "" : ",") . "'" . addslashes($v) . "'";
                }
            } elseif ($type === '%') {
                // Это набор пар ключ=>значение.
                $lerror = array();
                foreach ($a as $k => $v) {
                    if (!is_string($k)) {
                        $lerror[$k] = "NOT_A_STRING_KEY_{$k}_FOR_PLACEHOLDER_{$key}";
                    } else {
                        $k = preg_replace('/[^a-zA-Z0-9_]/', '_', $k);
                    }
                    $repl .= ($repl === '' ? "" : ", ") . $k . "='" . @addslashes($v) . "'";
                }
                // Если была ошибка, составляем сообщение.
                if (count($lerror)) {
                    $repl = '';
                    foreach ($a as $k => $v) {
                        if (isset($lerror[$k])) {
                            $repl .= ($repl === '' ? "" : ", ") . $lerror[$k];
                        } else {
                            $k = preg_replace('/[^a-zA-Z0-9_-]/', '_', $k);
                            $repl .= ($repl === '' ? "" : ", ") . $k . "=?";
                        }
                    }
                    $error = $errmsg = $repl;
                }
            } elseif ($type === '&') {
                // Это список.
                foreach ($a as $v) {
                    $repl .= ($repl === '' ? "" : ",") . '`' . addslashes($v) . '`';
                }
            }
        } while (false);
        if ($errmsg) {
            $compiled[$num]['error'] = $errmsg;
        }
        if (!$error) {
            $out .= $repl;
        }
    }
    $out .= substr($tmpl, $p);
    // Если возникла ошибка, переделываем результирующую строку
    // в сообщение об ошибке (расставляем диагностические строки
    // вместо ошибочных placeholder-ов).
    if ($error) {
        $out = '';
        $p = 0;
        // текущая позиция
        foreach ($compiled as $num => $e) {
            list($key, $type, $start, $length) = $e;
            $out .= substr($tmpl, $p, $start - $p);
            $p = $start + $length;
            if (isset($e['error'])) {
                $out .= $e['error'];
            } else {
                $out .= substr($tmpl, $start, $length);
            }
        }
        // Последняя часть строки.
        $out .= substr($tmpl, $p);
        $errormsg = $out;
        return false;
    } else {
        $errormsg = false;
        return $out;
    }
}
Example #2
0
function sql_placeholder()
{
    $args = func_get_args();
    $tmpl = array_shift($args);
    if (is_array($tmpl)) {
        $compiled = $tmpl;
    } else {
        $compiled = sql_compile_placeholder($tmpl);
    }
    $has_named = $compiled[2];
    $tmpl = $compiled[1];
    $compiled = $compiled[0];
    if ($has_named) {
        $args = @$args[0];
    }
    $p = 0;
    $out = "";
    foreach ($compiled as $e) {
        $length = $e[3];
        $start = $e[2];
        $type = $e[1];
        $key = $e[0];
        $out .= substr($tmpl, $p, $start - $p);
        $p = $start + $length;
        $repl = "";
        if ($type === "#") {
            while (NULL === ($repl = @constant($key))) {
                $repl = "UNKNOWN_CONSTANT_" . $key;
            }
        } else {
            if (isset($args[$key])) {
                $repl = "UNKNOWN_PLACEHOLDER_" . $key;
            } else {
                $a = $args[$key];
                if ($type === "") {
                    if (is_array($a)) {
                        $repl = "NOT_A_SCALAR_PLACEHOLDER_" . $key;
                        break;
                    } else {
                        $repl = "'" . addslashes($a) . "'";
                    }
                } else {
                    if (is_array($a)) {
                        $repl = "NOT_AN_ARRAY_PLACEHOLDER_" . $key;
                    } else {
                        if ($type === "@") {
                            foreach ($a as $v) {
                                $repl .= ($repl === "" ? "" : ",") . "'" . addslashes($v) . "'";
                            }
                        } else {
                            if ($type === "%") {
                                foreach ($a as $k => $v) {
                                    if (is_string($k)) {
                                        $k = "NOT_A_STRING_KEY_" . $k . "_FOR_PLACEHOLDER_{$key}";
                                    } else {
                                        $k = preg_replace("/[^a-zA-Z0-9_-]/", "_", $k);
                                    }
                                    $repl .= ($repl === "" ? "" : ", ") . $k . "='" . @addslashes($v) . "'";
                                }
                            }
                        }
                        if (false) {
                        }
                    }
                }
            }
        }
    }
    $out .= $repl;
}