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; }