preprocessString($string); return $this->determineConversionStrategy($string); } private function determineConversionStrategy(string $string): Collection { // 多音字处理 if ($this->heteronym) { return $this->convertAsChars($string, true); } // 仅字符转换 if ($this->noWords) { return $this->convertAsChars($string); } // 替换姓氏 if ($this->asSurname) { $string = $this->convertSurname($string); } // 智能加载词典 $string = $this->smartConvert($string); return $this->split($string); } private function smartConvert(string $string): string { // 使用和CachedConverter相同的逻辑,但保持缓存机制 $dictionary = $this->getFullDictionary(); return strtr($string, $dictionary); } private function getFullDictionary(): array { if (self::$fullDictionary === null) { self::$fullDictionary = []; // 按顺序加载,保证长词优先 foreach ($this->wordSegmentPaths() as $path) { self::$fullDictionary += $this->loadSegmentWithCache($path); } } return self::$fullDictionary; } private function loadSegmentWithCache(string $path): array { if (! isset(self::$segmentCache[$path])) { // 缓存数量限制 if (count(self::$segmentCache) >= self::MAX_CACHE_SEGMENTS) { // 移除最早的缓存(简单的 FIFO) $firstKey = array_key_first(self::$segmentCache); if ($firstKey !== null) { unset(self::$segmentCache[$firstKey]); } } self::$segmentCache[$path] = require $path; } return self::$segmentCache[$path]; } protected function convertAsChars(string $string, bool $polyphonic = false): Collection { // 字符表太大,不缓存 $map = require self::CHARS_PATH; $chars = mb_str_split($string); $items = []; foreach ($chars as $char) { if (isset($map[$char])) { if ($polyphonic) { $pinyin = array_map(fn ($pinyin) => $this->formatTone($pinyin, $this->toneStyle->value), $map[$char]); if ($this->heteronymAsList) { $items[] = [$char => $pinyin]; } else { $items[$char] = $pinyin; } } else { $items[$char] = $this->formatTone($map[$char][0], $this->toneStyle->value); } } } return new Collection($items); } protected function convertSurname(string $name): string { // 姓氏表很小,可以缓存 self::$surnamesCache ??= require self::SURNAMES_PATH; foreach (self::$surnamesCache as $surname => $pinyin) { if (str_starts_with($name, $surname)) { return $pinyin.mb_substr($name, mb_strlen($surname)); } } return $name; } /** * 清理缓存 */ public static function clearCache(): void { self::$surnamesCache = null; self::$segmentCache = []; self::$fullDictionary = null; } }