仕上がりイメージ
仕上がりイメージはこんな感じです。ボタンの中に各SNSのシェア数が表示されています。Pocketに関してはオリジナルデザインでシェア数の取得が認められていないため、表示していません。
設置方法
基本的には以前に書いた「SNSボタンをオリジナルデザインに!設置方法&シェア数の取得方法まとめ」と流れは全く一緒です。ざっとこの3つの流れでシェア数を取得しています。
- 最初にページのURLを取得し、変数に格納
- 各SNSのシェア数を取得して、変数に格納
- 表示したい箇所で各SNSシェア数が格納された変数を呼び出し、表示
キモはページのURL(パーマリンク)を取得して変数に格納するところですかね。
WordPressでは何かを表示させるには「the_()」という書き方をしますが、値を取得するだけであれば「get_the_()」と書きます。ですが、このget_*()という書き方はセキュリティに影響を及ぼす場合があるらしく、使い方に注意が必要とのことです。
パーマリンクを変数に入れる方法としては、以下の記事で紹介されていたやり方を参考にさせていただきました!Firegobyさんありがとうございます!
また、the_()とget_the_()の違いについては、Ateitexe アテークゼさんの記事が大変勉強になりますので、気になる方はぜひ読んでみてください!
【2015年6月11日 追記】file_get_contents()の使い方に注意しよう
重要なことでしたので追記します。こちらの内容はコメントにて教えていただきました。教えていただかなかったら全く知らない事実でした…本当にありがとうございます!
file_get_contents()は「allow_url_fopen =off」のサーバー環境では動いてくれない
APIを取得する際に使用しているfile_get_contents()というPHPの関数には注意が必要です。まず、その関数が動かない環境があるということ。file_get_contents()を使うにはサーバーの「allow_url_fopen」の設定をONにする必要があります。もし設定がOFFになっている場合はfile_get_contents()が使えません!
ONにする方法としては以下の記事がわかりやすくまとめてくれていましたので、offだった方は参考にどうぞ!
データの取得に失敗するとWarningエラーが出てセキュリティに影響を及ぼす可能性がある
また、URLが存在しなかったなどの理由でfile_get_contents()関数でのデータの取得に失敗してしまうと、場合によってはWarningエラーが出てしまい、そうなるとサーバーの情報なども表示されてしまうそうです。自分のサーバー環境ではWarningの表示は確認できなかったのですが、もしサーバーの情報が出てしまった場合これは怖いですよね。
Warningエラー自体は、file_get_contents()の前に@をつけてあげれば消すことができるのですが、もしURLの取得に失敗した場合の処理を以下のように分岐させて書いておく必要があります。
※失敗した時に表示する内容はNO DATAでも何でも構いません。
※なお、はてなブックマークについてはエラー(URLが存在しない場合)でも、ブックマークがひとつもついていない場合でも、いずれも空の値を返すようなので、私はどちらの場合も0の数字が表示されるようにしています。
<?php $url = "取得したいURL"; //JSONデータを取得 //URLの存在の有無に応じて処理を分岐する if ($json = @file_get_contents('http://urls.api.twitter.com/1/urls/count.json?url=' . $url . '')) { //JSONデータを連想配列に直す $array = json_decode($json,true); //$twitter_countという変数に格納 $twitter_count = $array['count']; }else{ //もしURLの取得に失敗したら「NO DATA」を表示 $twitter_count = "NO DATA"; } ?>
file_get_contents関数でWarningエラーが起きてしまった時の対処方法は以下の記事に詳しく書いてくださっています!もう少し詳しく知りたい方はこちらをどうぞ!
【2015年10月2日 追記】ツイート数を取得する「count.json」が提供終了
なんと、ツイート数を取得するために利用していた「count.json」の提供が終了してしまったようなので、この記事に記載してあるTwitterのカウント数取得のコードは使えません…。
何か代替の方法がわかりましたら追記します!詳しくは以下の記事が参考になります。
Twitter:ツイート数取得API「count.json」提供終了のお知らせ
【2016年8月28日 追記】Facebookの仕様変更のためソースを一部変更
Facebookが仕様変更をしたため、従来の方法ではカウント数の取得ができなくなってしまったので、ソースコードを一部変更しました。
以上のことをふまえ、いよいよsingle.phpに記載していきます。以下がソースコードです。
single.php
<?php //-------------------------------------------------- //ページのURLを取得・変数に格納 //-------------------------------------------------- $url = esc_url( apply_filters( 'the_permalink', get_permalink() ) ); //-------------------------------------------------- //SNSシェア数を取得・変数に格納 //-------------------------------------------------- // Facebook ------------------------- //JSONデータを取得 //URLの存在の有無に応じて処理を分岐する if ($json = @file_get_contents('http://graph.facebook.com/?id=' . $url . '')) { //JSONデータを連想配列に直す $array = json_decode($json); //配列の中の「share_count」をfb_countという変数に格納 $fb_count = $array -> share -> share_count; //データが存在しない場合は0を返す if(!isset($fb_count)){ $count = 0; }else{ $count = $fb_count; } //$facebook_countという変数に格納 $facebook_count = $count; }else{ //もしURLの取得に失敗したら「NO DATA」を表示 $facebook_count = "NO DATA"; } // Google+ ------------------------- // 公式の+1ボタンからカウント数だけ取得 //URLの存在の有無に応じて処理を分岐する function getGooglePlusCount( $url ) { if ($plus = @file_get_contents( 'https://apis.google.com/_/+1/fastbutton?url=' . urlencode( $url ) )) { // 正規表現でカウント数のみを抽出 preg_match( '/\[2,([0-9.]+),\[/', $plus, $count ); return $count[1]; }else{ //もしURLの取得に失敗したら「NO DATA」を表示 $count = "NO DATA"; return $count; } } $count = getGooglePlusCount( $url ); //$gplus_countという変数に格納 $gplus_count = $count; // hatena ------------------------- //APIではてブ数を取得 //URLの存在の有無に応じて処理を分岐する if ($count = @file_get_contents('http://api.b.st-hatena.com/entry.count?url=' . $url . '')) { //カウントが0の場合 if(!isset($count) || !$count){ $count = 0; } //$hatena_countという変数に格納 $hatena_count = $count; }else{ //もしURLの取得に失敗したら「0」を表示 $hatena_count = 0; } ?> <!-- オリジナルボタンのところでSNSシェア数を出力 --> <ul id="share"> <li class="twitter"><a href="http://twitter.com/share?url=<?php the_permalink(); ?>&text=<?php the_title(); ?>" target="_blank"><span>Tweets</span></a></li> <li class="facebook"><a href="http://www.facebook.com/share.php?u=<?php the_permalink(); ?>" onclick="window.open(this.href, 'FBwindow', 'width=650, height=450, menubar=no, toolbar=no, scrollbars=yes'); return false;"><span><?php echo $facebook_count; ?></span></a></li> <li class="gplus"><a href="https://plus.google.com/share?url=<?php the_permalink(); ?>" onclick="window.open(this.href, 'Gwindow', 'width=650, height=450, menubar=no, toolbar=no, scrollbars=yes'); return false;"><span><?php echo $gplus_count; ?></span></a></li> <li class="hatebu"><a href="http://b.hatena.ne.jp/entry/<?php the_permalink(); ?>" class="hatena-bookmark-button" data-hatena-bookmark-layout="simple" title="<?php the_title(); ?>"><script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script><span><?php echo $hatena_count; ?></span></a></li> </ul>
所定の位置にちゃんとシェア数が表示されれば、成功です!
本当はシェア数取得の部分はfunctions.phpにまとめてしまったほうがいいのかもしれないですが、私は全部single.phpに取得〜表示までのソースを記述しています。ソースの見通しが悪くなるし、パフォーマンス的にもどうなんだろう…と悩んでいますが、ひとまずはこの方法で様子を見ようと思います。何か、いい方法があれば教えていただければ助かります!
なお、各SNSのシェア数取得の方法は以下の2サイト様の記事を参考にしています。詳しく知りたい方はそちらをご参照ください。
また、通常のPHPファイルでオリジナルSNSボタンを設置するには以前に書いた記事をご参照ください。
SNSボタンをオリジナルデザインに!設置方法&シェア数の取得方法まとめ | Design Color
以前に書いた記事
ここで紹介されている方法でうまくいかない方は、SNSのシェア数を表示してくれる「SNS Count Cache」というWordpressのプラグインがあるらしいので、そちらを使ってみてもいいかもしれませんね。以下の記事に実装方法が紹介されています。
さいごに
WordPressでオリジナルのSNSボタンを設置したい、という意見がありましたので、遅ればせながら書いてみました。この記事がどなたかのお役に立てれば幸いです。
以上、彩がお伝えしました!
コメント
コメント一覧 (4件)
サーバー側でallow_url_fopenが無効になっている場合はfile_get_contentsは利用できないと思われます。
代替え案としてはcUrlを利用することだろうと思います。
また、@file_get…は失敗した時にワーニングが出ませんでしたっけ?
ワーニングが出ると、まぁどこでもだいたい同じ構造ではあるとは思いますが、色々とサーバーの中身がわかってしまったりしてよろしくないかも知れませんね。
予め、if ($json = @file_get…($url))で条件分岐して、参照先が無い時どうするかを処理するともっと良いかも知れません。
通りすがりさん
記事を読んでいただき&ご指摘ありがとうございます!
恥ずかしながらプログラムについての知識が浅く、
教えていただかなかったら全く知らない事実でした><
セキュリティの影響は怖いですよね…。教えていただいて本当に助かりました!
教えていただいた内容を記事に追記させていただきました!
ついでに、
function file_cget_contents($address){
$ch = curl_init(); // 初期化
curl_setopt( $ch, CURLOPT_URL, $address ); // URLの設定
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // 出力内容を受け取る設定
$result = curl_exec( $ch ); // データの取得
curl_close($ch); // cURLのクローズ
return $result;
}
これでfile_get_contentsが機能しないサーバーでもcUrlで同じようなことができます。cUrlが機能してないとダメですけどね。たいてい動作していると思うんですが、ここは何とも…。
また、if文でパーマリンクのアドレス入れて各apiからデータを拾ってくる部分ですが、何かしら関数を作ってデータを取得する部分として1つ、取得したデータを処理する部分で1つというように行うことを分離するほうが管理がしやすくなると思います。
file_get_contents部分は共通で、違うのは中身(url)ですから、urlを処理する部分と言うのも作ると良いかも知れません。
そうするとapiのデータ取得方法が変わった場合など、アドレス部分だけを直せば良いとか、データの処理だけ直せば良いなどとメンテナンス性が上がると思います。
それぞれ以下のような感じで分けて処理しておき、各SNSの表示部分を最終的に総合表示としてまとめるとコンパクトにもなると思います。
・apiに送るアドレスの整形
・apiのレスポンスを取得する部分
・取得したデータの処理部分
・表示部分
具体的には、
//アドレスの処理
function readyUrl($sns,$url){
switch($sns){
case “tt”: $address = //twitterのアドレスの処理; break
case “gp”: $address = //Google+のアドレスの処理; break
default: //例えば何も処理しないものとかでurlencodeだけがいるとか;
}
return $address;
}
//apiのレスポンス
function apiResponse($url){
//file_get_contents等を利用したデータの取得
}
//データ整形(表示もここに混ぜてもいいかも)
function datamaking($sns,$data){
switch($sns){
case “tt”: $count = //twitterのカウント; break;
}
return $count;
}
$url = esc_url( apply_filters( ‘the_permalink’, get_permalink() ) );
//twitterの時
$twitterUrl = readyUrl(“tt”,$url);
$twitterData = apiResponse($twitterUrl);
$twitterCount = datamaking(“tt”, $twitterData);
//facebookの時
$facebookUrl = readyUrl(“fb”,$url);
$facebookData = apiResponse($facebookUrl);
$facebookCount = datamaking(“fb”, $facebookData);
みたいな感じでしょうか?
まぁ色々しないといけませんけれども、こういう流れとかどうですか?
twitterの時などと書いてありますが、ここも例えば連想配列にしてforeachでまわしたら1発で書けそうです。
foreachで[sns名 => url, …]の配列を回して[ “tt” => count, “fb” => count, … ]が作れれば、表示する部分で$count[“tt”]などとして利用できるんじゃなかろうかと思ったり。
そうする場合は、readyUrlの部分で一発で配列も作れそうですね。
curl_multi(http://techblog.yahoo.co.jp/architecture/api1_curl_multi/)をうまく利用できれば並列でデータを取得できるかも知れません。
通りすがりさん
コメントありがとうございます?!
おおお・・・!今回のは結構難しそうですね><
そうか、メンテナンス性を考えるとデータの取得と処理は分けたほうがいいんですね。
効率よくコードを書くならループを駆使するのか?。なるほど!
今回はいったん自分で勉強してからでないと書けなそうなので、
すぐには追記できないかもしれないですが、
効率のいいソースコードを目指して時間がかかっても頑張ってみますねーo(^-^)o
教えていただいた方法で実装することができたら、また記事に追記させていただきます!
本当に丁寧に教えていただいてありがとうございます?!