2010年12月30日木曜日

[php]ファイルをテンポラリなパスでダウンロードさせる

publicでない場所に置いてあるファイルを、ランダムなパスで一時的にダウンロードできるようにする。

というのを作りました。

ちょうど今zencartをいじっていて、ダウンロード販売機能のソースコードを参考にさせて(というかほぼそのまま使わせて)もらいました。
該当のソースコードは以下のパスにあります。
includes/modules/pages/download/header_php.php

プログラムの流れは

1.ユーザーがphpにアクセス
2.ランダムで一時ディレクトリを作成
3.作成した一時ディレクトリの中にオリジナルファイルへのシンボリックリンクを作成。
4.ユーザーをシンボリックリンクへ303リダイレクト
5.ユーザーが目的のファイルを閲覧する

となります。

それと、作成したディレクトリを定期的に削除することで、ファイルが一般に公開されてしまうことを防ぎます。

zencartではphpにアクセスがあるたびに過去に作成した一時ディレクトリを削除していますが、必要ならばcronで定期的に削除するなどの処理を組み込んでもいいと思います。

ソースはこんな感じになります。


//古いシンボリックリンクを削除
zen_unlink_temp_dir(DIR_FS_DOWNLOAD_PUBLIC);

//ディレクトリ作成
$tempdir = zen_random_name();
umask(0000);
mkdir(DIR_FS_DOWNLOAD_PUBLIC . $tempdir, 0777);

$symlink_file = DIR_FS_DOWNLOAD_PUBLIC . $tempdir . '/' . $file_name;
$redirect_link = "/pub/" . $tempdir . '/' . $file_name;

//シンボリックリンク作成
$link_create_status = @symlink($org_file, $symlink_file);

//リダイレクト
if ($link_create_status==true) {
header("HTTP/1.1 303 See Other");
header("Location: ".$redirect_link);
}

2010年12月21日火曜日

phpのrequireとincludeの違い

ファイルを読み込むこの2つのメソッド。どちらも同じような動きをします。

自分はrequire派です。なんとなくincludeよりrequireのほうが上等というか、レベルが高い印象があったので、requireを使ってました。

今回とあるサンプルコードを読んでいたらincludeが使われており、気になって調べてみましたが、答えはphpマニュアルに書いてありました。

require() は include() とほぼ同じですが、失敗した場合に E_COMPILE_ERROR レベルの致命的なエラーも発生するという点が異なります。 つまり、スクリプトの処理がそこで止まってしまうということです。一方 include() の場合は、警告 (E_WARNING) を発するもののスクリプトの処理は続行します。


http://phpspot.net/php/man/php/function.require.html

とのことです。なるほど。

ちなみにrequire_once、include_onceというのもあって、こちらだとすでにそのファイルが読み込まれている場合はスキップしてくれます。

便利です。が、_onceありは_onceなしに比べて処理が重くなるという話をどこかで読んだことがあります。(当然と言えば当然ですが)

特に理由がないようならrequireを使っておくのが無難なようです。

2010年12月20日月曜日

jqueryのhover()でプルダウンメニューを作る

仕事でプルダウンメニューを作った際のメモ。

jqueryを使ってちょっとしたプルダウンメニューを作りました。

サンプル:jqueryのhoverでプルダウンメニュー

最初は

$('#menu').mouseover(function(){ ...処理... }).mouseout(function(){ ...処理... });

という具合に、mouseoverとmouseoutのメソッドチェーンを使ってみました。

これでも問題ないように見えましたが、実際に作ってみるとカーソルをメニュー要素からプルダウン要素に動かすと、その都度mouseoverの処理が走ってしまうということがわかりました。

ただのプルダウンメニューであれば問題ないかもしれませんが、メニューの表示にajaxでのHTTPリクエストを入れていたので、パフォーマンスの点で問題があります。というか使いものになりません。
サンプルにconsole.logを仕込んであるので、実際にマウスを動かしながらfirebugのコンソールを見ると現象がよくわかると思います。

そこで今度はhoverメソッドを使ってみたのですが、こちらはカーソルをグリグリ動かしても処理は1度しか走りませんでした。

挙動が違う理由はよくわかりませんが、とりあえずhoverを採用して無事実装完了しました。

2010年12月18日土曜日

session.use_trans_sidがOnだと、別ドメインへのformでもhiddenにセッション 情報を埋め込んでしまう

session.use_trans_sidをOnにしているサイトで、formのaction先が別ドメインのサイトなのにも関わらず、hiddenにセッションIDを付加してしまう、という問題に遭遇しました。

session.use_trans_sidは外部ドメインへのformタグにも無差別に付加する

けっこう面倒な問題。セキュリティ的にもかなりマズイです。

上記のページではurl_rewriter.tagsを使った解決策をとっていますが、今回はjqueryのremove()でhiddenタグを削除するという方法を考えてみました。

$('#form1 input:hidden[name=session_name]').remove();

当然携帯サイトなどでは使えませんが、javascriptがOffだと送信できないフォームなので、この方法を使ってみました。

2010年12月16日木曜日

秀丸のzen-codingマクロでhtmlコーディングをちょっとだけ効率化

最近話題のzen-coding、自分も秀丸にマクロ入れて使っています。

秀丸のzen-codingマクロ

普段からできる限りzen-codingを使おうとしてはいるのですが、なかなか使いこなすことができません。

