PHPからData APIでアイテムをアップロードする

MTQに、「PHPからData APIでアイテムをアップロードする方法が知りたい」といった質問がありました。
この質問に答えます。

1.考え方

Data APIでアイテムをアップロードする場合、HTTPのPOSTプロトコルでのアップロードの手順に従って、サーバーにデータを送信します。
POSTするデータを、multipart/form-dataの形式にした上で、サーバーに送信します。

PHPでサーバーと通信する方法はいくつかありますが、file_get_contents関数とstream_context_create関数を使うのが比較的簡単です。

2.Data APIへのログイン

Data APIでアイテムをアップロードするには、まずData APIにログインすることが必要です。
PHPでログインする手順は、こちらの記事をご参照ください。
この記事の「事例」の箇所の32行目までが、ログインの処理です。

3.アイテムのアップロード

Data APIにログインしたら、Data APIに対してファイルをアップロードします。
ログイン以降の処理を書くと、以下のようになります。

// アップロードの際のパラメータ
$filename = 'ファイル名';
$filepath = 'ファイルがあるディレクトリ';
$path = 'アップロード先ディレクトリ';
$mimetype = 'ファイルのMIMEタイプ';
$autoRenameIfExists = 1;
$normalizeOrientation = 1;

// 画像の読み込み
if (!preg_match('/\/$/', $filepath)) {
    $filepath .= '/';
}
$file = file_get_contents($filepath . $filename);

// 送信データの作成
$eol = "\r\n";
$postdata = '';
$boundary = substr(md5(rand(0,32000)), 0, 10);
$postdata .= '--' . $boundary . $eol;
$postdata .= 'Content-Disposition: form-data; name="path"' . $eol . $eol . $path . $eol;
$postdata .= '--' . $boundary . $eol;
$postdata .= 'Content-Disposition: form-data; name="autoRenameIfExists"' . $eol . $eol . $autoRenameIfExists . $eol;
$postdata .= '--' . $boundary . $eol;
$postdata .= 'Content-Disposition: form-data; name="normalizeOrientation"' . $eol . $eol . $normalizeOrientation . $eol;
$postdata .= '--' . $boundary . $eol;
$postdata .= 'Content-Disposition: form-data; name="file"; filename="' . $filename . '"' . $eol;
$postdata .= 'Content-Type: ' . $mimetype . $eol;
$postdata .= 'Content-Transfer-Encoding: binary' . $eol . $eol;
$postdata .= $file . $eol;
$postdata .= '--' . $boundary . '--' . $eol . $eol;

// アイテムのアップロード
$endpoint = 'http://your-host/path-to-mt/mt-data-api.cgi/v1/sites/サイトID/assets/upload';
$options = array('http' =>
  array(
    'method' => 'POST',
    'header' => array(
      'X-MT-Authorization: MTAuth accessToken=' . $accessToken,
      'Content-Type: multipart/form-data; boundary=' . $boundary
    ),
    'content' => $postdata,
  )
);
$response = file_get_contents($endpoint, false, stream_context_create($options));
if (!$response) {
  echo "アイテムのアップロードに失敗しました。";
  var_dump($http_response_header);
  exit();
}
else {
  アップロードに成功した時の処理
}

先頭の「アップロードの際のパラメータ」の部分(2~7行目)は、ご自分の状況に応じて書き換えます。
それぞれの意味は以下の通りです。

パラメータ内容
$filenameアップロードするファイルの名前を指定します。
$filepathアップロードするファイルがあるディレクトリを指定します。
$pathアップロード先のディレクトリを指定します。
アップロード先のブログ(またはウェブサイト)のルートを基点とした相対パスで指定します。
$mimetypeアップロードするファイルのMIMEタイプ(image/jpegなど)を指定します。
$autoRenameIfExists同名のファイルがすでにあるときにファイル名を自動的に変更するかどうかを表します。
1を指定すると、ファイル名を変更してアップロードします。
0を指定すると、同名のファイルがすでにあるときにはアップロードがエラー(HTTPの409エラー)になります。
$normalizeOrientation」画像のExif情報から縦横を判別して、適切に回転するかどうかを表します。
1なら回転し、0なら回転しません。

また、33行目の「your-host」と「path-to-mt」は、ご自分のMovable Typeの環境に合わせて書き換えます。
「サイトID」は、アップロード先のブログ(またはウェブサイト)のIDに書き換えます。