PHPで自然文で質問して回答を得る

(1/1)
今回は、PHP で「docomo Developer support」を利用し、「さそり座にある 1等星の名前は?」のように自然文で質問を行い、自然文で回答を得るプログラムをつくる。
なお、今回のプログラムで利用している API が 2018 年(平成 30 年)6 月末に廃止予定とのアナウンスがあった。後継API を使ったプログラムは「PHP で自然対話(知識検索・雑談対話)」を参照のこと。

サンプル・プログラム:実行例

PHPで自然文で質問して回答を得る
「質問文」に質問文を記入し、「質問」ボタンを押下すると、回答が表示される。

サンプル・プログラム

docomo Developer support クラス

docomo Developer support を利用する関数群はクラス pahooDoCoMoAPI として別ファイル "pahooDoCoMoAPI.php" に定義してある。このファイルを  require_once  できるパスに配置すること。

https通信を使うため、PHP から OpenSSL を利用できるようにしておく必要がある。その手順は「PHP の https 対応」を参照のこと。

0022:     //認証用パラメータ:申請はhttps://dev.smt.docomo.ne.jp/?p=login
0023:     var $DOCOMO_API_KEY        = '***************';
0024:     var $DOCOMO_CLIENT_SECRET  = '***************';
0025:     var $DOCOMO_CLIENT_CLIENT  = '***************';

docomo Developer support を利用するには、事前にアカウント登録(無料)とアプリケーションを登録し、API キーなどを取得しておく必要がある。新規登録画面から登録しよう。

docomo Developer support:知識Q&A

自然文テキストで質問し、自然文テキストで回答を得るための docomo Developer support である。
知識Q&A (GET)
URL
https://api.apigw.smt.docomo.ne.jp/knowledgeQA/v1/ask

入力パラメータ
項目名 フィールド名 内  容
APIキー APIKEY string 【必須】APIにアクセスするアプリの認証に利用する。
質問文 q string 【必須】質問文を半角/全角2000文字以内で設定する(URLエンコード)。
応答データ(json) code 質問回答のレスポンスコード message textForDisplay メッセージ表示用のテキスト textForSpeech メッセージ読み上げ用のテキスト answers answer rank 回答の順位 answerText 回答テキスト linkText 引用元テキスト linkUrl 引用元URL

解説:API KEYを用いたリクエスト

0076: /**
0077:  * docomoAPI:API KEYを用いたリクエスト
0078:  * @param string $url    docomoAPIのリクエストURL
0079:  * @param string $method GET|POST
0080:  * @param array  $option オプションパラメータ配列/NULL
0081:  * @return bool TRUE:リクエスト成功/FALSE:失敗
0082: */
0083: function docomoAPI($url$method$option) {
0084:     //パラメータ
0085:     $params = array(
0086:         'APIKEY' => $this->DOCOMO_API_KEY
0087:     );
0088: 
0089:     $context['http']['header'] = array('Content-Type: application/json');
0090: 
0091:     //オプション処理
0092:     if (count($params) > 0) {
0093:         if ($method == 'GET') {
0094:             $params = array_merge($option$params);
0095:             $url .= '?' . http_build_query($params);
0096:         } else {
0097:             $url .= '?' . http_build_query($params);
0098:             $context['http']['content'] = $option;
0099:         }
0100:     }
0101: 
0102:     // cURLを使ってリクエスト
0103:     $curl = curl_init() ;
0104:     curl_setopt($curlCURLOPT_URL$url);
0105:     curl_setopt($curlCURLOPT_HEADER, 1); 
0106:     curl_setopt($curlCURLOPT_CUSTOMREQUEST$method);
0107:     curl_setopt($curlCURLOPT_SSL_VERIFYPEER , FALSE);  //証明書は無視
0108:     curl_setopt($curlCURLOPT_RETURNTRANSFERTRUE);        //結果を文字列で
0109:     curl_setopt($curlCURLOPT_HTTPHEADER$context['http']['header']);
0110:     if (isset($context['http']['content']) && !empty($context['http']['content'])) {
0111:         curl_setopt($curlCURLOPT_POSTFIELDS$context['http']['content']);         //リクエストボディ
0112:     }
0113:     curl_setopt($curlCURLOPT_TIMEOUT, 5);
0114:     $res1 = curl_exec($curl);
0115:     $res2 = curl_getinfo($curl);
0116:     curl_close($curl);
0117: 
0118:     //結果処理
0119:     $this->webapi = $url;
0120:     $json = substr($res1$res2['header_size']);
0121:     $this->responses = json_decode($jsonFALSE, 512, JSON_BIGINT_AS_STRING);
0122:     if (isset($this->responses->requesError)) {
0123:         $this->error   = TRUE;
0124:         $this->errmsg  = $this->responses->requesError->policyException->text;
0125:         $this->errcode = $this->responses->requesError->policyException->messageId;
0126:     }
0127: 
0128:     return (! $this->error);
0129: }

docomo Developer support の呼び出しは https であることから、「PHP セキュリティ対策:SSL通信を行う」で紹介した CURL, Client URL Library 関数を利用する。

解説:知識Q&A

0131: /**
0132:  * 知識Q&A
0133:  * @param string $query 質問文(UTF-8限定)
0134:  * @return bool TRUE:リクエスト成功/FALSE:失敗
0135: */
0136: function knowledgeQA($query) {
0137:     $url    = 'https://api.apigw.smt.docomo.ne.jp/knowledgeQA/v1/ask';
0138:     $method = 'GET';
0139:     $option = array('q' => $query);
0140: 
0141:     return $this->docomoAPI($url$method$option);
0142: }

仕様通りに知識Q&Aを呼び出すメソッドである。

解説:知識Q&Aを利用

0140: /**
0141:  * docomoAPI の知識Q&Aを利用する
0142:  * @param string $query  質問文
0143:  * @param string $answer 回答を格納する変数
0144:  * @param   string $api    利用したWebAPIのURLを格納する変数
0145:  * @return string エラーメッセージ/''
0146: */
0147: function ask_knowledgeQA($query, &$answer, &$api) {
0148:     $pda = new pahooDoCoMoAPI(); //docomoAPIクラス
0149: 
0150:     if ($query == '')  return '質問文がありません';
0151:     if (mb_strlen($query > 2000))   return '質問文が長すぎます';
0152: 
0153:     //docomoAPI 知識Q&A
0154:     $results = $pda->knowledgeQA($query);
0155: 
0156:     if ($results == FALSE) {
0157:         $answer = $api = '';
0158:         return $query . ' の回答を取得できません';
0159:     } else {
0160:         $answer = $pda->responses->message->textForDisplay;
0161:         $api = $pda->webapi;
0162:     }
0163: 
0164:     return '';
0165: }

まず、docomo Developer support クラスを呼び出す。
質問文 $query が空だったり 2000 文字を超えたらエラーを返すようにする。

続いて、前述のメソッド knowledgeQA を呼び出す。
回答は、textForDisplay に入っているメッセージをそのまま利用する。

参考サイト

(この項おわり)
header