[ 'timeout' => 15, 'user_agent' => 'Mozilla/5.0', ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($fileUrl, false, $ctx); if ($raw === false || strlen($raw) < 10) { return ''; } if ($ext === 'docx') { return self::extractDocxText($raw); } if ($ext === 'pdf') { return self::extractPdfText($raw); } return ''; } private static function extractDocxText(string $raw): string { $tmp = tempnam(sys_get_temp_dir(), 'docx_'); if ($tmp === false) { return ''; } if (file_put_contents($tmp, $raw) === false) { @unlink($tmp); return ''; } $zip = new \ZipArchive(); if ($zip->open($tmp) !== true) { @unlink($tmp); return ''; } $xml = $zip->getFromName('word/document.xml'); $zip->close(); @unlink($tmp); if ($xml === false || $xml === '') { return ''; } preg_match_all('/]*>([^<]*)<\/w:t>/u', $xml, $m); $text = isset($m[1]) ? implode('', $m[1]) : ''; $text = html_entity_decode($text, ENT_QUOTES | ENT_XML1, 'UTF-8'); $text = preg_replace('/[^\x{4e00}-\x{9fff}\x{3000}-\x{303f}a-zA-Z0-9\s\.,;:!?()()【】\[\]\/\-_@]/u', ' ', $text); return trim(preg_replace('/\s{2,}/', ' ', $text)); } private static function extractPdfText(string $raw): string { $text = ''; if (preg_match_all('/BT\s+(.*?)\s+ET/s', $raw, $blocks)) { foreach ($blocks[1] as $block) { if (preg_match_all('/\(([^)]*)\)\s*Tj/s', $block, $tj)) { $text .= implode(' ', $tj[1]) . ' '; } if (preg_match_all('/\[(.*?)]\s*TJ/s', $block, $tjArr)) { foreach ($tjArr[1] as $inner) { if (preg_match_all('/\(([^)]*)\)/s', $inner, $parts)) { $text .= implode('', $parts[1]) . ' '; } } } } } $text = preg_replace('/[^\x{4e00}-\x{9fff}\x{3000}-\x{303f}a-zA-Z0-9\s\.,;:!?()()【】\[\]\/\-_@]/u', ' ', $text); return trim(preg_replace('/\s{2,}/', ' ', $text)); } }