[PHPでLOD Part.1]PHPでDBpediaの記事をぶっこ抜く
Linked Open Dataを使用する際に必要なURIをPHPで取得させてみました。とりあえずDBpediaを使ってWikipediaの情報をぶっこ抜きしたサンプルつきです。
目次
追記
記事内にてWordPressでは非推奨のコードを使用していましたので、記事タイトルを変更しています。
- ・非推奨コード:file_get_contents
- ・代替コード :wp_remote_get
wp_remote_getを使用したバージョンについては、近日中にアップ予定です。
*大曲さんご指摘ありがとうございましたm(_ _)m
ことの発端
1:Code for ShigaでLODを使った「琵琶湖花火大会アプリ」を作りました。
2:WordFesNagoya2014で、そのことについてLTしました。
3:第33回WordBench大阪で世話人することになりました。
4:「当日までになんかサンプル作ろう」ということに。
そもそもLODって?
ざっくり言ってしまうと、「データ版Flickr」みたいなものです。
CC(クリエイティブコモンズ)で公開されているデータをAPI形式で取得することで、誰でも自由に利用することができます。
Wikipediaや行政のデータを、「常に最新の情報」を「いちいちコピペせずとも」扱えるようになる素敵なやつです。
技術的には「RDF」や「turtle」などで公開されているデータを、「SPARQL」とよばれるクエリ言語でJSON形式とかで引っ張ってきて使うイメージです。
・・・なんのこっちゃらだと思いますので、ハッカソン当日までサンプル付きで「WordPressからLODを使う方法」を紹介していきたいと思います。
とりあえずPHPでLODを取得する
本来は「SPARQLでデータを検索する方法」をまず紹介すべきなのでしょうが、WordPress側でデータを表示させることを優先します。
「待てない」っちゅう方はこのスライドでの自習推奨です。
今回のサンプル
とりあえずここではWikipediaからデータを引っ張ってくる形をとります。
行政系とかですとその地域の人以外にとっては全く面白くないですし、いろんなデータで遊べるというあたりも練習台にはうってつけです。
Wikipediaのデータは「DBpedia Japanese」にてLOD化されています。
SPAQRLのサンプルなどもありますので、余裕があればここで色々と試してみるのもオススメです。
ということでこのDBPediaからAPIに必要なURIをとってきます。
「API」というからには「URI」が存在する
APIを使うということは、どういう形であれ「URI」が必要になります。
「なんで必要なのか?」と疑問をもたれる方もいらっしゃると思いますが、とりあえず「そういうもの」だと思ってください。そしてググろう
今回は「PHPで表示できるようにすること」がゴールですので、「URIを取得する方法」についてはざっくり割愛してしまいましょう。
ここまで3分クッキング並みにすっ飛ばしてますが、すっ飛ばした分はまた後日紹介するということでご勘弁ください。
というわけで今回使用するURIはこちら、
[html]
https://ja.dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fja.dbpedia.org&query=PREFIX+geo%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2003%2F01%2Fgeo%2Fwgs84_pos%23%3E+PREFIX+dbpedia-owl%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%2F%3EPREFIX+prop-ja%3A+%3Chttp%3A%2F%2Fja.dbpedia.org%2Fproperty%2F%3EPREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3EPREFIX+rs%3A%3Chttp%3A%2F%2Fja.dbpedia.org%2Fresource%2F%3Eselect+distinct+%3Fcont+%3Faddress+%3Fthumb+%3Flink+%3Fd+%3Fname+%3Fnum+where+%7B%3Fb+prop-ja%3A%E6%9C%AD%E6%89%80%E7%AD%89+%22%E8%A5%BF%E5%9B%BD%E4%B8%89%E5%8D%81%E4%B8%89%E6%89%80%E7%AC%AC1%E7%95%AA%22%40ja%3Brdfs%3Alabel+%3Ftitles%3Brdfs%3Acomment+%3Fcont%3Bdbpedia-owl%3Aaddress+%3Faddress%3Bdbpedia-owl%3Athumbnail+%3Fthumb%3Bdbpedia-owl%3AwikiPageExternalLink+%3Flink%3Bprop-ja%3A%E9%96%8B%E5%9F%BA+%3Fd%3Bprop-ja%3A%E5%90%8D%E7%A7%B0+%3Fname%3Bprop-ja%3A%E6%9C%AD%E6%89%80%E7%AD%89+%3Fnum.%7D&format=application%2Fsparql-results%2Bjson&timeout=0&debug=on
[/html]
べらぼうに長いですね。
SEO対策でURLクエリをどうにかされた方などにとってかなり汚らしいURIに見えると思います。
ただこれはSPARQLがそのまま載っちゃっている関係ですので、「仕方ないね」と割り切って下さい。
JSONデータを取得しよう
先ほどのURLに直接アクセスすると、JSON形式のデータが表示されます。
ということで後はこれをPHPで扱えるように加工してしまいましょう。
PHPでJSONファイルを読み込む際は「file_get_contents」と「json_decode」を使用します。
*追記(9月10日):WordPressの場合は「file_get_contents」ではなく「wp_remote_get」を使用するとのことです。
参考:wp_remote_get は file_get_contents よりも応用できてよいですね【WordPress】
修正コードは近日中にアップします。
【functions.phpに追加するコード】
[php]
function get_sparql_data(){
//APIのURI
$sparql_url = "https://ja.dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fja.dbpedia.org&query=PREFIX+geo%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2003%2F01%2Fgeo%2Fwgs84_pos%23%3E+PREFIX+dbpedia-owl%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%2F%3EPREFIX+prop-ja%3A+%3Chttp%3A%2F%2Fja.dbpedia.org%2Fproperty%2F%3EPREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3EPREFIX+rs%3A%3Chttp%3A%2F%2Fja.dbpedia.org%2Fresource%2F%3Eselect+distinct+%3Fcont+%3Faddress+%3Fthumb+%3Flink+%3Fd+%3Fname+%3Fnum+where+%7B%3Fb+prop-ja%3A%E6%9C%AD%E6%89%80%E7%AD%89+%22%E8%A5%BF%E5%9B%BD%E4%B8%89%E5%8D%81%E4%B8%89%E6%89%80%E7%AC%AC1%E7%95%AA%22%40ja%3Brdfs%3Alabel+%3Ftitles%3Brdfs%3Acomment+%3Fcont%3Bdbpedia-owl%3Aaddress+%3Faddress%3Bdbpedia-owl%3Athumbnail+%3Fthumb%3Bdbpedia-owl%3AwikiPageExternalLink+%3Flink%3Bprop-ja%3A%E9%96%8B%E5%9F%BA+%3Fd%3Bprop-ja%3A%E5%90%8D%E7%A7%B0+%3Fname%3Bprop-ja%3A%E6%9C%AD%E6%89%80%E7%AD%89+%3Fnum.%7D&format=application%2Fsparql-results%2Bjson&timeout=0&debug=on";
//ファイルを取得する
$sparql_json = file_get_contents($sparql_url);
//JSONをオブジェクト形式に変換する
$sparql_data = json_decode($sparql_json);
//配列に変換する場合はこっち
//$sparql_data = json_decode($sparql_json, true);
//とりあえず中身を見てみよう
var_dump($sparql_data);
return $sparql_data;
}
[/php]
json_decode関数は完全に配列にするか、オブジェクト形式にするか選べる。
個人的にオブジェクト形式の方が使いやすいので、こっちを採用した。
で先ほど取得したデータを見てみるとこうなる。
[php]
object(stdClass)#2311 (2) {
["head"]=>
object(stdClass)#2310 (2) {
["link"]=>
array(0) {
}
["vars"]=>
array(7) {
[0]=>
string(4) "cont"
[1]=>
string(7) "address"
[2]=>
string(5) "thumb"
[3]=>
string(4) "link"
[4]=>
string(1) "d"
[5]=>
string(4) "name"
[6]=>
string(3) "num"
}
}
["results"]=>
object(stdClass)#2309 (3) {
["distinct"]=>
bool(false)
["ordered"]=>
bool(true)
["bindings"]=>
array(3) {
[0]=>
object(stdClass)#2312 (7) {
["cont"]=>
object(stdClass)#2313 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(377) "青岸渡寺(せいがんとじ)は、和歌山県東牟婁郡那智勝浦町にある天台宗の寺院。西国三十三所第一番札所。山号は那智山。本尊は如意輪観世音菩薩。 本堂および宝篋印塔は国の重要文化財。ユネスコの世界遺産『紀伊山地の霊場と参詣道』(2004年〈平成16年〉7月登録)の一部。"
}
["address"]=>
object(stdClass)#2314 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(49) "和歌山県東牟婁郡那智勝浦町那智山8"
}
["thumb"]=>
object(stdClass)#2315 (2) {
["type"]=>
string(3) "uri"
["value"]=>
string(96) "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Seigantoji01.JPG/200px-Seigantoji01.JPG"
}
["link"]=>
object(stdClass)#2316 (2) {
["type"]=>
string(3) "uri"
["value"]=>
string(49) "https://www2.ocn.ne.jp/~sanzan/NTTcontents/seigan/"
}
["d"]=>
object(stdClass)#2317 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(18) "伝・裸形上人"
}
["name"]=>
object(stdClass)#2318 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(12) "青岸渡寺"
}
["num"]=>
object(stdClass)#2319 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(25) "西国三十三所第1番"
}
}
[1]=>
object(stdClass)#2320 (7) {
["cont"]=>
object(stdClass)#2321 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(377) "青岸渡寺(せいがんとじ)は、和歌山県東牟婁郡那智勝浦町にある天台宗の寺院。西国三十三所第一番札所。山号は那智山。本尊は如意輪観世音菩薩。 本堂および宝篋印塔は国の重要文化財。ユネスコの世界遺産『紀伊山地の霊場と参詣道』(2004年〈平成16年〉7月登録)の一部。"
}
["address"]=>
object(stdClass)#2322 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(49) "和歌山県東牟婁郡那智勝浦町那智山8"
}
["thumb"]=>
object(stdClass)#2323 (2) {
["type"]=>
string(3) "uri"
["value"]=>
string(96) "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Seigantoji01.JPG/200px-Seigantoji01.JPG"
}
["link"]=>
object(stdClass)#2324 (2) {
["type"]=>
string(3) "uri"
["value"]=>
string(49) "https://www2.ocn.ne.jp/~sanzan/NTTcontents/seigan/"
}
["d"]=>
object(stdClass)#2325 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(18) "伝・裸形上人"
}
["name"]=>
object(stdClass)#2327 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(12) "青岸渡寺"
}
["num"]=>
object(stdClass)#2328 (2) {
["type"]=>
string(3) "uri"
["value"]=>
string(58) "https://ja.dbpedia.org/resource/東海白寿三十三観音"
}
}
[2]=>
object(stdClass)#2329 (7) {
["cont"]=>
object(stdClass)#2330 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(377) "青岸渡寺(せいがんとじ)は、和歌山県東牟婁郡那智勝浦町にある天台宗の寺院。西国三十三所第一番札所。山号は那智山。本尊は如意輪観世音菩薩。 本堂および宝篋印塔は国の重要文化財。ユネスコの世界遺産『紀伊山地の霊場と参詣道』(2004年〈平成16年〉7月登録)の一部。"
}
["address"]=>
object(stdClass)#2331 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(49) "和歌山県東牟婁郡那智勝浦町那智山8"
}
["thumb"]=>
object(stdClass)#2332 (2) {
["type"]=>
string(3) "uri"
["value"]=>
string(96) "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Seigantoji01.JPG/200px-Seigantoji01.JPG"
}
["link"]=>
object(stdClass)#2333 (2) {
["type"]=>
string(3) "uri"
["value"]=>
string(49) "https://www2.ocn.ne.jp/~sanzan/NTTcontents/seigan/"
}
["d"]=>
object(stdClass)#2334 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(18) "伝・裸形上人"
}
["name"]=>
object(stdClass)#2335 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(12) "青岸渡寺"
}
["num"]=>
object(stdClass)#2336 (3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(31) "神仏霊場巡拝の道第2番"
}
}
}
}
}
[/php]
はい。
先ほどの長ったらしいURIは、西国三十三所のスタート地点「青岸渡寺」のデータでした。
ちなみに通常の配列にすると、こうなります。
[php]
array(2) {
["head"]=>
array(2) {
["link"]=>
array(0) {
}
["vars"]=>
array(7) {
[0]=>
string(4) "cont"
[1]=>
string(7) "address"
[2]=>
string(5) "thumb"
[3]=>
string(4) "link"
[4]=>
string(1) "d"
[5]=>
string(4) "name"
[6]=>
string(3) "num"
}
}
["results"]=>
array(3) {
["distinct"]=>
bool(false)
["ordered"]=>
bool(true)
["bindings"]=>
array(3) {
[0]=>
array(7) {
["cont"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(377) "青岸渡寺(せいがんとじ)は、和歌山県東牟婁郡那智勝浦町にある天台宗の寺院。西国三十三所第一番札所。山号は那智山。本尊は如意輪観世音菩薩。 本堂および宝篋印塔は国の重要文化財。ユネスコの世界遺産『紀伊山地の霊場と参詣道』(2004年〈平成16年〉7月登録)の一部。"
}
["address"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(49) "和歌山県東牟婁郡那智勝浦町那智山8"
}
["thumb"]=>
array(2) {
["type"]=>
string(3) "uri"
["value"]=>
string(96) "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Seigantoji01.JPG/200px-Seigantoji01.JPG"
}
["link"]=>
array(2) {
["type"]=>
string(3) "uri"
["value"]=>
string(49) "https://www2.ocn.ne.jp/~sanzan/NTTcontents/seigan/"
}
["d"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(18) "伝・裸形上人"
}
["name"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(12) "青岸渡寺"
}
["num"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(25) "西国三十三所第1番"
}
}
[1]=>
array(7) {
["cont"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(377) "青岸渡寺(せいがんとじ)は、和歌山県東牟婁郡那智勝浦町にある天台宗の寺院。西国三十三所第一番札所。山号は那智山。本尊は如意輪観世音菩薩。 本堂および宝篋印塔は国の重要文化財。ユネスコの世界遺産『紀伊山地の霊場と参詣道』(2004年〈平成16年〉7月登録)の一部。"
}
["address"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(49) "和歌山県東牟婁郡那智勝浦町那智山8"
}
["thumb"]=>
array(2) {
["type"]=>
string(3) "uri"
["value"]=>
string(96) "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Seigantoji01.JPG/200px-Seigantoji01.JPG"
}
["link"]=>
array(2) {
["type"]=>
string(3) "uri"
["value"]=>
string(49) "https://www2.ocn.ne.jp/~sanzan/NTTcontents/seigan/"
}
["d"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(18) "伝・裸形上人"
}
["name"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(12) "青岸渡寺"
}
["num"]=>
array(2) {
["type"]=>
string(3) "uri"
["value"]=>
string(58) "https://ja.dbpedia.org/resource/東海白寿三十三観音"
}
}
[2]=>
array(7) {
["cont"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(377) "青岸渡寺(せいがんとじ)は、和歌山県東牟婁郡那智勝浦町にある天台宗の寺院。西国三十三所第一番札所。山号は那智山。本尊は如意輪観世音菩薩。 本堂および宝篋印塔は国の重要文化財。ユネスコの世界遺産『紀伊山地の霊場と参詣道』(2004年〈平成16年〉7月登録)の一部。"
}
["address"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(49) "和歌山県東牟婁郡那智勝浦町那智山8"
}
["thumb"]=>
array(2) {
["type"]=>
string(3) "uri"
["value"]=>
string(96) "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bb/Seigantoji01.JPG/200px-Seigantoji01.JPG"
}
["link"]=>
array(2) {
["type"]=>
string(3) "uri"
["value"]=>
string(49) "https://www2.ocn.ne.jp/~sanzan/NTTcontents/seigan/"
}
["d"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(18) "伝・裸形上人"
}
["name"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(12) "青岸渡寺"
}
["num"]=>
array(3) {
["type"]=>
string(7) "literal"
["xml:lang"]=>
string(2) "ja"
["value"]=>
string(31) "神仏霊場巡拝の道第2番"
}
}
}
}
}
[/php]
ここまでで必要なデータはPHPの中に取り込むことができました。
あとは取り込んだデータを表示させるだけです。
取得したデータを表示させる
【functions.phpに追加するコード】
[php]
//表示するHTMLを作成
function display_dbpedia(){
$dbcont = get_sparql_data();
$dbpedia_html = "<table>
<tr><td colspan=’2′>{$dbcont->results->bindings[0]->num->value}</td></tr>
<tr><td>名称</td><td>{$dbcont->results->bindings[0]->name->value}</td></tr>
<tr><td>画像</td><td><img src='{$dbcont->results->bindings[0]->thumb->value}’></td></tr>
<tr><td>住所</td><td>{$dbcont->results->bindings[0]->address->value}</td></tr>
<tr><td>説明</td><td>{$dbcont->results->bindings[0]->cont->value}</td></tr>
<tr><td>公式サイトURL</td><td><a href='{$dbcont->results->bindings[0]->link->value}’ target=’_blank’>{$dbcont->results->bindings[0]->link->value}</a></td></tr>
</table>";
return $dbpedia_html;
}
//the_contentに先ほどのHTMLをフックさせる
add_filter( ‘the_content’, ‘display_dbpedia’);
[/php]
今回はadd_filterを使用して、投稿の最後にDBpediaの情報を表示させるようにしました。
あとデータの取得方法をオブジェクト形式にしましたので、セレクタを使ってでデータを取得しています。
ちなみにclassを使ってsetter/getterを使えるようにすれば、「getThumbnail()」みたいにWordPressっぽい取得方法も可能です。
というかそっちの方が確実に楽だと思いますので、時間を見てそちらも試してみます。
というわけで、完成品
functions.phpに今回紹介したコードを記述することで、上の画像のようなコンテンツを追加することができました。
他のDBpediaの情報を取得されたい場合は、URIの書き換えとセレクタの書き換えでだいたい対応できます。
現在WordPressの投稿画面でどうにかする方法を模索中ですので、まとまり次第紹介します。
まとめ
・LODの扱い方はAPIと同じ
・JSONでとれるから、PHPで使いやすい様にごにょごにょしよう
・add_filter周りをいじればウィジェット・ショートコードでも扱える
そんなわけで、次回は「SPARQLでの検索方法」か「ウィジェット・ショートコードでの使い方」のどちらかを紹介したいと思います。
宣伝
9月20日のハッカソンは、WordBench大阪での開催です。
世話人という形で参加していますので、当日はよろしくお願いしますm(_ _)m