本文目录导读:

我来详细介绍PHP项目对接AI识别接口的完整方案。
常见AI识别接口类型
主流AI接口提供商
- 百度AI:图像识别、文字识别、人脸识别
- 腾讯AI:智能图像、OCR、语音识别
- 阿里云视觉智能:图像分析、文字识别
- 华为云ModelArts:通用AI识别
- OpenAI:GPT视觉识别
基础对接代码示例
通用API请求类
<?php
class AIClient {
private $apiKey;
private $secretKey;
private $baseUrl;
public function __construct($apiKey, $secretKey, $baseUrl) {
$this->apiKey = $apiKey;
$this->secretKey = $secretKey;
$this->baseUrl = $baseUrl;
}
/**
* 发送POST请求
*/
public function postRequest($endpoint, $data, $headers = []) {
$url = $this->baseUrl . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// 设置请求头
$defaultHeaders = [
'Content-Type: application/json',
'Accept: application/json'
];
if (!empty($headers)) {
$defaultHeaders = array_merge($defaultHeaders, $headers);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $defaultHeaders);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API请求失败,HTTP状态码: " . $httpCode);
}
return json_decode($response, true);
}
/**
* 发送GET请求
*/
public function getRequest($endpoint, $params = []) {
$url = $this->baseUrl . $endpoint;
if (!empty($params)) {
$url .= '?' . http_build_query($params);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
对接百度AI图像识别
获取Access Token
<?php
class BaiduAIClient {
private $appId;
private $apiKey;
private $secretKey;
private $accessToken;
private $expireTime;
public function __construct($appId, $apiKey, $secretKey) {
$this->appId = $appId;
$this->apiKey = $apiKey;
$this->secretKey = $secretKey;
$this->getAccessToken();
}
/**
* 获取百度AI access_token
*/
private function getAccessToken() {
// 检查缓存
$cacheFile = __DIR__ . '/baidu_token_cache.json';
if (file_exists($cacheFile)) {
$cache = json_decode(file_get_contents($cacheFile), true);
if ($cache['expire_time'] > time()) {
$this->accessToken = $cache['access_token'];
return;
}
}
$url = "https://aip.baidubce.com/oauth/2.0/token";
$params = [
'grant_type' => 'client_credentials',
'client_id' => $this->apiKey,
'client_secret' => $this->secretKey
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if (isset($data['access_token'])) {
$this->accessToken = $data['access_token'];
// 缓存token(提前5分钟过期)
$cache = [
'access_token' => $data['access_token'],
'expire_time' => time() + $data['expires_in'] - 300
];
file_put_contents($cacheFile, json_encode($cache));
} else {
throw new Exception("获取百度AI Token失败: " . $data['error_description']);
}
}
/**
* 图像识别(通用物体识别)
*/
public function imageRecognition($imagePath) {
$url = "https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general";
$url .= "?access_token=" . $this->accessToken;
// 读取图片并base64编码
$image = file_get_contents($imagePath);
$base64Image = base64_encode($image);
$data = [
'image' => $base64Image,
'baike_num' => 5 // 返回百科词条数量
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
/**
* 通用文字识别
*/
public function textRecognition($imagePath) {
$url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic";
$url .= "?access_token=" . $this->accessToken;
$image = file_get_contents($imagePath);
$base64Image = base64_encode($image);
$data = [
'image' => $base64Image,
'detect_direction' => true
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
/**
* 人脸检测
*/
public function faceDetection($imagePath) {
$url = "https://aip.baidubce.com/rest/2.0/face/v3/detect";
$url .= "?access_token=" . $this->accessToken;
$image = file_get_contents($imagePath);
$base64Image = base64_encode($image);
$data = [
'image' => $base64Image,
'image_type' => 'BASE64',
'face_field' => 'age,gender,expression,emotion'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
批量图片识别处理
<?php
class BatchImageRecognizer {
private $baiduAI;
public function __construct($baiduAI) {
$this->baiduAI = $baiduAI;
}
/**
* 批量处理图片
*/
public function batchRecognize($imageDirectory, $callback = null) {
$results = [];
$files = glob($imageDirectory . '/*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($files as $index => $imagePath) {
try {
$result = $this->baiduAI->imageRecognition($imagePath);
$results[] = [
'filename' => basename($imagePath),
'status' => 'success',
'data' => $result
];
// 回调处理
if ($callback) {
call_user_func($callback, $index + 1, count($files), $imagePath, $result);
}
// 防止请求过快
usleep(500000); // 0.5秒延迟
} catch (Exception $e) {
$results[] = [
'filename' => basename($imagePath),
'status' => 'error',
'message' => $e->getMessage()
];
}
}
return $results;
}
}
对接OpenAI视觉API
<?php
class OpenAIVisionClient {
private $apiKey;
private $baseUrl = 'https://api.openai.com/v1';
public function __construct($apiKey) {
$this->apiKey = $apiKey;
}
/**
* 图片分析(GPT-4V)
*/
public function analyzeImage($imagePath, $question = "请描述这张图片") {
// 读取图片并转换为base64
$imageData = file_get_contents($imagePath);
$base64Image = base64_encode($imageData);
// 获取图片MIME类型
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $imagePath);
finfo_close($finfo);
$data = [
'model' => 'gpt-4o',
'messages' => [
[
'role' => 'user',
'content' => [
[
'type' => 'text',
'text' => $question
],
[
'type' => 'image_url',
'image_url' => [
'url' => "data:{$mimeType};base64,{$base64Image}"
]
]
]
]
],
'max_tokens' => 500
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->baseUrl . '/chat/completions');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $this->apiKey
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$result = json_decode($response, true);
return $result['choices'][0]['message']['content'];
} else {
throw new Exception("OpenAI API错误: " . $response);
}
}
}
图片预处理优化
<?php
class ImagePreprocessor {
/**
* 压缩图片到指定大小
*/
public static function compressImage($sourcePath, $targetPath, $maxWidth = 1024, $quality = 80) {
list($width, $height, $type) = getimagesize($sourcePath);
// 如果图片宽度大于最大宽度,进行缩放
if ($width > $maxWidth) {
$ratio = $maxWidth / $width;
$newWidth = $maxWidth;
$newHeight = $height * $ratio;
} else {
$newWidth = $width;
$newHeight = $height;
}
// 创建新图片
$thumb = imagecreatetruecolor($newWidth, $newHeight);
switch ($type) {
case IMAGETYPE_JPEG:
$source = imagecreatefromjpeg($sourcePath);
break;
case IMAGETYPE_PNG:
$source = imagecreatefrompng($sourcePath);
// 保持PNG透明
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
break;
case IMAGETYPE_GIF:
$source = imagecreatefromgif($sourcePath);
break;
default:
throw new Exception("不支持的图片格式");
}
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
// 保存压缩后的图片
switch ($type) {
case IMAGETYPE_JPEG:
imagejpeg($thumb, $targetPath, $quality);
break;
case IMAGETYPE_PNG:
imagepng($thumb, $targetPath, 9);
break;
case IMAGETYPE_GIF:
imagegif($thumb, $targetPath);
break;
}
imagedestroy($source);
imagedestroy($thumb);
return true;
}
/**
* 自动旋转图片(根据EXIF信息)
*/
public static function autoRotate($imagePath) {
$exif = @exif_read_data($imagePath);
if ($exif && isset($exif['Orientation'])) {
$orientation = $exif['Orientation'];
$image = imagecreatefromjpeg($imagePath);
switch ($orientation) {
case 3:
$image = imagerotate($image, 180, 0);
break;
case 6:
$image = imagerotate($image, -90, 0);
break;
case 8:
$image = imagerotate($image, 90, 0);
break;
}
imagejpeg($image, $imagePath, 100);
imagedestroy($image);
}
}
}
完整使用示例
<?php
// 自动加载
require_once 'AIClient.php';
require_once 'BaiduAIClient.php';
require_once 'ImagePreprocessor.php';
// 配置信息
$config = [
'baidu' => [
'app_id' => 'your_app_id',
'api_key' => 'your_api_key',
'secret_key' => 'your_secret_key'
]
];
// 初始化客户端
$baiduAI = new BaiduAIClient(
$config['baidu']['app_id'],
$config['baidu']['api_key'],
$config['baidu']['secret_key']
);
try {
// 1. 预处理图片
$sourceImage = 'uploads/photo.jpg';
$processedImage = 'uploads/processed_photo.jpg';
// 压缩图片
ImagePreprocessor::compressImage($sourceImage, $processedImage, 800, 85);
// 自动旋转
ImagePreprocessor::autoRotate($processedImage);
// 2. 进行图像识别
$result = $baiduAI->imageRecognition($processedImage);
// 3. 处理结果
if ($result['error_code'] === 0) {
echo "识别结果:\n";
foreach ($result['result'] as $item) {
echo "{$item['keyword']} (置信度: {$item['score']})\n";
// 如果有百科信息
if (isset($item['baike_info'])) {
echo "百科描述: {$item['baike_info']['description']}\n";
}
}
} else {
echo "识别失败: " . $result['error_msg'];
}
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
错误处理与日志
<?php
class AIApiLogger {
private $logFile;
public function __construct($logFile = 'ai_api.log') {
$this->logFile = $logFile;
}
public function log($message, $level = 'INFO') {
$timestamp = date('Y-m-d H:i:s');
$logMessage = "[{$timestamp}] [{$level}] {$message}\n";
file_put_contents($this->logFile, $logMessage, FILE_APPEND | LOCK_EX);
}
public function logApiCall($endpoint, $request, $response, $status) {
$this->log("API Call: {$endpoint}", 'INFO');
$this->log("Request: " . json_encode($request), 'DEBUG');
$this->log("Response Status: {$status}", 'INFO');
if ($status !== 200) {
$this->log("Response Error: " . json_encode($response), 'ERROR');
}
}
}
性能优化建议
缓存策略
<?php
class RedisCache {
private $redis;
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function getCachedResult($imageHash) {
$key = "ai_recognition:{$imageHash}";
$cached = $this->redis->get($key);
return $cached ? json_decode($cached, true) : null;
}
public function cacheResult($imageHash, $result, $ttl = 86400) {
$key = "ai_recognition:{$imageHash}";
$this->redis->setex($key, $ttl, json_encode($result));
}
public function getImageHash($imagePath) {
return md5_file($imagePath);
}
}
队列处理
<?php
// 使用Redis队列处理大批量任务
class AIQueueProcessor {
private $redis;
private $queueName = 'ai_recognition_queue';
public function addTask($imagePath) {
$task = [
'id' => uniqid(),
'image_path' => $imagePath,
'created_at' => time()
];
$this->redis->lPush($this->queueName, json_encode($task));
}
public function processQueue() {
while ($task = $this->redis->rPop($this->queueName)) {
$taskData = json_decode($task, true);
try {
// 处理任务
$result = $this->processImage($taskData['image_path']);
// 保存结果
$this->saveResult($taskData['id'], $result);
} catch (Exception $e) {
$this->handleError($taskData, $e);
}
}
}
}
注意事项
- API配额管理:注意各平台的调用次数限制
- 并发控制:避免短时间内大量请求
- 数据安全:敏感图片进行脱敏处理
- 异常处理:完善的错误处理机制
- 日志记录:记录API调用日志便于问题排查
- 图片格式:统一处理为支持的格式
- 网络超时:设置合理的超时时间(建议30秒以上)
这个方案涵盖了主流AI接口的对接方式、图片处理、性能优化和错误处理,可以根据实际需求选择使用。