本文目录导读:

我来详细讲解PHP项目中如何基于接口实现语义分析功能。
语义分析接口设计原则
核心接口定义
<?php
// 语义分析基础接口
interface SemanticAnalyzerInterface {
public function analyze(string $text): AnalysisResult;
public function analyzeBatch(array $texts): array;
public function getSupportedLanguages(): array;
}
// 分析结果对象
class AnalysisResult {
private string $text;
private string $language;
private float $sentiment;
private array $entities;
private array $keywords;
private string $summary;
public function __construct(
string $text,
string $language,
float $sentiment,
array $entities,
array $keywords,
string $summary = ''
) {
$this->text = $text;
$this->language = $language;
$this->sentiment = $sentiment;
$this->entities = $entities;
$this->keywords = $keywords;
$this->summary = $summary;
}
}
// NLP服务适配器接口
interface NLPServiceAdapterInterface {
public function sentimentAnalysis(string $text): array;
public function entityRecognition(string $text): array;
public function keywordExtraction(string $text): array;
public function textSummarization(string $text): string;
}
主流云服务接口实现
1 百度AI接口实现
<?php
class BaiduNLPService implements NLPServiceAdapterInterface {
private $client;
private $config;
public function __construct(array $config) {
$this->config = $config;
$this->initializeClient();
}
private function initializeClient() {
$this->client = new BaiduAipNlp(
$this->config['app_id'],
$this->config['api_key'],
$this->config['secret_key']
);
}
public function sentimentAnalysis(string $text): array {
try {
$result = $this->client->sentimentClassify($text);
return [
'sentiment' => $result['items'][0]['sentiment'],
'confidence' => $result['items'][0]['confidence'],
'positive_prob' => $result['items'][0]['positive_prob'],
'negative_prob' => $result['items'][0]['negative_prob']
];
} catch (Exception $e) {
throw new SemanticAnalysisException("情感分析失败: " . $e->getMessage());
}
}
public function entityRecognition(string $text): array {
$result = $this->client->lexer($text);
return array_map(function($item) {
return [
'word' => $item['item'],
'type' => $item['pos'],
'offset' => $item['byte_offset']
];
}, $result['items']);
}
public function keywordExtraction(string $text): array {
$result = $this->client->keyword($text);
return array_map(function($item) {
return [
'keyword' => $item['word'],
'weight' => $item['weight']
];
}, $result['items']);
}
public function textSummarization(string $text): string {
// 百度AI摘要接口处理
$result = $this->client->newsSummary($text, 200);
return $result['summary'] ?? '';
}
}
2 OpenAI API实现
<?php
class OpenAISemanticService implements NLPServiceAdapterInterface {
private $httpClient;
private $apiKey;
public function __construct(string $apiKey) {
$this->apiKey = $apiKey;
$this->httpClient = new GuzzleHttp\Client([
'base_uri' => 'https://api.openai.com/v1/',
'headers' => [
'Authorization' => 'Bearer ' . $apiKey,
'Content-Type' => 'application/json'
]
]);
}
public function sentimentAnalysis(string $text): array {
$response = $this->httpClient->post('completions', [
'json' => [
'model' => 'text-davinci-003',
'prompt' => "Analyze the sentiment of this text: \"{$text}\"\nSentiment:",
'max_tokens' => 50
]
]);
$result = json_decode($response->getBody(), true);
return $this->parseSentimentResponse($result['choices'][0]['text']);
}
public function entityRecognition(string $text): array {
// OpenAI 实体识别实现
$response = $this->httpClient->post('completions', [
'json' => [
'model' => 'text-davinci-003',
'prompt' => "Extract entities from: \"{$text}\"\nEntities:",
'max_tokens' => 200
]
]);
return $this->parseEntitiesResponse($response);
}
private function parseSentimentResponse(string $response): array {
$sentiment = trim($response);
$score = 0;
switch (strtolower($sentiment)) {
case 'positive':
$score = 0.8;
break;
case 'negative':
$score = 0.2;
break;
default:
$score = 0.5;
}
return [
'sentiment' => $score,
'label' => $sentiment,
'confidence' => 0.9
];
}
}
统一语义分析器实现
<?php
class UnifiedSemanticAnalyzer implements SemanticAnalyzerInterface {
private array $adapters;
private string $defaultAdapter;
private array $cache;
public function __construct(array $adapters, string $defaultAdapter = 'baidu') {
$this->adapters = $adapters;
$this->defaultAdapter = $defaultAdapter;
$this->cache = [];
}
public function analyze(string $text): AnalysisResult {
// 检查缓存
$cacheKey = md5($text);
if (isset($this->cache[$cacheKey])) {
return $this->cache[$cacheKey];
}
$adapter = $this->getAdapter($this->defaultAdapter);
try {
// 并行执行多个分析任务
$promises = [
'sentiment' => $adapter->sentimentAnalysis($text),
'entities' => $adapter->entityRecognition($text),
'keywords' => $adapter->keywordExtraction($text),
'summary' => $adapter->textSummarization($text)
];
// 等待所有结果
$results = \GuzzleHttp\Promise\Utils::all($promises)->wait();
$analysisResult = new AnalysisResult(
$text,
$this->detectLanguage($text),
$results['sentiment']['sentiment'] ?? 0.5,
$results['entities'] ?? [],
$results['keywords'] ?? [],
$results['summary'] ?? ''
);
// 缓存结果
$this->cache[$cacheKey] = $analysisResult;
return $analysisResult;
} catch (Exception $e) {
throw new SemanticAnalysisException("语义分析失败: " . $e->getMessage());
}
}
public function analyzeBatch(array $texts): array {
$results = [];
$batchSize = 10; // 批处理大小
foreach (array_chunk($texts, $batchSize) as $chunk) {
$promises = [];
foreach ($chunk as $text) {
$promises[] = \GuzzleHttp\Promise\Utils::all([
$this->analyzeAsync($text)
]);
}
$batchResults = \GuzzleHttp\Promise\Utils::all($promises)->wait();
$results = array_merge($results, $batchResults);
}
return $results;
}
private function analyzeAsync(string $text): \GuzzleHttp\Promise\PromiseInterface {
return \GuzzleHttp\Promise\FulfilledPromise::create($this->analyze($text));
}
private function getAdapter(string $name): NLPServiceAdapterInterface {
if (!isset($this->adapters[$name])) {
throw new \InvalidArgumentException("未找到适配器: {$name}");
}
return $this->adapters[$name];
}
private function detectLanguage(string $text): string {
// 简单语言检测
if (preg_match('/[\x{4e00}-\x{9fa5}]/u', $text)) {
return 'zh';
}
return 'en';
}
public function getSupportedLanguages(): array {
return ['zh', 'en', 'jp', 'ko'];
}
}
高级功能实现
1 智能路由和故障转移
<?php
class SmartRouterSemanticAnalyzer implements SemanticAnalyzerInterface {
private array $adapters = [];
private array $failover = [];
public function analyze(string $text): AnalysisResult {
$errors = [];
foreach ($this->adapters as $name => $adapter) {
try {
return $adapter->analyze($text);
} catch (Exception $e) {
$errors[$name] = $e->getMessage();
// 尝试故障转移适配器
if (isset($this->failover[$name])) {
return $this->failover[$name]->analyze($text);
}
}
}
throw new SemanticAnalysisException(
"所有适配器分析失败: " . json_encode($errors)
);
}
}
2 缓存和性能优化
<?php
class CachedSemanticAnalyzer implements SemanticAnalyzerInterface {
private SemanticAnalyzerInterface $analyzer;
private CacheInterface $cache;
private int $ttl = 3600; // 缓存1小时
public function analyze(string $text): AnalysisResult {
$cacheKey = 'semantic_' . md5($text);
// 尝试从缓存获取
$cached = $this->cache->get($cacheKey);
if ($cached) {
return $cached;
}
// 执行分析
$result = $this->analyzer->analyze($text);
// 写入缓存
$this->cache->set($cacheKey, $result, $this->ttl);
return $result;
}
}
使用示例
<?php
// 配置文件
$config = [
'baidu' => [
'app_id' => 'your_app_id',
'api_key' => 'your_api_key',
'secret_key' => 'your_secret_key'
],
'openai' => [
'api_key' => 'your_openai_key'
]
];
// 初始化适配器
$adapters = [
'baidu' => new BaiduNLPService($config['baidu']),
'openai' => new OpenAISemanticService($config['openai']['api_key'])
];
// 创建统一分析器
$analyzer = new UnifiedSemanticAnalyzer($adapters, 'baidu');
// 使用缓存包装
$cachedAnalyzer = new CachedSemanticAnalyzer(
$analyzer,
new RedisCache()
);
// 执行分析
try {
$text = "今天天气真好,心情非常愉悦!";
$result = $cachedAnalyzer->analyze($text);
echo "情感评分: " . $result->getSentiment() . "\n";
echo "关键词: " . implode(', ', $result->getKeywords()) . "\n";
} catch (SemanticAnalysisException $e) {
echo "分析失败: " . $e->getMessage() . "\n";
}
// 批量分析
$texts = [
"这个产品很棒!",
"服务态度很差",
"性价比一般"
];
$results = $analyzer->analyzeBatch($texts);
最佳实践建议
- 接口隔离原则:每个服务适配器只实现必要接口
- 错误处理:实现完善的异常处理和降级策略
- 缓存策略:对常见文本进行缓存,减少API调用
- 并发处理:使用异步请求处理多个文本分析
- 监控和日志:记录API调用次数和性能指标
- 配置管理:API密钥等敏感信息使用环境变量
这种基于接口的设计可以实现服务解耦、易于扩展和维护,同时支持多种NLP服务提供商的切换。