- 001
- 002
- 003
- 004
- 005
- 006
- 007
- 008
- 009
- 010
- 011
- 012
- 013
- 014
- 015
- 016
- 017
- 018
- 019
- 020
- 021
- 022
- 023
- 024
- 025
- 026
- 027
- 028
- 029
- 030
- 031
- 032
- 033
- 034
- 035
- 036
- 037
- 038
- 039
- 040
- 041
- 042
- 043
- 044
- 045
- 046
- 047
- 048
- 049
- 050
- 051
- 052
- 053
- 054
- 055
- 056
- 057
- 058
- 059
- 060
- 061
- 062
- 063
- 064
- 065
- 066
- 067
- 068
- 069
- 070
- 071
- 072
- 073
- 074
- 075
- 076
- 077
- 078
- 079
- 080
- 081
- 082
- 083
- 084
- 085
- 086
- 087
- 088
- 089
- 090
- 091
- 092
- 093
- 094
- 095
- 096
- 097
- 098
- 099
- 100
/**
* Компиляция плейсхолдера
*/
private function sql_compile_placeholder($tmpl)
{
$compiled = array();
$p = 0; // текущая позиция в строке
$i = 0; // счетчик placeholder-ов
$has_named = false;
while(false !== ($start = $p = strpos($tmpl, "?", $p)))
{
// Определяем тип placeholder-а.
switch ($c = substr($tmpl, ++$p, 1))
{
case '%': case '@': case '#':
$type = $c; ++$p; break;
default:
$type = ''; break;
}
// Проверяем, именованный ли это placeholder: "?keyname"
if (preg_match('/^((?:[^\s[:punct:]]|_)+)/', substr($tmpl, $p), $pock))
{
$key = $pock[1];
if ($type != '#')
$has_named = true;
$p += strlen($key);
}
else
{
$key = $i;
if ($type != '#')
$i++;
}
// Сохранить запись о placeholder-е.
$compiled[] = array($key, $type, $start, $p - $start);
}
return array($compiled, $tmpl, $has_named);
}
/**
* Выполнение плейсхолдера
*/
private function sql_placeholder_ex($tmpl, $args, &$errormsg)
{
// Запрос уже разобран?.. Если нет, разбираем.
if (is_array($tmpl))
$compiled = $tmpl;
else
$compiled = $this->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)
{
/* .. тут куча кода .. */
}
$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;
}
}