4in1_ws_web/lib/sphinx.php

109 lines
3.2 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
class sphinx {
public static function execute(string $sql) {
$link = self::getLink();
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 = self::normalize($arg);
$v = '\''.$link->real_escape_string($arg).'\'';
$sql = substr_replace($sql, $v, $positions[$i], 1);
}
}
$q = $link->query($sql);
$error = self::getError();
if ($error)
logError(__FUNCTION__, $error);
return $q;
}
public static function getError() {
$link = self::getLink(auto_create: false);
return $link?->error;
}
public static function 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 = self::normalize($q);
$q = trim($q);
$q = self::getClient()->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;
}
public static function getClient(): Sphinx\SphinxClient {
static $cl = null;
if (!is_null($cl))
return $cl;
return $cl = new Sphinx\SphinxClient;
}
protected static function normalize(string $origstr): string {
$buf = preg_replace('/[Ёё]/iu', 'е', $origstr);
if (!pcreNoError($buf, no_error: true)) {
$origstr = mb_convert_encoding($origstr, 'UTF-8', 'UTF-8');
$buf = preg_replace('/[Ёё]/iu', 'е', $origstr);
pcreNoError($buf);
}
if ($buf === null) {
logError(__METHOD__.': preg_replace() failed with error: '.preg_last_error().': '.preg_last_error_msg());
$buf = $origstr;
}
return preg_replace('/[!\?]/', '', $buf);
}
protected static function getLink($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;
}
}