PHP

おてがるにOGPのチェッカーを作る

ちょうど先週に書いたばっかりなので。Facebook Sharing DebuggerはWebに公開済みのコンテンツしかチェックできないので困る。

異常に雑なWebアプリを作るのにPHPで秒殺できるのはよいですヾ(〃><)ノ゙ といふかoscarotero/Embed: Get info from any web service or pageを使ってるだけ。

手順

  1. 適当な場所を用意する
    • パブリックな場所でやると、踏み台にされて面倒なのでクローズドな場所でやるといいよ
    • 僕はビルトインサーバーが好きなので、それでやります
  2. Composerを入れる
  3. Composerでembed/embedを入れる
    • 独立したリポジトリでやるときはcomposer require embed/embedです
    • 今回は一時的な利用なので僕はcomposer g require embed/embedしました (本格的に運用するならおすすめしません)
  4. コードを置く (checker.phpを下の方に用意しました)
  5. ビルトインサーバーを起動する
    • php -S 0.0.0.0:3939 checker.php

コード

checker.php
<?php

// composer global require した場合
require getenv('HOME') . '/.composer/vendor/autoload.php';
// composer require した場合
// require __DIR__ . '/../vendor/autoload.php';

use Embed\Embed;

if (isset($_GET['src'])) {
    header('Content-Type: text/plain');
    readfile(__FILE__ );
    return;
}

?>
<title>OGP Checker</title>
<meta name=”robots” content=”noindex”>
<form method="get">
    <input name="url" value="<?= h((string)($_GET['url'] ?? '')) ?>"></input>
    <button type="submit">submit</button>
</form>
<?php
if (empty($_GET['url']) || !is_string($_GET['url'] ?? '')) {
    return;
}

?>
<hr>
<?php
$info = Embed::create($_GET['url']);

$data = [
    'title' => $info->title,
    'description' => $info->description,
    'url' => $info->url,
    'type' => $info->type,
    'tags' => $info->tags,

    'images' => $info->images,
    'image' => $info->image,
    'imageWidth' => $info->imageWidth,
    'imageHeight' => $info->imageHeight,

    'code' => $info->code,
    'width' => $info->width,
    'height' => $info->height,
    'aspectRatio' => $info->aspectRatio,

    'authorName' => $info->authorName,
    'authorUrl' => $info->authorUrl,

    'providerName' => $info->providerName,
    'providerUrl' => $info->providerUrl,
    'providerIcons' => $info->providerIcons,
    'providerIcon' => $info->providerIcon,

    'publishedDate' => $info->publishedDate,
    'license' => $info->license,
    'linkedData' => $info->linkedData,
    'feeds' => $info->feeds,
];

?>
<details><summary>raw (展開)</summary>
    <pre><?= htmlspecialchars(json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), ENT_QUOTES, 'UTF-8') ?></pre>
</details>

<table border>
    <?php display($data); ?>
</table>

<?php
function h(string $s)
{
    return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}

function display(array $data)
{
    foreach ($data as $k => $v): ?>
    <tr><th><?= h($k) ?></th><td>
        <?php if (is_array($v)): ?>
            <table border>
                 <?php display($v); ?>
            </table>
<?php elseif ($k === 'url' && isset($data['mime']) && strpos($data['mime'], 'image/') === 0): ?>
            <img src="<?= h($v) ?>">
        <?php else: ?>
            <?= h(var_export($v, 1)) ?>
        <?php endif; ?>
        </td>
    <?php endforeach;
}

表示

まあ最低限の用は足りてるんじゃないですかね。READMEに書いてある項目を雑に出してるだけなので、もっと情報はとれるのかも。

image.png

あとは見やすくなるよう、各自よしなに。