目次
サンプル・プログラムの実行例
サンプル・プログラム
| wikisearch.php | サンプル・プログラム本体 |
| pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
| pahooCache.php | キャッシュ処理に関わるクラス pahooCache。 キャッシュ処理に関わるクラスの使い方は「PHPで天気予報を求める」を参照。include_path が通ったディレクトリに配置すること。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.2.0 | 2025/09/06 | pahooCacheクラス導入 |
| 2.1 | 2021/04/08 | PHP8対応,リファラ・チェック改良 |
| 2.0 | 2020/12/19 | Wikipedia APIに切替。全面改訂。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.0.1 | 2025/08/11 | getParam() bug-fix |
| 2.0.0 | 2025/08/11 | pahooLoadEnv() 追加 |
| 1.9.0 | 2025/07/26 | getParam() 引数に$trim追加 |
| 1.8.1 | 2025/03/15 | validRegexPattern() debug |
| 1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 1.3.0 | 2025/12/06 | PHP8.5対応:curl_closeを使わない |
| 1.2.0 | 2025/09/06 | cLoad() HTTPヘッダを送信できるようにした |
| 1.1.3 | 2025/08/10 | var→public |
| 1.1.2 | 2023/07/22 | bug-fix |
| 1.1.1 | 2023/02/11 | コメント追記 |
サンプル・プログラムの流れ
次に、WebAPI の応答フォーマットがXMLかJSONかを識別する。後述するが、一般的なWebAPI にはXMLを返すものとJSONを返すものがあり、今回は学習用として、どちらにも対応できるような関数を用意している。
応答フォーマットがXMLのとき、WebAPI をコールして、サマリを返す関数が searchWikipediaSummaryXML である。Wikipedia API を呼び出したら、エラーチェックを行い、エラーが無ければ変数 $res にサマリーを、エラーがあれば FALSE を返す。
最後に、makeCommonBody 関数を使ってHTMLのbodyタグ部分を生成し、あらかじめ用意したヘッダとフッタをあわせて、ブラウザに表示する。
今後紹介するクラウド連携プログラムも、基本的にこのフローに沿って構築されている。
準備:PHP の https対応
Windowsでは、"php.ini" の下記の行を有効化する。
extension=php_openssl.dllLinuxでは --with-openssl=/usr オプションを付けて再ビルドする。→OpenSSLインストール手順
これで準備は完了だ。
準備:pahooInputData 関数群
また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
準備:pahooCache クラス
pahooCache.php
13: class pahooCache {
14: const LIFE_CACHE = (2 * 60); // キャッシュ保持時間(デフォルト;分)
15: const DEF_DIRCACHE = './pcache/'; // キャッシュ・ディレクトリ(デフォルト)
16:
17: public $lifeCache; // キャッシュ保持時間(分)(0:キャッシュしない)
18: public $dirCache; // キャッシュ用ディレクトリ
19: public $httpHeader; // HTTPヘッダ(空文字の時は何も送らない)
20: public $error; // エラーフラグ
21: public $errmsg; // エラーメッセージ
22: public $debug; // デバッグ用ファイル名
23:
24: /**
25: * コンストラクタ
26: * 参考サイト https://www.pahoo.org/e-soul/webtech/php06/php06-72-01.shtm
27: * @param int $life キャッシュ保持時間(分)(省略可能)
28: * @param string $dir キャッシュ・ディレクトリ(省略可能)
29: * @param array $httpHeader httpヘッダに渡す配列(省略可能)
30: * USER AGENT偽装に用いることを想定
31: * (例)
32: * array(
33: * 'User-Agent: Mozilla/5.0(Windows NT 10.0; Win64; x64) pahooAppy/pahoo.org AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
34: * 'Accept-Language: ja-JP'
35: * );
36: * @return なし
37: */
38: function __construct($life=self::LIFE_CACHE, $dir=self::DEF_DIRCACHE, $httpHeader=NULL) {
39: if ($life < 0) {
40: $life = 0;
41: }
42: if (preg_match('/\/$/ui', $dir) == 0) {
43: $dir = $dir . '/';
44: }
45: $this->error = FALSE;
46: $this->errmsg = '';
47: $this->debug = '';
48: $this->lifeCache = $life;
49: $this->dirCache = $dir;
50: $this->httpHeader = $httpHeader;
51:
52: // PHP5以上であることを調べる.
53: if (! $this->isphp5over()) {
54: $this->error = TRUE;
55: $this->errmsg = '動作にはPHP5以上が必要です';
56: return;
57: }
58:
59: // キャッシュ・ディレクトリが無ければ作成する.
60: if (! is_dir($this->dirCache)) {
61: $res = mkdir($this->dirCache, 0744);
62: if ($res == FALSE) {
63: $this->error = TRUE;
64: $this->errmsg = 'キャッシュ・ディレクトリ "' . $this->$dirCache . '" の作成に失敗しました';
65: return;
66: }
67: }
68: }
そこで、頻繁に変更がないデータについては、一度取り込んだら、こちら側のサーバのローカルストレージにキャッシュしておく仕組みを用意した。それが pahooCacheクラス である。同梱のクラス・ファイル "pahooCache.php" は include_path が通ったディレクトリに配置してほしい。他のプログラムでも pahooCacheクラス を利用するが、常に最新のクラス・ファイルを1つ配置すればよい。
pahooCacheクラス の注意ポイントは、キャッシュ時間(単位:分)とキャッシュを保存するディレクトリをコンストラクタで指定している点だ。これらはプログラムによって変わるものである。インスタンス化するときの値は、pahooCacheクラス を利用するメイン・プログラムの方で解説する。
サイトによっては、User-Agent などを必要とすることがあるだろう。そこで、第3引数に HTTPヘッダ として送信するデータを配列で渡すことができるようにした。配列の構造はコメントを参照していただきたい。
PHPのクラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。
準備:各種定数など
wikisearch.php
61: // 各種定数(START) ===========================================================
62:
63: // 応答フォーマット:切替可能
64: define('REQUEST_FORMAT', 'xml');
65: // define('REQUEST_FORMAT', 'json');
66:
67: // API呼び出しURL:変更不可
68: define('REQUEST_WIKIPEDIA', 'https://ja.wikipedia.org/w/api.php');
69:
70: // 表示幅(ピクセル)
71: define('WIDTH', 600);
72:
73: // 検索キーワード(デフォルト)
74: define('DEF_QUERY', 'PHP');
75:
76: // キャッシュ保持時間(分) 0:キャッシュしない
77: // Wikipediaへのアクセス負荷軽減のため,720分以上のキャッシュ保持をお勧めする.
78: define('LIFE_CACHE', 1440);
79:
80: // キャッシュ・ディレクトリ
81: // 書き込み可能で,外部からアクセスされないディレクトリを指定すること.
82: define('DIR_CACHE', './pcache/');
83:
84: // Wikipediaアクセス時に送信するHTTPヘッダ
85: $HttpHeader = array(
86: 'User-Agent: Mozilla/5.0(Windows NT 10.0; Win64; x64) pahooAppy/pahoo.org AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
87: 'Accept-Language: ja-JP'
88: );
89:
90: // 各種定数(END) ===============================================================
後述する応答フォーマットを REQUEST_FORMAT によって切り換えることができるようにしてある。
後述するように pahooCache クラスを使用する。定数 LIFE_CACHE にキャッシュ保持時間を、定数 DIR_CACHE にキャッシュ・ディレクトリを設定する。それぞれの設定値についてはコメントを参照のこと。
制約事項であるが、定数 LIFE_CACHE で指定した期間中は、Wikipediaサイトからデータを取ってこない。したがって、この期間中に Wikipediaサイトが編集されたとしても、その内容は反映されない。
2025年(令和7年)9月現在、Wikipediaにアクセスするのに User-Agent が必要になった。すべてのコンテンツについて必要かどうかは確認していないが、念のため、User-Agent と Accep--Language を送信するようにした。その値を設定しているのがグローバル配列 $HttpHeader である。
User-Agent の内容は自由に変更して構わない。また、これ以外にも HTTPヘッダとして送るデータが出てきたら、配列 $HttpHeader に追加してほしい。
Wikipedia API
| URL |
|---|
| https://ja.wikipedia.org/w/api.php |
| フィールド名 | 要否 | 内 容 |
|---|---|---|
| format | 省略可 | xml, json, yaml等 |
| action | 必須 | 操作:ここではquery |
| prop | 省略可 | action固有のパラメータ。記事の各構成要素を取得する。ここではextractsを指定し、サマリを抽出する。 |
| explaintext | 省略可 | 出力をHTMLではなくプレーンテキストにする。 |
| redirects | 省略可 | リダイレクト記事を含める。 |
| titles | 必須 | 見出し検索語。 |
解説:サマリのリクエストURLを取得する
wikisearch.php
151: /**
152: * Wikipedia API:サマリのリクエストURLを取得する
153: * @param string $query 検索キーワード(UTF-8)
154: * @return string URL URL
155: */
156: function getURL_WikipediaAPI_summary($query) {
157: return REQUEST_WIKIPEDIA . '?format=' . REQUEST_FORMAT . '&action=query&prop=extracts&exintro&explaintext&redirects=1&titles=' . urlencode($query);
158: }
Wikipedia検索(サマリ):XML応答
wikisearch.php
160: /**
161: * Wikipedia検索(サマリ):XML応答
162: * @param string $query 検索キーワード(UTF-8)
163: * @param string $errmsg エラーメッセージを格納
164: * @return string サマリ/FALSE:エラー発生
165: */
166: function searchWikipediaSummaryXML($query, &$errmsg) {
167: // インスタンス生成
168: global $HttpHeader;
169: $pcc = new pahooCache(LIFE_CACHE, DIR_CACHE, $HttpHeader);
170:
171: // リクエストURL
172: $url = getURL_WikipediaAPI_summary($query);
173:
174: // XMLエラーを有効にする
175: libxml_use_internal_errors(TRUE);
176:
177: // 応答読み込み
178: $xml = $pcc->simplexml_load($url);
179:
180: // インスタンス解放
181: $pcc = NULL;
182:
183: // Wikipedia API接続失敗
184: if (count(libxml_get_errors()) > 0) {
185: $res = FALSE;
186: $errmsg = 'Wikipedia APIに接続できません';
187: // 検索結果あり
188: } else if (isset($xml->query->pages->page->extract)) {
189: $res = $xml->query->pages->page->extract;
190: $errmsg = '';
191: // 検索結果なし
192: } else {
193: $res = FALSE;
194: $errmsg = '検索結果がありません';
195: }
196:
197: return $res;
198: }
まず、検索キーワードをユーザー関数 getURL_WikipediaAPI_summary に渡し、リクエストURLを受け取る。
次に、 libxml_use_internal_errors 関数でXMLエラーを有効にしてから、simplexml_load メソッドを使って応答XMLを受け取る。
XMLエラーを有効にしたので、リクエストURLが反応しない場合は、 libxml_get_errors 関数にエラーが入る。結果の配列が無ければ、リクエストURLは何らかの応答を返している。
最後に、応答構造 $xml->query->pages->page->extract が存在するかどうかをチェックし、存在すれば、それがサマリーである。無ければ、検索結果無しのエラーを返す。
解説:Wikipedia検索(サマリ):JSON応答
wikisearch.php
200: /**
201: * Wikipedia検索(サマリ):JSON応答
202: * @param string $query 検索キーワード
203: * @param string $errmsg エラーメッセージを格納
204: * @return string サマリ/FALSE:エラー発生
205: */
206: function searchWikipediaSummaryJSON($query, &$errmsg) {
207: $url = getURL_WikipediaAPI_summary($query); // リクエストURL
208:
209: $json = @file_get_contents($url);
210:
211: // Wikipedia API接続失敗
212: if ($json == FALSE) {
213: $res = FALSE;
214: $errmsg = 'Wikipedia APIに接続できません';
215: // JSON解釈
216: } else {
217: $res = FALSE;
218: $errmsg = '検索結果がありません';
219: $json = json_decode($json);
220: foreach ($json as $obj1) {
221: if (is_object($obj1)) {
222: foreach ($obj1 as $obj2) {
223: if (is_object($obj2)) {
224: foreach ($obj2 as $obj3) {
225: if (is_object($obj3)) {
226: if (isset($obj3->extract)) {
227: $res = (string)$obj3->extract;
228: $errmsg = '';
229: }
230: }
231: }
232: }
233: }
234: }
235: }
236: }
237: return $res;
238: }
一般的にWebAPIでは、応答がXMLの場合とJSONの場合とがあるので、ここでは学習のため、両方のユーザー関数を用意した。
まず、検索キーワードをユーザー関数 getURL_WikipediaAPI_summary に渡し、リクエストURLを受け取るところはユーザー関数 searchWikipediaSummaryXML と同じである。
JSONの場合、応答は file_get_contents 関数を使って受け取る。戻り値がFALSEであれば、リクエストURLが反応していないとしてエラーを返す。
戻り値があれば、 json_decode
が、応答構造が可変であるため、foreach を使ってオブジェクト・ツリーを下ってゆく。
HTML BODYを作成する
wikisearch.php
240: /**
241: * HTML BODYを作成する
242: * @param string $query 検索キーワード
243: * @param string $summary Wikipediaサマリ
244: * @param string $errmsg エラーメッセージ;エラー無しの時は空文字
245: * @param string $url リクエストURL
246: * @return string HTML BODY
247: */
248: function makeCommonBody($query, $summary, $errmsg, $url) {
249: $myself = MYSELF;
250: $refere = REFERENCE;
251: $width = WIDTH;
252: $p_title = TITLE;
253: $version = '<span style="font-size:small;">' . date('Y/m/d版', filemtime(__FILE__)) . '</span>';
254:
255: // 表示内容を $msg へ
256: if ($errmsg == '') {
257: $msg = '<h3>検索結果</h3>' . nl2br($summary);
258: } else {
259: $msg = '<span style="color:red;">error: ' . $errmsg . '</span>';
260: }
261:
262: // デバッグ用表示
263: if (! FLAG_RELEASE) {
264: $phpver = phpversion();
265: $format = REQUEST_FORMAT;
266: $phpver =<<< EOT
267: PHPver : {$phpver}<br>
268: FORMAT : {$format}<br>
269: WebAPI : <a href="{$url}">{$url}</a><br>
270:
271: EOT;
272: } else {
273: $phpver = '';
274: }
275:
276: $body =<<< EOT
277: <body>
278: <h2>{$p_title} {$version}</h2>
279: <form name="myform" method="GET" action="{$myself}" enctype="multipart/form-data">
280: 検索キーワード:
281: <input type="text" name="query" id="query" size="40" value="{$query}">
282: <input type="submit" name="exec" value="検索">
283: <input type="submit" name="reset" value="リセット">
284: </form>
285: <div style="border-style:solid; border-width:1px; margin:20px 0px 0px 0px; padding:5px; width:{$width}px; overflow-wrap:break-word; word-break:break-all;">
286: {$msg}
287: </div>
288:
289: <div style="border-style:solid; border-width:1px; margin:20px 0px 0px 0px; padding:5px; width:{$width}px; font-size:small; overflow-wrap:break-word; word-break:break-all;">
290: <h3>使い方</h3>
291: <ol>
292: <li>[<span style="font-weight:bold;">検索キーワード</span>]に検索したいキーワードを入力してください.</li>
293: <li>[<span style="font-weight:bold;">検索</span>]ボタンを押してください.</li>
294: <li>検索結果を表示します.</li>
295: <li>[<span style="font-weight:bold;">リセット</span>]ボタンを押すと,初期化します.</li>
296: </ol>
297: ※参考サイト:<a href="{$refere}">{$refere}</a>
298: <p>{$phpver}</p>
299: </div>
300: </body>
301:
302: EOT;
303: return $body;
304: }
検索キーワード入力と結果表示を1つの関数で処理している。入力した検索キーワードはURL変数 query に追加し、再び自分自身(PHPプログラム)を呼び出す。頭で説明したサンプル・プログラムの流れの通り、query に値が入ることで検索処理を実行する仕組みである。
まず、エラーメッセージがあるかどうかをチェックし、無ければ「検索結果」の見出しを、あればエラーメッセージを赤色にして変数 $msg に代入する。変数 $msg は、このあと、結果表示用に利用する。
デバッグ用に定数 FLAG_RELEASE がFALSEのときは、PHPのバージョン、応答フォーマット(XMLまたはJSON)、WebAPIのリクエストURLを変数 $phpver に代入する。
最後に、変数 $body にbodyタグの内容を代入していく。
代入する内容が長いので、実際のHTMLタグを書くようにして代入ができるPHPのヒアドキュメント構文]を利用している。可変部分は "{$変数}:blue" のようにして、変数の値を代入することができる。
メイン・プログラム
wikisearch.php
306: // メイン・プログラム =======================================================
307: // 初期値
308: $query = getParam('query', TRUE, DEF_QUERY);
309: $summary = $errmsg = '';
310:
311: // リセット
312: if (isButton('reset')) {
313: $query = DEF_QUERY;
314: }
315:
316: // 検索実行
317: if ($query != '') {
318: if (REQUEST_FORMAT == 'xml') {
319: $summary = searchWikipediaSummaryXML($query, $errmsg);
320: } else {
321: $summary = searchWikipediaSummaryJSON($query, $errmsg);
322: }
323: }
324:
325: // リクエストURL
326: $url = getURL_WikipediaAPI_summary($query);
327:
328: // 表示用コンテンツ作成
329: $HtmlBody = makeCommonBody($query, $summary, $errmsg, $url);
330:
331: // 表示処理
332: echo $HtmlHeader;
333: echo $HtmlBody;
334: echo $HtmlFooter;
まず、URL変数として query があれば、それを検索キーワードとして変数 $query に代入する。
resetボタンが押下されたら、変数 $query の値をデフォルト値にする。
続いて、検索を実行する。
最後に、makeCommonBody を呼び出し、事前に用意してあるヘッダ $HtmlHeader、フッタ $HtmlFooter とあわせてブラウザに表示する。
メイン・プログラムで呼び出している、その他の関数については後述する。
指定したパラメータを取り出す
wikisearch.php
引数 $key はパラメータ名である。
たとえば "wikisearch.php?query=PHP" のようにして呼び出されたら、$key に "query" を指定することで、値 "PHP" を返す。
日本語はURLエンコードされるので、受け取った値をデコードしたいときは、引数 $auto を TRUE にする。
URL変数が見当たらないときの初期値は、引数 $def に代入する。
引数 $auto および $def は、PHPの可変長引数リスト機能を使って省略可能にしてある。省略時には、イコールの右側の値が代入される。
URL変数は、GET渡しが優先で、無ければPOST渡しを探し、それでも無ければ $def の値を返す。
指定したボタンが押下されたか
wikisearch.php
PHP5以上かどうか検査する
wikisearch.php
プログラム冒頭で実行し、PHP5以上でなければエラーメッセージを表示して、強制終了する。
リファラ・チェック
wikisearch.php
135: // リファラ・チェック
136: if (REFER_ON != '') {
137: if (isset($_SERVER['HTTP_REFERER'])) {
138: $url = parse_url($_SERVER['HTTP_REFERER']);
139: $res = ($url['host'] == REFER_ON) ? TRUE : FALSE;
140: } else {
141: $res = FALSE;
142: }
143: } else {
144: $res = TRUE;
145: }
146: if (! $res) {
147: echo 'Please refer to ' . REFER_ON . ' !';
148: exit(1);
149: }
150:
151: /**
wikisearch.php
50: // リファラ・チェック(直リン防止用;空文字ならチェックしない)
51: if (! isCommandLine()) {
52: define('REFER_ON', 'www.pahoo.org');
定数 REFER_ON には、本プログラムを配置したサーバのドメイン名をセットしておく。本プログラムが、このドメインから呼び出されていなければ、エラーメッセージを表示して、強制終了する。
また、定数 REFER_ON を空文字にすることで、このチェックを働かないようにすることができる。
エラー処理ハンドラ
wikisearch.php
125: /**
126: * エラー処理ハンドラ
127: */
128: function myErrorHandler($errno, $errmsg, $filename, $linenum) {
129: echo 'Sory, system error occured !';
130: exit(1);
131: }
wikisearch.php
132: error_reporting(E_ALL);
133: if (FLAG_RELEASE) $old_error_handler = set_error_handler('myErrorHandler');
自前のエラーハンドラ関数 myErrorHandler に差し替えて、簡単なエラーメッセージを表示して強制終了する。
質疑応答
プログラムをダウンロードして、自分のサイトで使用できるのか試してみましたが、システムエラーとしか表示されません。【回答】
Wikipediaの利用に際して、ユーザー登録などが必要なのでしょうか。APIのサイトを見ても自分ではよくわかりません。
自分のサイトで使用する場合、どこをどう変更するのか、そのあたりを教えてください。
自サイトで使用できないと送りましたが、
define('REFER_ON', '');
とするだけでよかったのですね。利用させていただきます。
二十四節気+節分・七十二候一覧を作成も利用させていただきます。
ご利用ありがとうございます。
説明不足でしたね。「リファラ・チェック」に補足説明をしました。
参考サイト
- MediaWiki API
- PHPでマッシュアップするための準備:ぱふぅ家のホームページ

今回は、PHPで WebAPI を利用する手始めとして、Wikipedia API を利用し、検索キーワードを入力し、ヒットした見出し語のサマリを表示するプログラムを作ってみることにする。
さらに、KAKASI を使った単語分解処理と組み合わせることで、用語の解説として Wikipedia のハイパーリンクを張ったようなサイトを構築することもできるだろう。
なお、本記事は作成当初 http://wikipedia.simpleapi.net を利用するプログラムを紹介していたが、2020年(令和2年)12月現在、このWebAPIは動作していないようなので、Wikipedia API を利用するプログラムに全面改訂した。
(2025年12月6日)PHP8.5対応:curl_closeを使わない
(2025年9月6日)Wikipediaの仕様変更への対応=pahooCacheクラスを導入した.pahooCacheクラスにHTTPヘッダ送信機能を追加した.