4in1_ws_web/engine/sphinx.php

105 lines
2.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
function sphinx_execute(string $sql) {
$link = _sphinxql_link();
if (func_num_args() > 1) {
$mark_count = substr_count($sql, '?');
$positions = array();
$last_pos = -1;
for ($i = 0; $i < $mark_count; $i++) {
$last_pos = strpos($sql, '?', $last_pos + 1);
$positions[] = $last_pos;
}
for ($i = $mark_count - 1; $i >= 0; $i--) {
$arg = func_get_arg($i + 1);
if (is_string($arg))
$arg = _sphinx_normalize($arg);
$v = '\''.$link->real_escape_string($arg).'\'';
$sql = substr_replace($sql, $v, $positions[$i], 1);
}
}
$q = $link->query($sql);
$error = sphinx_error();
if ($error)
logError(__FUNCTION__, $error);
return $q;
}
function sphinx_error() {
$link = _sphinxql_link(auto_create: false);
return $link?->error;
}
function sphinx_mkquery($q, array $opts = []) {
$defaults = [
'any_word' => false,
'star' => false,
'and' => false,
'exact_first' => false
];
$opts = array_merge($defaults, $opts);
$q = preg_replace('/\s+/', ' ', $q);
$q = _sphinx_normalize($q);
$q = trim($q);
$q = sphinx_client()->escapeString($q);
if ($opts['star']) {
$words = explode(' ', $q);
$words = array_map(fn($word) => $word.'*', $words);
$q = implode(' ', $words);
}
if ($opts['any_word']) {
$q = str_replace(' ', ' | ', $q);
} else if ($opts['and']) {
$q = str_replace(' ', ' AND ', $q);
}
if ($opts['exact_first']) {
$q = '"^'.$q.'$" | "'.$q.'" | ('.$q.')';
}
return $q;
}
function sphinx_client(): Sphinx\SphinxClient {
static $cl = null;
if (!is_null($cl))
return $cl;
return $cl = new Sphinx\SphinxClient;
}
function _sphinx_normalize(string $origstr): string {
$buf = preg_replace('/[Ёё]/iu', 'е', $origstr);
if (!pcre_check_error($buf, no_error: true)) {
$origstr = mb_convert_encoding($origstr, 'UTF-8', 'UTF-8');
$buf = preg_replace('/[Ёё]/iu', 'е', $origstr);
pcre_check_error($buf);
}
if ($buf === null) {
logError(__METHOD__.': preg_replace() failed with error: '.preg_last_error().': '.preg_last_error_msg());
$buf = $origstr;
}
return preg_replace('/[!\?]/', '', $buf);
}
function _sphinxql_link($auto_create = true) {
global $config;
/** @var ?mysqli $link */
static $link = null;
if (!is_null($link) || !$auto_create)
return $link;
$link = new mysqli();
$link->real_connect(
$config['sphinx']['host'],
ini_get('mysql.default_user'),
ini_get('mysql.default_password'),
null,
9306);
$link->set_charset('utf8');
return $link;
}