Skip to content

Commit

Permalink
fix: ! DB类变更where数组参数中子查询需要绑定sql的模式(键名前加冒号) [':field'=>$SubQuery]
Browse files Browse the repository at this point in the history
fix: DB类where数组参数['field1|field2|field3 LIKE'=>'value']解析错误
fix: DB类where数组参数增加键名是数字(非字段名)的解析
fix: 模板解析可能出现的错误
  • Loading branch information
playadmin committed Jan 6, 2024
1 parent 2f2113e commit 171ab6d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 30 deletions.
33 changes: 17 additions & 16 deletions lib/z/dbc/db.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ public function InTransaction()
public function GetSql (): string {
return $this->PDO->GetSql();
}
public function GetParams (): array {
return $this->PDO->GetParams();
}
public function Begin(): bool
{
$this->DB_CALL = [];
Expand Down Expand Up @@ -324,7 +327,7 @@ public function QueryChain(&$data, array $chain)
}
public function Parse ($reset = true): array
{
$sql = $this->DB_sql();
$sql = $this->DB_sql(true);
$field = $this->DB_field();
$res[] = "SELECT {$field} FROM " . $sql;
$res[] = $this->DB_BIND;
Expand Down Expand Up @@ -387,7 +390,7 @@ public function Count(string $field = '', bool $done = true): int
} else {
$result = $this->PDO->Stmt("SELECT COUNT({$field}) FROM {$from}", $this->DB_BIND)->Row(\PDO::FETCH_COLUMN);
}
$done ? $this->DB_done() : $this->DB_SQLD = '';
$done && $this->DB_done();
return (int)$result;
}
public function Merge(string $sql, string|array $type = ''): static
Expand Down Expand Up @@ -519,7 +522,7 @@ public function Select(string | bool $field = false, bool $lock = false): array
if ($lock || !$this->Z_CACHE) {
$field = $this->DB_field();
$this->DB_PAGE && $this->DB_page();
$sql = "SELECT {$field} FROM " . $this->DB_sql();
$sql = "SELECT {$field} FROM " . $this->DB_sql(!!$this->DB_PAGE);
$lock && $sql = $this->DB_lockRows($sql);
if (null === $sql) {
throw new Exception('Row lock is not supported');
Expand Down Expand Up @@ -960,14 +963,14 @@ protected function DB_whereArr(array $where): array
foreach ($where as $k => $value) {
if (is_int($k)) {
// 键名不是字段的情况
$pre = strtoupper(trim(substr($value, 0, 3)));
if ('AND' === $pre || 'OR' === $pre) {
$lc || $lc = "{$pre} ";
return [$this->WrapSql($value), ''];
} else {
$lc || $lc = 'AND ';
return [$this->WrapSql($value), $lc];
if (!$sql) {
$pre = strtoupper(substr($value, 0, 3));
if ('AND' === $pre || 'OR ' === $pre) {
$value = ltrim(substr($value, 3));
}
}
$sql .= $this->WrapSql($value);
continue;
}

list($isSqlValue, $logic, $key, $operator) = $this->DB_checkKey($k);
Expand All @@ -981,7 +984,7 @@ protected function DB_whereArr(array $where): array
'<>', '!=' => 'NOT IN',
default => $operator ?: 'IN',
};
} elseif (is_string($value) && 'SELECT' === strtoupper(substr($value, 0, 6))) {
} elseif ($isSqlValue && is_string($value) && preg_match('/^SELECT\s/i', $value)) {
// 包含子查询
$operator || $operator = 'IN';
$sql && $sql .= " {$logic}";
Expand Down Expand Up @@ -1041,14 +1044,13 @@ protected function DB_checkKey(string $key): array
$isSqlValue = false;
$operator = '';
$logic = '';
$preg = '/^(OR\s+|AND\s+)?([\|\:\w.]+)\s*([\<\>\=\!]{0,2}|\s+(NOT\s+)?(IN|LIKE\s+|BETWEEN\s+))$/i';
$preg = '/^(OR\s+|AND\s+)?([\|\:\w.]+)\s*([\<\>\=\!]{0,2}|\s+(NOT\s+)?(IN|LIKE|BETWEEN))$/i';
if (preg_match($preg, $key, $match)) {
$logic = empty($match[1]) ? '' : $match[1];
$keys = $match[2];
$operator = $match[3] ?? '=';
if (1 < count($keys = explode('|', $match[2]))) {
$operator = empty($match[3]) ? '=' : trim($match[3]);
if (str_contains($keys, '|') && $keys = explode('|', $keys)) {
':' === $keys[0][0] && ($isSqlValue = true) && $keys[0] = substr($keys[0], 1);
$keys = $this->Wrap($keys);
} else {
$keys = $match[2];
':' === $keys[0] && ($isSqlValue = true) && $keys = substr($keys, 1);
Expand All @@ -1057,7 +1059,6 @@ protected function DB_checkKey(string $key): array
$keys = $this->WrapSql($key);
':' === $keys[0] && ($isSqlValue = true) && $keys = substr($keys, 1);
}

return [$isSqlValue, $logic, $keys, $operator];
}
}
30 changes: 16 additions & 14 deletions nec/z/view.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
class view
{
const
ENCODE_PREFIX = 'z-php-encode.', ENCODE_END_CHAR = '.',
OPTIONS = LIBXML_NSCLEAN + LIBXML_PARSEHUGE + LIBXML_NOBLANKS + LIBXML_NOERROR + LIBXML_HTML_NODEFDTD + LIBXML_ERR_FATAL + LIBXML_COMPACT;
ENCODE_PREFIX = '!z-php-encode.', ENCODE_END_CHAR = '.!',
OPTIONS = LIBXML_NSCLEAN + LIBXML_PARSEHUGE + LIBXML_NOBLANKS + LIBXML_NOERROR + LIBXML_HTML_NODEFDTD + LIBXML_ERR_FATAL + LIBXML_COMPACT + LIBXML_NOXMLDECL;
private static \DOMDocument|null $DOM = null;
private static array $TAG = [], $TPLDOM = [], $PARAMS = [], $REPLACE = [], $PREG_FIX = [], $CACHE = [];
private static array $TAG = [], $TPLDOM = [], $PARAMS = [], $REPLACE = [], $CACHE = [];
private static string $PRE = '', $SUF = '', $PREG_CODE = '';
private static int $CHANGED = 0;

Expand All @@ -29,21 +29,25 @@ public static function setup(): void {
}
private static function replaceEncode(string $html): string
{
$preg = '/\<\w+\s+[^>]*'.self::$PREG_CODE.'[^<]+\>/';
$pregCode = '/'.self::$PREG_CODE.'/U';
$html = preg_replace_callback($preg, function (array $match) use($pregCode): string {
return preg_replace_callback($pregCode, function (array $m2) {
$code = trim($m2[1]);
$i = array_push(self::$REPLACE, "<?php echo {$code};?>") - 1;
return self::ENCODE_PREFIX . $i . self::ENCODE_END_CHAR;
}, $match[0]);
$html = preg_replace_callback($pregCode, function (array $m) {
$code = trim($m[1]);
$i = array_push(self::$REPLACE, "<?php echo {$code};?>") - 1;
return self::ENCODE_PREFIX . $i . self::ENCODE_END_CHAR;
}, $html);

$pregPHP = '/\<\?php((?<!\?\>)[\s\S]+)\?\>/U';
$html = preg_replace_callback($pregPHP, function (array $m) {
$i = array_push(self::$REPLACE, $m[0]) - 1;
return self::ENCODE_PREFIX . $i . self::ENCODE_END_CHAR;
}, $html);

$pregSymbol = '/(\s+[@#&$]+\w+)\s*(?==\s*["\'])/';
$html = preg_replace_callback($pregSymbol, function (array $m) {
$i = array_push(self::$REPLACE, $m[1]) - 1;
return self::ENCODE_PREFIX . $i . self::ENCODE_END_CHAR;
}, $html);
return preg_replace(self::$PREG_FIX, ['<?php echo ', ';?>'], $html);
return $html;
}
private static function replaceDecode(string $html): string
{
Expand Down Expand Up @@ -107,7 +111,6 @@ private static function getBlock(string $file): \DOMDocument
$time = filemtime($file);
$time > self::$CHANGED && self::$CHANGED = $time;
$html = self::replaceEncode(file_get_contents($file));
// $html = '<?xml encoding="UTF-8">' . (str_contains($html, '<' . self::$TAG['template']) ? $html : '<' . self::$TAG['template'] . '>' . $html . '</' . self::$TAG['template'] . '>');
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->loadHTML('<?xml encoding="UTF-8">' . $html, self::OPTIONS);
DEBUGER && 2 < $GLOBALS['ZPHP_CONFIG']['DEBUG']['level'] && (DEBUGER)::setMsg(1140, $file);
Expand All @@ -121,7 +124,7 @@ private static function getBlock(string $file): \DOMDocument
$params = explode(',', $params);
foreach($params as $v) {
$p = explode(':', $v);
$d[$p[0]] = $p[1] ?? null;
$d[$p[0]] = $p[1] ?? true;
}
self::$TPLDOM[$file][$name][1] = $d;
} else {
Expand Down Expand Up @@ -264,7 +267,6 @@ public static function Compile(string $tpl, string $run_file, int $run_time): vo
$pregPre = preg_quote(self::$PRE);
$pregSuf = preg_quote(self::$SUF);
self::$PREG_CODE = "{$pregPre}([\s\S]+){$pregSuf}";
self::$PREG_FIX = ["/\s*{$pregPre}\s*/", "/\s*{$pregSuf}\s*/"];

$flag = '<meta flag="ZPHP-UTF-8" http-equiv="Content-Type" content="text/html; charset=utf-8">';
$html = self::replaceEncode(file_get_contents($tpl));
Expand Down

0 comments on commit 171ab6d

Please sign in to comment.