Решил я тут прогнуться под любителей именованных пейсхолдеров.
Соответственно, сделать запросы совместимыми с ПДО
Соответственно, ввести дефолтный плейсхолдер, без указания типа, обрабатывается, как строковый.
Соответственно, поддерживать ключи как с двоеточиями, так и без.
В этой связи накатал какой-то ужас.
Рабочий урезанный вариант класса можно взять здесь https://github.com/colshrapnel/safemysqli.dev/blob/master/safemysqli.class.php
Ну и сам код на посмотреть.
уду рад критическим замечаниям.
Соответственно, сделать запросы совместимыми с ПДО
Соответственно, ввести дефолтный плейсхолдер, без указания типа, обрабатывается, как строковый.
Соответственно, поддерживать ключи как с двоеточиями, так и без.
В этой связи накатал какой-то ужас.
Рабочий урезанный вариант класса можно взять здесь https://github.com/colshrapnel/safemysqli.dev/blob/master/safemysqli.class.php
Ну и сам код на посмотреть.
PHP:
function prepare($query, $args = array() )
{
$pattern = '~(\?[nsiuap]?|[nsiuap]?:[a-zA-Z_][a-zA-Z0-9_]*)~u';
$array = preg_split($pattern, $query , null, PREG_SPLIT_DELIM_CAPTURE);
$out = '';
if (key($args) === 0)
{
$mode = 'numeric';
$anum = count($args);
$pnum = floor(count($array) / 2);
if ( $pnum != $anum )
{
$this->error("Number of args ($anum) doesn't match number of placeholders ($pnum) in [$query]");
}
} else {
$mode = 'named';
}
foreach ($array as $i => $part)
{
if ( ($i % 2) == 0 )
{
$out .= $part;
continue;
}
if ($part[0] == '?')
{
if ($mode == 'named')
{
$this->error("Cannot mix named and positional placeholders");
}
$value = array_shift($args);
$type = trim($part,"?");
} else {
if ($mode == 'numeric')
{
$this->error("Cannot mix named and positional placeholders");
}
list($type, $key) = explode(":", $part);
if (isset($args[$key]))
{
$value = $args[$key];
} elseif (isset($args[":$key"])) {
$value = $args[":$key"];
} else {
$this->error("No key found for the named placeholder [$key] in the data array");
}
}
switch ($type)
{
case '':
case 's':
$part = $this->escapeString($value);
break;
case 'n':
$part = $this->escapeIdent($value);
break;
case 'i':
$part = $this->escapeInt($value);
break;
case 'a':
$part = $this->createIN($value);
break;
case 'u':
$part = $this->createSET($value);
break;
case 'p':
$part = $value;
break;
}
$out .= $part;
}
return $out;
}
PHP:
include 'safemysqli.class.php';
$db = new SafeMySQLi();
$sql = "SELECT :one FROM n:two WHERE f = i:tre OR f = i:tre OR f = :four\n";
$args['one'] = 'hello';
$args['two'] = 'table';
$args['tre'] = 5;
$args[':four'] = 666;
echo $db->prepare($sql, $args);
$sql = "SELECT ?s FROM ?n WHERE f = ?i OR f = ?\n";
$args = array('hello', 'table', 5,666);
echo $db->prepare($sql, $args);
echo $db->prepare("SELECT c FROM t \n");
SELECT 'hello' FROM `table` WHERE f = 5 OR f = 5 OR f = '666'
SELECT 'hello' FROM `table` WHERE f = 5 OR f = '666'
SELECT c FROM t
уду рад критическим замечаниям.