博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【应用】PHP调用百度文档翻译接口
阅读量:145 次
发布时间:2019-02-28

本文共 12511 字,大约阅读时间需要 41 分钟。

的文档是需要消费的,并且它的api请求是一个异步的过程,如果业务上用户不需要登录的时候,无法直接获取到翻译结果文档。因此,做了个异步返回的功能。

思路:

1、上传文档;

2、调用翻译接口;

3、通过kafka监听接口回调,处理返回数据,保存到本地(方便以后扩展,如加入用户信息,查看我的翻译记录)

4、前端监听后端服务,通过swoole的websocket实时请求文档数据

关键部分代码(赶工做的,未做优化):

//上传文件public function upload(){	header("Access-Control-Allow-Origin:*");  	set_time_limit(300);	$file = $_FILES['file'];	if(!$file){        $show = array('status'=>422,'message'=>'请上传图片或者文档文件');        json($show);	}	$app = '2020bd';	if($_SERVER['SERVER_ADDR']=='127.0.0.1'){	    $sPath = '/Users/kunyuan/www/activity/storage/'.$app.'/';	}else{	    $sPath = '/var/www/html/activity/storage/'.$app.'/';	}	if(!mk_dir($sPath)){	    $show = array('status'=>500,'message'=>'目录不存在');    	json($show);	}    $path_parts = pathinfo($file['name']);    $ext = strtolower($path_parts["extension"]);    $extAry = array(    	'jpg','jpeg','png','docx','xls','xlsx','ppt','pptx','pdf'    );    if(!in_array($ext, $extAry)){        $show = array('status'=>422,'message'=>'请上传图片或者文档文件');        json($show);    }    try{    	//保存到服务器本地    	$filename = date('Ymd'). '_' .rand(10000, 99999).'_'.time();	    $tmpfile = $filename . '.'.$ext;	    $tmp = $file["tmp_name"];	    $img = file_get_contents($tmp);	    $path1 = $sPath . $tmpfile;	    $res = file_put_contents($path1, $img);	    if(is_https()){	    	$url = 'https://'.$_SERVER['SERVER_NAME'].'/storage/'.$app.'/'.$tmpfile;	    }else{	    	$url = 'http://'.$_SERVER['SERVER_NAME'].'/storage/'.$app.'/'.$tmpfile;	    }	    	    $error = '上传失败';	    if($res){	    	//判断文件类型,为了文件调用百度的图片接口或者文档接口	    	if(in_array($ext,array('jpg','jpeg','png'))){	    		$resExt = 'pic';	    	}else{	    		$resExt = 'docs';	    	}	    	//保存数据库	    	$fileid = $this->common->setFiles(array(	    		'sourceFile'	=> $url,	    		'localFile'		=> $path1,	    		'type'	=> $resExt	    	));			$show = array('status'=>0,'fileUrl'=>$url,'fileSize'=>ceil(filesize($path1)/1000)."k",'ext'=>$resExt, 'id' => $fileid,'resExt'=>$resExt);	    }else{	    	$show = array('status'=>500,'message'=>$error,'info'=>$info,'fileSize'=>ceil(filesize($path1)/1000)."k");	    }	    json($show);    }catch(Exception $e){        $show = array('status'=>$e->getCode(),'message'=>$e->getMessage());        json($show);    }}
//调用百度接口public function api(){	//$type = I('type','docs');	$id = I('id',0);	$callback = I('callback');	//判断是否为上传的文件	$data = $this->common->getFiles(array('id'=>$id));	if(empty($data)){        $show = array('status'=>420,'message'=>'数据有误');        json($show, $callback);	}	$type = $data['type'];	switch($type){		case 'docs':			$this->docsTran($data);		break;		case 'pic':			$this->picTran($data);		break;		default:			$this->docsTran($data);		break;	}}//文档翻译接口private function docsTran($data){	//die('ooo');	$file = $data['localFile'];//I('file');	$from = I('from', 'zh');	$to = I('to','en');	$callback = I('callback');	if(empty($file)){        $show = array('status'=>422,'message'=>'请上传文档文件');        json($show, $callback);	}    $path_parts = pathinfo($file);    $ext = strtolower($path_parts["extension"]);    $extAry = array(    	'docx','xls','xlsx','ppt','pptx','pdf'    );    if(!in_array($ext, $extAry)){        $show = array('status'=>423,'message'=>'请上传文档文件');        json($show, $callback);    }	if($from == $to){        $show = array('status'=>424,'message'=>'翻译语言不能与原文档言语一样');        json($show, $callback);	}	$arr = array(		'requestId'		=> uniqid(),		'sourceFile'	=> $data['sourceFile'],		'localFile'		=> '',		'type'			=> 'docs',		'content'		=> '',		'create_time'	=> time()	);	$id = $this->common->set($arr);	$params = array(	    'appid' => $this->appid, //你的appid	    'from' => $from, 	    'to' => $to,	    'timestamp' => time(), //10位时间戳	    'type' => $ext, //文档类型,根据具体文档而定	);	$seckey = $this->seckey; //你的密钥	ksort($params);	$querySign = '';	foreach ($params as $key => $value) {	    $querySign .= $key . '=' . $value . '&';	}	$filePath = $file; //文档路径	$params['sign'] = md5($querySign . '' . md5_file($filePath) . '' . $seckey);	$url = 'http://fanyi-api.baidu.com/api/trans/vip/doctrans';	$header = array(	    'Content-Type' => 'multipart/form-data',	       );	$params['file'] =  '@' . realpath($imagePath);	//高版本兼容	if (class_exists('\CURLFile')) {	    $params['file'] = new \CURLFile(realpath($filePath));	}	$ch = curl_init();	curl_setopt($ch, CURLOPT_HTTPHEADER, $header);	curl_setopt($ch, CURLOPT_POST, 1);	curl_setopt($ch, CURLOPT_POSTFIELDS,$params);	curl_setopt($ch,CURLOPT_URL,$url);	curl_setopt($ch,CURLOPT_TIMEOUT, 10);	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);	$result=curl_exec($ch);	curl_close($ch);	logs('Docs Result>>>'.$result);	$callRet = json_decode($result, true);	//print_R($result); 	if($callRet['error_code'] == 52000){		$arr = array(			'requestId'		=> $callRet['data']['requestId'],		);		$this->common->update($arr, array('id'=>$id));		//$this->load->libraliry('Kafka');    	$this->kafkaMsg($callRet['data']['requestId']);        $show = array('status'=>0,'message'=>'翻译成功','requestId'=>$callRet['data']['requestId']);        json($show, $callback);	}else{        $show = array('status'=>$callRet['error_code'],'message'=>$callRet['error_msg']);        json($show, $callback);	}}//图片翻译接口private function picTran($data){	$file = $data['localFile'];//I('file');	//echo $file;	$from = I('from', 'zh');	$to = I('to','en');	$callback = I('callback');	if(empty($file)){        $show = array('status'=>422,'message'=>'请上传图片文件');        json($show, $callback);	}    $path_parts = pathinfo($file);    $ext = strtolower($path_parts["extension"]);    $extAry = array(    	'jpg','jpeg','png'    );    if(!in_array($ext, $extAry)){        $show = array('status'=>423,'message'=>'请上传图片文件');        json($show, $callback);    }	if($from == $to){        $show = array('status'=>424,'message'=>'翻译语言不能与原文件言语一样');        json($show, $callback);	}	$appid = $this->appid;	$salt = rand();	$cuid = 'APICUID';	$mac = 'MAC';	$secKey = $this->seckey;	$imagePath = $file;	//echo $imagePath;	$sign = md5($appid . md5(file_get_contents($imagePath)) . $salt . $cuid . $mac . $secKey);	$url = 'https://fanyi-api.baidu.com/api/trans/sdk/picture?appid=' . $this->appid . '&from=' . $from . '&to=' . $to . '&salt=' . $salt . '&cuid=' . $cuid . '&mac=' . $mac . '&sign=' . $sign;	$header = array(			'Content-Type' => 'multipart/form-data',		       );	$sendData = array(			'image' => '@' . realpath($imagePath) . ';type=image/jpeg',			);	if (class_exists('\CURLFile')) {		$sendData['image'] = new \CURLFile(realpath($imagePath));	}	$ch = curl_init();	curl_setopt($ch, CURLOPT_HTTPHEADER, $header);	curl_setopt($ch, CURLOPT_POST, 1);	curl_setopt($ch, CURLOPT_POSTFIELDS,$sendData);	curl_setopt($ch,CURLOPT_URL,$url);	curl_setopt($ch,CURLOPT_TIMEOUT, 10);	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);	$result=curl_exec($ch);	curl_close($ch);	logs('PIC Result>>>'.$result);	$callRet = json_decode($result, true);	//print_R($callRet); 	if($callRet['error_code'] == 0){		$arr = array(			'requestId'		=> uniqid(),			'sourceFile'	=> $data['sourceFile'],			'localFile'		=> $file,			'type'			=> 'pic',			'content'		=> $callRet['data']['sumSrc'],			'create_time'	=> time()		);		//print_r($arr);		$this->common->set($arr);        $show = array('status'=>0,'message'=>'翻译成功','srcContent'=>$callRet['data']['sumSrc'] ,'tranContent'	=> $callRet['data']['sumDst']);        json($show, $callback);	}else{        $show = array('status'=>$callRet['error_code'],'message'=>$callRet['error_msg']);        json($show, $callback);	}	}//消息生产private function kafkaMsg($requestId){    $topicname = "testlin";    logs('kafkaMsgStart>>>' . $requestId . '>>' . $topicname);    	$conf = new RdKafka\Conf();	$conf->set('metadata.broker.list', 'localhost:9092');	$producer = new RdKafka\Producer($conf);	$topic = $producer->newTopic($topicname);    $topic->produce(RD_KAFKA_PARTITION_UA, 0, $requestId);    //$producer->poll(0);    $result = $producer->flush(1000);	if (RD_KAFKA_RESP_ERR_NO_ERROR !== $result) {		logs('ERROR>>>' . 'Was unable to flush, messages might be lost!');	}    logs('kafkaMsgEnd>>>' . $requestId);     }
//百度返回后的处理,通过kafka订阅消息public function dealLocal(){    $topicname = "testlin";    logs('deal start>>>'.$topicname);    $conf = new RdKafka\Conf();    // Set the group id. This is required when storing offsets on the broker    $conf->set('group.id', 'myConsumerGroup');    $rk = new RdKafka\Consumer($conf);    $rk->addBrokers("localhost:9092");    $topicConf = new RdKafka\TopicConf();    $topicConf->set('auto.commit.interval.ms', 100);    // Set the offset store method to 'file'    $topicConf->set('offset.store.method', 'broker');    // Alternatively, set the offset store method to 'none'    // $topicConf->set('offset.store.method', 'none');    // Set where to start consuming messages when there is no initial offset in    // offset store or the desired offset is out of range.    // 'earliest': start from the beginning    $topicConf->set('auto.offset.reset', 'earliest');    $topic = $rk->newTopic($topicname, $topicConf);    // Start consuming partition 0    $topic->consumeStart(0, RD_KAFKA_OFFSET_STORED);    while (true) {        $message = $topic->consume(0, 120*10000);        switch ($message->err) {            case RD_KAFKA_RESP_ERR_NO_ERROR:                logs('MESSAGE>>>'  . $message->payload);                $this->dd($message->payload);                break;            case RD_KAFKA_RESP_ERR__PARTITION_EOF:                logs( "No more messages; will wait for more\n");                break;            case RD_KAFKA_RESP_ERR__TIMED_OUT:                logs( "Timed out\n");                break;            default:                logs( $message->errstr());                //throw new \Exception($message->errstr(), $message->err);                break;        }    }}//下载文档保存private function dd($requestId){    $app = '2020bd';    $dataEx = $this->common->getLog( array('requestId' => $requestId) );    logs('原数据ID>>>>'.json_encode($dataEx));    $fileSrcUrl = $dataEx['fileSrcUrl'];    $this->common->update(array('bdfile' => $fileSrcUrl, 'status' => 1, 'update_time' => time()), array('requestId' => $requestId));    //die();    //下载文件    $sPath = '/var/www/html/activity/storage/'.$app.'/';        if(empty($fileSrcUrl)){        logs('文件不存在,结束>>>>>');        die();    }    $fileTemp = explode('?', $fileSrcUrl);    $path_parts = pathinfo($fileTemp[0]);    $ext = strtolower($path_parts["extension"]);    logs('ext:'.$ext);    try{        logs('下载中>>>>'.$fileSrcUrl);        $filename = date('Ymd'). '_' .rand(10000, 99999).'_'.time();        $tmpfile = $filename . '.'.$ext;        $img = file_get_contents($fileSrcUrl);//logs('下载成功'.var_dump($img));        $path1 = $sPath . $tmpfile;        //logs('下载中>>>>'.$path1);        $res = file_put_contents($path1, $img);        $_SERVER['SERVER_NAME'] = 'w.com';        if(is_https()){            $url = 'https://'.$_SERVER['SERVER_NAME'].'/storage/'.$app.'/'.$tmpfile;        }else{            $url = 'http://'.$_SERVER['SERVER_NAME'].'/storage/'.$app.'/'.$tmpfile;        }                //if($res){            $this->common->update(array('localFile' => $url), array('requestId' => $requestId));            logs('下载成功>>>>'.$url);        /*}else{            logs('下载失败');        }*/    }catch(Exception $e){        logs($e->getMessage());    }    logs($requestId.'校验结束');    echo 'ok';}
//通过swoole处理,返回给前端public function dealForUser(){    $topicname = "getDocs";    logs('swoole start>>>'.$topicname);    //创建WebSocket Server对象,监听0.0.0.0:9502端口    $ws = new Swoole\WebSocket\Server('0.0.0.0', 9502);    //监听WebSocket连接打开事件    $ws->on('Open', function ($ws, $request) {        $ws->push($request->fd, '');    });    //监听WebSocket消息事件    $ws->on('Message', function ($ws, $frame) {        log("Message: {$frame->data}\n") ;        $requestId = $frame->data;        $file = $this->getDocs($requestId);        if(!empty($file)){            $ws->push($frame->fd, "{$file}");        }            });    //监听WebSocket连接关闭事件    $ws->on('Close', function ($ws, $fd) {        //echo "client-{$fd} is closed\n";    });    $ws->start();    logs('swoole end>>>'.$topicname);}//读取文档内容private function getDocs($requestId){    $app = '2020bd';    $dataEx = $this->common->get_one( array('requestId' => $requestId) );    if(!empty($dataEx)){       logs('DATA FIND>>>'.$dataEx['bdfile']) ;       return $dataEx['bdfile'];    }    return '';        logs($requestId.'校验结束');    echo 'ok';}

 前端测试代码

    
Document Test 文件上传框
显示进度条
上传成功后的返回内容
翻译测试:
<翻译》》》>
下载文档》》》
下载
图片翻译内容>>>

 

转载地址:http://oned.baihongyu.com/

你可能感兴趣的文章