2013年2月13日水曜日

PNGの透過を維持したままGIFに変換

PHPマニュアル通りにPNGからGIFを生成すると透過せずに黒く塗りつぶされる。
透過を指定しろと書いてるが、何指定したらいいかわからなかった。
透過を維持したまま画像を縮小させる関数(smart_resize_image)を作った人がいて、
このソースを見て参考にしたらできた。


header('Content-Type: image/gif');

$image = imagecreatefrompng($_GET['imgUrl']);

// Create a new transparent color for image
$color = imagecolorallocatealpha($image, 0, 0, 0, 127);

// Completely fill the background of the new image with allocated color.
imagecolortransparent($image, $color);

imagegif($image);
imagedestroy($image);


pngの透過で指定されている値をそのままGIF生成前に教えてあげればいいだけ。α値を忘れずに指定しよう。PHPマニュアルにはないから困ったほんと。
このスクリプトはGETパラメータとして受け取ったPNG画像のURLをそのままGIF画像として出力しているだけ。
ちなみにPOSTでパラメータ送ると、I.E.、FireFoxで画像を保存をできない。両者は画像保存時にもう一回、URLを参照して画像を取りに行くから。もう一度POSTデータを送信してくれてるわけじゃないらしいから、画像を作れず壊れます。GETでURLをユニークしちゃえば何度でも生成できる。

2012年4月25日水曜日

文字を配列化

文字列を区切って配列化と言えば、どの言語もsplitを思い出すもんだけど。。。
phpでは、非推奨になったっぽい。
explodeを使いましょう

$data =explode(',','test1,test2,test3,test4');

implodeもセットにして覚えておこう。
こちらは配列をセパレータで1つの文字列にする。
$data=implode(',',array(hoge1,hoge2,hoge3));

2012年4月24日火曜日

HTTP通信

PHPで他のサーバーとHTTP通信してみます。
いろいろあるけど、一番簡単なのは、 "file_get_contents"を使ったやり方じゃないかな。


○HTTP通信結果をHTTPの結果らしく出力する。(POST方式)


$url = 'http://www.google.co.jp/ig';

//POSTデータ
$data = array(
    "name1" => "value3",
    "name2" => "value2",
    "name3" => "value3"
);
$data = http_build_query($data, "&");

//Request Header
$header = array(
    "Content-Type: application/x-www-form-urlencoded",
    "Content-Length: ".strlen($data)
);
$header = implode("\r\n", $header);


//context生成
$context = array(
    "http" => array(
        "method"  => "POST",
        "header"  => $header,
        "content" => $data
    )
);
//送信、戻り値はレスポンスのデータ部
$out = file_get_contents($url, false, stream_context_create($context));

//レスポンスヘッダーを出力
foreach ($http_response_header as $header){
  echo($header . '<br/>');
}
echo('<br/>');
//レスポンスデータ部をエスケープして出力
echo(htmlspecialchars($out));



・リクエスト
ヘッダーにContent-Lengthを記述するので、データ部から先に生成しています。
(Content-Length書かなかったらHTTPステータス411(Length Required)で返すサーバーのほうがほとんどじゃないかな。)


・レスポンス
file_get_contentsでHTTP通信すると、レスポンスヘッダーは、$http_response_headerから取得できる。
昔の言語っぽいよね。
先に関数作っちゃったから、仕方なかったのかも?






○HTTP通信結果をHTTPの結果らしく出力する。(GET方式)


$url = 'http://www.google.co.jp/';

//GETデータ
$data = array(
    "name1" => "value3",
    "name2" => "value2",
    "name3" => "value3"
);
$data = http_build_query($data, "&");

//Request Header
$header = array(
    "Content-Type: application/x-www-form-urlencoded",
);
$header = implode("\r\n", $header);


//context生成
$context = array(
    "http" => array(
        "method"  => "GET",
        "header"  => $header,
    )
);
//送信、戻り値はレスポンスのデータ部
$out = file_get_contents($url . '?' . $data , false, stream_context_create($context));

//レスポンスヘッダーを出力
foreach ($http_response_header as $header){
  echo($header . '<br/>');
}
echo('<br/>');
//レスポンスデータ部をエスケープして出力
echo(htmlspecialchars($out));


・リクエスト
POSTより簡素。
データは、クェリ文字列として渡すこと。(※URLの末尾に?をつけてデータをつける。)
大事なのは「不要な物を入れない」こと。
例えば、GETなのにHTTPデータ部が入っているとHTTPステータス400(Bad Request)で返すサーバーもある。

・レスポンス
 POST形式と別に何も変わらない。



2012年4月11日水曜日

HTTPのボティ部をそのまま表示

HTTTPボディ部の生データを取得したいときに使えます。





$post = fopen("php://input", "r");
$data = stream_get_contents($post);
echo($data);
fclose($post);



ただし enctype="multipart/form-data"(すなわちアップロード方式)の場合は無効です。


"php://"は、様々な入出力ストリームに対応しています。勉強していると便利ですね。

※参考文献
PHP: php:// - Manual