2.

PHP Facebook (Meta) Graph API 導入と投稿実装完全ガイド

編集
この記事の要点
  • 注意: Meta は公式 PHP SDK の Composer パッケージを 2020 年に廃止facebook/graph-sdkfacebook/php-graph-sdk も保守停止
  • 現代の正解: Guzzle で直接 Graph API REST 呼出 + 自前 OAuth 実装、またはJustCoded/php-graph-sdk のようなフォーク利用
  • Facebook ページ投稿の API は POST /{page-id}/feed、画像投稿は POST /{page-id}/photos
  • 認証は Page Access Token(長期トークンを推奨)
  • 個人プロフィールへの投稿はもうできない。Page または Instagram Graph API のみ
  • Webhook で他者からのリアクションをリアルタイム取得可

事前知識: SDK の現状(2026)

重要な経緯: Facebook (Meta) は 2010 年代に PHP SDK を公式提供していましたが、2020 年以降は更新が止まり、Composer の facebook/graph-sdk も廃止されました。現在の選択肢は:

選択肢状態推奨度
facebook/graph-sdk2018 で停止、廃止×
facebook/php-graph-sdk5.x で停止、廃止予告×
JustCoded / sammyjankis フォーク非公式継続△ 動くが自己責任
Guzzle で REST 直叩き常に動く◎ 最推奨
Laravel SocialiteOAuth ログインのみ○ ログインなら

Meta for Developers の準備

  1. developers.facebook.com でアプリ作成
  2. 「Facebook ログイン」プロダクト追加
  3. App ID / App Secret をメモ
  4. 投稿先 Facebook ページの管理者権限を確認
  5. Graph API Explorer で長期 Page Access Tokenを生成
  6. 必要な権限: pages_manage_posts / pages_read_engagement / pages_show_list
  7. 「アプリレビュー」を申請(本番公開時)

方式 A: Guzzle 直叩き(推奨)

composer require guzzlehttp/guzzle

テキスト投稿

<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;

$pageId = 'YOUR_PAGE_ID';
$pageAccessToken = 'EAAB...long-lived-token';

$client = new Client([
    'base_uri' => 'https://graph.facebook.com/v19.0/',
    'timeout'  => 30,
]);

try {
    $response = $client->post("{$pageId}/feed", [
        'form_params' => [
            'message'      => 'PHP からの投稿テスト',
            'access_token' => $pageAccessToken,
        ],
    ]);
    $body = json_decode((string) $response->getBody(), true);
    echo "投稿成功: post_id = " . $body['id'] . "\n";
} catch (\GuzzleHttp\Exception\ClientException $e) {
    $err = json_decode((string) $e->getResponse()->getBody(), true);
    echo "エラー: " . ($err['error']['message'] ?? '不明') . "\n";
}

画像投稿

<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;

$client = new Client(['base_uri' => 'https://graph.facebook.com/v19.0/']);

$response = $client->post("{$pageId}/photos", [
    'multipart' => [
        ['name' => 'access_token', 'contents' => $pageAccessToken],
        ['name' => 'caption',      'contents' => '今日のランチ'],
        ['name' => 'source',       'contents' => fopen('/path/to/image.jpg', 'r')],
    ],
]);

$body = json_decode((string) $response->getBody(), true);
echo "photo_id = " . $body['id'] . "\n";

// URL 指定での画像投稿(自前で download する代わりに Meta に取りに来てもらう)
$response = $client->post("{$pageId}/photos", [
    'form_params' => [
        'url'          => 'https://example.com/image.jpg',
        'caption'      => 'URL 指定投稿',
        'access_token' => $pageAccessToken,
    ],
]);

動画投稿

$response = $client->post("{$pageId}/videos", [
    'multipart' => [
        ['name' => 'access_token', 'contents' => $pageAccessToken],
        ['name' => 'description',  'contents' => 'プロモ動画'],
        ['name' => 'source',       'contents' => fopen('/path/promo.mp4', 'r')],
    ],
]);

予約投稿

$response = $client->post("{$pageId}/feed", [
    'form_params' => [
        'message'                 => '明日の朝に投稿',
        'published'               => 'false',           // 即時公開しない
        'scheduled_publish_time'  => time() + 86400,    // UNIX 時刻
        'access_token'            => $pageAccessToken,
    ],
]);

方式 B: 非公式フォーク SDK

# 非公式フォーク (例)
composer require espresso-dev/facebook-graph
# または
composer require justcoded/facebook-php-sdk
<?php
require 'vendor/autoload.php';
use Facebook\Facebook;  // フォークが提供する場合のみ

$fb = new Facebook([
    'app_id'                => 'YOUR_APP_ID',
    'app_secret'            => 'YOUR_APP_SECRET',
    'default_graph_version' => 'v19.0',
]);

try {
    $response = $fb->post("/{$pageId}/feed", [
        'message' => 'SDK 経由の投稿',
    ], $pageAccessToken);
    $node = $response->getGraphNode();
    echo $node['id'];
} catch (\Facebook\Exception\ResponseException $e) {
    echo $e->getMessage();
}

新規開発では非推奨。レガシ保守でのみ使用。

Page Access Token の発行

  1. Graph API Explorer を開く
  2. 右上のアプリを選択
  3. User Access Token 取得 → 権限 pages_manage_posts 等を選択
  4. 「Get Token」 → ユーザートークン発行
  5. GET /me/accounts でページごとの Page Access Token を取得
  6. Access Token Debugger長期化(60 日)に変換
  7. Page Access Token は Page を管理する限り無期限(仕様変更注意)

エラーハンドリング

code意味対処
190Access Token 失効再発行
200権限不足追加権限申請
368スパム判定投稿頻度を下げる
1487画像 URL 不正HTTPS / 公開 URL に
100パラメータ不正API リファレンス確認

Webhook 連携

投稿に対するいいね・コメントをリアルタイム受信:

// webhook.php
$secret = 'YOUR_APP_SECRET';
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '';

$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $signature)) {
    http_response_code(403); exit;
}

$event = json_decode($payload, true);
foreach ($event['entry'] as $entry) {
    foreach ($entry['changes'] as $change) {
        // feed / comments / reactions のイベント
        error_log(json_encode($change));
    }
}
http_response_code(200);

Instagram Graph API への展開

Facebook ページに接続された Instagram Business アカウントは、同じ Graph API で操作可能:

// 1. メディアコンテナ作成
$container = $client->post("{$igUserId}/media", [
    'form_params' => [
        'image_url' => 'https://example.com/photo.jpg',
        'caption'   => '#sunset',
        'access_token' => $pageAccessToken,
    ],
])->getBody();
$containerId = json_decode($container, true)['id'];

// 2. 公開
$client->post("{$igUserId}/media_publish", [
    'form_params' => [
        'creation_id'  => $containerId,
        'access_token' => $pageAccessToken,
    ],
]);

FAQ

Q: 個人プロフィールに投稿したい
A: 不可。Meta は 2018 年以降、個人アカウントへの API 投稿を全面禁止。Page か Instagram のみ。

Q: 公式 SDK が廃止されたが Facebook が SDK で書かれた例を載せている
A: 古いドキュメント。Meta 自身も「Graph API は HTTPS の REST なので任意の言語で直接呼べる」と推奨しています。

Q: トークンが頻繁に失効する
A: ユーザートークンを Page Access Token に変換せず使っている可能性。Page トークンは長期です。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. アプリケーションの登録のトークンの取得
  2. SDKの導入と投稿の実装(PHP)

最近更新/作成されたページ