記事一覧はこちら

phpのCURLOPT_POSTFIELDSで@から始まるテキストを送信する方法

phpcurlでファイルとメッセージをpostしたい場合

$post["file"]="ほげほげ";
$post["file"]="@./upload.png";
$curl = curl_init("http://example.com/");
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS,$post);
$result = curl_exec($curl);

こんな感じで簡単にファイルupload.pngとメッセージほげほげをpost出来ますが、メッセージが@user ほげほげ の様に@から始まると、それをファイル名として認識し、開けないよ とエラーが出てしまいます。
解決策としてはCURLOPT_POSTFIELDSに配列ではなく文字列を直接指定する必要があるのですが、Content-Typeリクエストヘッダとバイナリデータとテキストデータを混ぜて送信する書式が決まっているので、それを作る関数を作りました。

@の変わりとなるprefixを指定する必要があるので、md5(microtime().rand());で作ってやります。

$prefix=md5(microtime().rand());
$post["file"]="ほげほげ";
$post["file"]=$prefix."./upload.png";
$post2=post2($post,$prefix);

これで$post2にヘッダーとボディが入るので

$curl = curl_init("http://example.com/");
curl_setopt($curl, CURLOPT_HTTPHEADER,array($post2["header"]));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS,$post2["post"]);
$result = curl_exec($curl);

指定して、送信。これで先頭が@で始まる文字も無事post出来ました。
しかしこれphpの仕様ミスだと思うんだけど、本来@から始まる文字とバイナリファイルを multipart/form-dataで送信する時はどうすべきなんだろう。自分で作れって事なのかな。自分で作ったけど。

参考にしました
Cocoaを使ってmultipartでテキスト、ファイル、他なんかいろいろ送信する - +8
これに使いました
PHP + Twitpic API v2 で、ファイルをアップロード