動的に生成されるURLに対して固有のOGPを生成する方法メモ

http://hoge.com/#1000 みたいな、ハッシュ以下の値に対してコンテンツを書き換えるサイトで、それぞれのハッシュに応じて異なるOpen Graph Protocol(OGP)を吐き出したい時の対処法。

フェイスブック、ミクシィ、グリーで使われている OGP (Open Graph Protocol) とは何か
http://d.hatena.ne.jp/amachang/20110117/1295233078

1. まず同一ドメイン内に、OGP吐き出し用のPHPを用意する。

ex) http://hoge.com/share.php

2. 元のhtmlと同一のハッシュを受け取ってその値に応じたOGPを吐くようにする。

ex) http://hoge.com/share.php?id=1000

3. html内に設置したShareボタン、Likeボタンの対象URLを上記のshare.phpにする。

 <div data-href="http://hoge.com/share.php?id=1000" data-send=false data-layout="button_count" data-width=450 data-show-faces=false></div>

4. このままだとウォールにshare.phpのURLが投稿されてしまい、ウォールからアクセスしたユーザーがshare.phpに飛んでしまうので、share.php内でfacebookのクローラー以外を元のhtmlにリダイレクトする。
facebookのクローラーはUserAgant内の“facebookexternalhit”の有無で判定する。

Best Practices – Facebook開発者
http://developers.facebook.com/docs/best-practices/

5. 以下share.phpの概要

<?php
$id = $_GET["id"];
$ua = $_SERVER['HTTP_USER_AGENT'];
 
//facebook crowlerじゃなかったらリダイレクト
if (!preg_match('/facebookexternalhit/i', $ua))
{
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: http://hoge.com/#" . $id);
    exit;
}
 
//idに応じて情報を取得する
$api = "http://hoge.com/api?id=" . $id;
$json = file_get_contents($api);
$user_data = json_decode($json);
$username = htmlspecialchars($user_data->result->username);
$img_path = htmlspecialchars($user_data->result->img_path);
 
?><!DOCTYPE html> 
<html lang="en" xmlns:og="http://ogp.me/ns#"> 
    <head>
        <meta charset="utf-8"> 
        <meta property="og:title" content="<?=$username?>'s page">
        <meta property="og:description" content="SITE DESCRIPTION">
        <meta property="og:url" content="http://hoge.com/#<?=$id?>">
        <meta property="og:image" content="<?=$img_path?>">
        <link rel="image_src" href="<?=$img_path?>">
        <title><?=$username?>'s page</title>
    </head>
    <body>
        <script type="text/javascript">location.replace("http://hoge.com/#<?=$id?>");</script>
    </body>
</html>