実際に使おうと思っても、記法が分からない時はリファレンスサイトを見に行かなくてはいけないので、そうなると「普通に手入力でいいや」となってしまいます。

あと、ゼロからhtmlでページを作る機会があまり多くないのも原因のような気がします。
部分修正の時にも使いたいのですが、インデントが崩れてしまったりするので、ちょっと使いにくい感じがします。


そこで設定ファイルをいじって、自分なりのzen-codingの使い方を考えてみました。


設定方法はzenhtml.iniのuse-indentをyesからnoにするだけ。

たとえばこんな文字列があったとします。

君は見たか愛が真っ赤に燃えるのを

「真っ赤」を<span>で囲み、class属性にredを指定したい場合、

「真っ赤」を選択してCtrl+Shift+EでWrapモードを呼び出し、「span.red」を入力してOKします。



すると

君は見たか愛が<span class="red">真っ赤</span>に燃えるのを

こうなります。

ちなみにuse-indentがyesだと、こんな風にインデントが入ってしまいます。

君は見たか愛が<span class="red">
    真っ赤</span>に燃えるのを


zen-codingの本来の使い方からすると少しズレてるのかもしれませんが、最近のコーディングはclassとかidを指定することが多いので、かなり役立ってます。

次のバージョンアップで、Wrapモードの時はインデントをオフにする、みたいな設定ができるようになると嬉しいですね。

2010年12月14日火曜日

phpで関数の頭に@(アットマーク)の意味

phpで、関数名の前に@がついてるのをたまに見かけます。

たとえば

@file($filename);

とか

@file_get_contents($url);

など。

これはエラー制御演算子といって、エラーログの出力を抑制するためのものなんだそうです。
上記の例では、ファイルが存在しなかったり、エラーを吐かないようになります。

なお関数だけじゃなく、変数などでも使えるようです。

基本的にはerror_reporting等でエラー出力の設定をして、部分的な対応のみこのエラー制御演算子を使う、というやり方になるようです。

2010年12月10日金曜日

jqueryでフロートメニューを自作する

以前、フロートメニューを作る際に「jquery-scroll-follow」というjqueryのプラグインを使ったことがあったんですが、今回新たに調べてみたところ、最新版のjqueryでは動作しないことがわかりました。

「jquery-scroll-follow」は2008年からバージョンが更新されていません。
フロートメニュー自体あまり人気もないし、今後も更新されなさそうな感じなので、自作してみることにしました。

サンプル:jqueryでフロートメニュー

拍子抜けするくらい簡単でした。

ついでにanimateを使ったバージョンも作成。矢印キーでスクロールするとちょっと動作が怪しいです(汗

サンプル:jqueryでフロートメニュー(animate版)

jqueryの場合、こうした簡単な機能であればライブラリを探すよりも自作してしまったほうが早いというケースも多そうです。

[追記]
animate版のほうを若干修正。要素セレクタに:not(:animated)を加えることで、アニメーション実行中にさらにアニメーションが実行され、動作が不安定になるのを防止するようにしました。

2010年12月9日木曜日

jQueryポケットリファレンス

普通のリファレンスです。サイズが小さく、持ち運びやすいです。
通勤時に電車内で読むために購入しました。

朝の通勤時にこれを読み、脳みそをjqueryモードにするのに使っています。

あと2010年4月発行と比較的新しく、ver1.4に対応している点もポイント高いと思います。

内容はあまり濃くありません。3日ほどで読み終わりました。
triggerメソッドについて記述がなかったりと、物足りない部分もあります。が、もともと完璧なものは期待していないので、それほど気にはなりませんでした。

空いた時間を使ってjqueryを脳みそにインプットしたい、という人にはおすすめできる一冊です。

2010年12月2日木曜日

Googleウェブマスターツールの404アラート

久しぶりにGoogleウェブマスターツールにログインしたら

http://kawama.jp/: 停止している可能性があります


というメッセージが数十通来ていました。

内容は、

サイトをクロールした際、2010-10-20 10:00 UTC(日本標準時は -9 時間)頃にソフト 404 エラーの数が一時的に増えていることが判明しました。サイトが停止している可能性があります。また、この問題は既に解決している可能性もあります。


というもの。このメッセージはメールに転送することもできるようです。
Googleウェブマスターツールはどんどん進化してると聞いてましたが、なるほど便利です。

ちなみに404アラートはcoreserver移行を機にピタリと止まってました。

面倒でしたが、やはり引っ越ししておいて良かったです。

2010年12月1日水曜日

php,smarty,mysql,javascriptでゼロ埋め

※javascriptも追加しました。

ゼロ埋めとかゼロパディングと言われるものです。
よく忘れてしまうのでまとめておきます。

■php
echo sprintf("%05d", $number);

echo str_pad($number, 5, "0", STR_PAD_LEFT);

引数をひとつ以上渡すことも可能。
echo sprintf("%04d-%02d-%02d", $year, $month, $day);

■smarty
{$number|string_format:"%05d"}

■mysql
select lpad(number, 5, '0') from table;

select to_char(number, '00000') from table;

■javascript

var number = 5;
alert(("0"+number).slice(-2));
> 05
alert(("00"+number).slice(-3));
> 005




他にもいろいろやり方はありますが、とりあえずよく使うものはこんなところだと思います。