Archive for 12月, 2007
.htaccess で error_reporting を設定するときの注意点
5.htaccess で PHP が出力するエラー表示を制御するには E_ALL などの定数は使えないので、ビット値で指定する必要があります。
E_ALL & ~E_NOTICE を設定する場合
php.ini
error_reporting = E_ALL & ~E_NOTICE
php コード内
error_reporting(E_ALL ^ E_NOTICE);
.htaccess
php_value error_reporting 6135
error_reporting に設定する値は PHP: error_reporting – Manual を参照するといいでしょう。
値 | 定数 |
---|---|
1 | E_ERROR |
2 | E_WARNING |
4 | E_PARSE |
8 | E_NOTICE |
16 | E_CORE_ERROR |
32 | E_CORE_WARNING |
64 | E_COMPILE_ERROR |
128 | E_COMPILE_WARNING |
256 | E_USER_ERROR |
512 | E_USER_WARNING |
1024 | E_USER_NOTICE |
6143 | E_ALL |
2048 | E_STRICT |
4096 | E_RECOVERABLE_ERROR |
ちなみに E_ALL & ~E_NOTICE の値が 6135 になる理由は E_ALL の値が 6143、E_NOTICE の値が 8 なので 6143-8=6135 になります。(または E_NOTICE と E_STRICT 以外の値を足した数が 6135 になります。
私は開発中は E_NOTICE も表示するようにしていますが、結構表示させない人が多いようで人のコードを修正するときなど Notice エラーが出て困ることがあります。E_NOTICE を表示するようにしておくと未定義の変数などバグの元になりやすいものを教えてくれるのでお勧めです。
また、開発終了して本番運用するときにはブラウザにエラーを出力しないように
error_reporting(0);
を設定しておくことを忘れずに!
その際も PHP のエラーはエラーログに記録されるようにしておかないのも忘れずに。
CakePHP JQuery ヘルパー
3JQuery helper for CakePHP ( PQuery port ) at NGCoders
CakePHP から JQuery を簡単に使うことができます。
正確には PQuery ヘルパーかもしれません。PQuery は JQuery を PHP から簡単に使用するライブラリで PQuery ヘルパーと同じ開発者が開発しています。
参考:PQuery – PHP and JQuery at NGCoders
インストール
JQuery helper for CakePHP ( PQuery port ) at NGCoders から JQuery ヘルパーをダウンロードし、解凍した pquery.php を /app/views/helpers にコピーします。
そのほかに jquery.js ファイルも必要になります。こちらもダウンロードして /app/webroot/js にコピーします。
コントローラ
Pquery ヘルパーと Javascritp ヘルパーを使用します
var $helpers = array('Pquery', 'Javascript');
ビュー
jquery.js の読み込み
<?php echo $javascript->link('jquery.js'); ?>
使用例
トグルボタン
<div id='msg'>Message...</div> <?php echo $pquery->link_to_function('toggle', $pquery->toggle('#msg'));?>
フォームで送信された内容により HTML を更新
入力したテキストを /controller/action/ に GET で送信し、id=idtoupdate に受け取った HTML を表示する
<?php echo $pquery->form_remote_tag(array('url'=>'/controller/action/','update'=>'#idtoupdate'));?> <input type='text' name='field' /> <input type='submit' /> <div id='idtoupdate'></div>
pquery.php を見ると色々なメソッドがあります。使い方はソースを見ればすぐに分かると思います。
scriptaculous.js を使ってマトリックス状に配置した要素を並び替える
1scriptaculous.js を使って並び替えを行う を応用して格子状に並んだ要素を並び替える例です。基本的な部分はリスト形式の並び替えと同じですので省略します。
最初にデモ、その後にコードを紹介します。
デモ
#sortarea { width: 350px; } #sortarea div { float: left; width: 100px; height: 70px; border: 1px solid #000; margin: 5px; text-align: center; padding-top: 30px; cursor: default; }
ソートする要素
前回は li タグで要素を定義しましたが、今回は div タグで定義しました。
CSS で格子状に並ぶようにしています。
<style> #sortarea { width: 350px; } #sortarea div { float: left; width: 100px; height: 70px; border: 1px solid #000; margin: 5px; text-align: center; padding-top: 30px; cursor: default; } </style> <div id="sortarea"> <div id="drag_1">A1</div> <div id="drag_2">A2</div> <div id="drag_3">A3</div> <div id="drag_4">A4</div> <div id="drag_5">A5</div> <div id="drag_6">A6</div> <div id="drag_7">A7</div> <div id="drag_8">A8</div> <div id="drag_9">A9</div> </div>
ソートする JavaScript コード
Sortable.create の option に overlap:’horizontal’ を指定しなくても並び替えはできますが、少しぎこちない感じになりますので、指定しておいたほうがいいでしょう。
<script type="text/javascript" language="javascript"> // <![CDATA[ Sortable.create("sortarea",{ tag:'div',overlap:'horizontal',constraint: false, }); // ]]> </script>
scriptaculous.js を使って並び替えを行う
2JavaScript の読み込み
まず prototype.js と scriptaculous.js を読み込む
<script type="text/javascript" src="prototype.js"></script> <script type="text/javascript" src="scriptaculous.js"></script>
ソートするリストを作成する
ここでのポイントはドラッグさせたい要素に drag_1 のように「共通の名前+アンダバー+数字」を付けることです。
<ul id="sortarea"> <li id="drag_1">A1</li> <li id="drag_2">A2</li> <li id="drag_3">A3</li> <li id="drag_4">A4</li> <li id="drag_5">A5</li> <li id="drag_6">A6</li> <li id="drag_7">A7</li> <li id="drag_8">A8</li> <li id="drag_9">A9</li> </ul>
ソートする JavaScript コード
ソートするエリアとソートする要素を定義した後で実際にソートするための JavaScript コードを書く。このコードがソートさせたい要素よりも前に書くとエラーになるので注意。
<script type="text/javascript" language="javascript"> // <![CDATA[ Sortable.create("sortarea",{ onUpdate:function(){ new Ajax.Updater( 'sortarea', '/path/to/phpcode', { asynchronous:true, evalScripts:true, parameters:Sortable.serialize("sortarea") } ); } }); // ]]> </script>
onUpdate でソート結果をPHP に送りデータベースなりに反映させる。
データベースに反映などが必要なければ、onUpdate は不要です。
デモ
これを実際に使用した例が下記になります。
#sortarea { width: 350px; border: 1px solid #000; } #sortarea li { cursor: default; }
- LIST1
- LIST2
- LIST3
- LIST4
- LIST5
- LIST6
- LIST7
- LIST8
- LIST9
IE で CSV がダウンロードできない問題
1OpenPNE の管理画面からメンバー情報を CSV ファイルとしてダウンロードする機能があります。その CSV ダウンロードが IE6 でエラーになってダウンロードできない問題がありました。
原因はマイクロソフトのサイト Content-Disposition: attachemnt と Cache-Control: no-cache によるダウンロードの問題 に書かれていました。
対処方法として、
webapp/modules/admin/do/csv_member.php を webapp_ext/modules/admin/do/csv_member.php にコピーして
header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=member.csv");
となっているところを下記のように修正します。
header("Pragma: public"); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=member.csv");
これでダウンロードができるようになります。
なお、Content-Disposition: attachemnt と Cache-Control: no-cache によるダウンロードの問題 では現象が発生するブラウザとして
?Microsoft Internet Explorer 5.0
?Microsoft Internet Explorer 6.0
?Microsoft Internet Explorer 6.0 Service Pack 1
と書かれていましたが、 IE6 の SP2 でも同様の現象が発生しました。
Smarty で正規表現を if 文で使用する
2Smarty には正規表現を使用して文字列を置換する regex_replace があります。
これを上手に使用して if 文で正規表現を用いて条件分岐させます。
if (preg_match('/php/i', 'PHP is the web scripting language of choice.')) { echo 'A match was found.'; } else { echo 'A match was not found.'; }
PHP で上記のような処理を Smarty で書くと下記のようになります。
{assign var='string' value='PHP is the web scripting language of choice.'} {if $string|regex_replace:'/.*php.*/i':'php' eq 'php'} A match was found. {else} A match was not found. {/if}
ポイントは regex_replace を用いて、正規表現のパターンに該当する場合は元の文字列を何かしらの文字列(上の例でいうと’php’)に置換してしまい、それを eq で置換されているか判定するということです。
これを実際に使用したのは OpenPNE のテンプレートです。
OpenPNE を使用していて、特定のカテゴリのときのみ読み込む CSS を変えたいときがありました。
OpnePNE のイベント関連の URL は http://expamle.com/?m=pc&a=page_c_event_*** という感じになります。
全部で14種類ありますので、これを普通に if 文で書いていると大変なことになりますし、追加などがあったときのことを考えるとよくありません。
そこで Smarty の if 文に正規表現を使用して下記のようにすることにより1つの条件で page_c_event_*** の URL を条件分岐させました。
Smarty テンプレート
{if $smarty.get.a|regex_replace:"/page_c_event.*_/":"event" eq "event"} {** イベントです**} {else} {** イベント以外です **} {/if}
WordPress の Simple Tagging プラグインで表示する関連エントリのはてブ数を表示する方法
1このブログは Simple Tagging というプラグインを使用して各エントリにタグをつけています。このプラグインを使用するとタグから各エントリの関連エントリを自動的に表示することができます。詳しくは下記エントリをご覧ください。
WordPress でタグを使えるようにしてみた
今回はこの関連エントリのはてなブックマーク数を表示するようにする方法です。
こんなイメージです。
関連エントリを表示するタグ
<?php STP_RelatedPosts(); ?>
この STP_RelatedPosts 関数の第1引数は表示フォーマットを指定するので、そこにはてブ数を表示するようなフォーマットを指定します。
<?php STP_RelatedPosts('<li><a href="%permalink%" title="%title% (%date%)">%title%</a> <a href="http://b.hatena.ne.jp/entry/%permalink%"><img src="http://b.hatena.ne.jp/entry/image/%permalink%" alt="" /></a>'); ?>
これで関連エントリにはてブ数が表示されるようになりました。
WordPress ではてなブックマーク数を表示
2少しづつはてブされるようになってきたので、各エントリーのタイトルの横にはてなブックマーク数とを表示するようにしてみました。
はてブボタンを表示
http://d.hatena.ne.jp/images/b_entry.gif からアイコンをダウンロードして自分のサーバにアップロードします。
表示したい場所に下記タグを追加します。
<a href='http://b.hatena.ne.jp/entry/<?php the_permalink(); ?>'><img src='/images/b_entry.gif' width='16' height='12' style='border: none;' alt='このエントリーを含むはてなブックマーク' title='このエントリーを含むはてなブックマーク' /></a>
参考:はてなブックマーク – ヘルプ – 自分のブログに「このエントリーを含むはてなブックマーク」ボタン
はてなブックマーク数を表示
表示したい場所に下記タグを追加します。
<a href='http://b.hatena.ne.jp/entry/<?php the_permalink(); ?>'><img src='http://b.hatena.ne.jp/entry/image/<?php the_permalink(); ?>' alt='' /></a>
HTTP_Request を使用してファイルをアップロードする方法
1PEAR の HTTP_Request を使用してファイルをアップロードする方法です。
<form action='POST_URL' method='post' enctype='multipart/form-data'> <input type='text' name='title'> <textarea name='body'></textarea> <input type='file' name='upload_file'> <input type='submit'> </form>
上記のような HTML でファイルをアップロードする場合と同じような処理をするには、下記のように HTTP_Request を使用します。
// POST パラメータ $post_data = array( 'title' => $title, 'body' => $body, ); // アップロードパラメータ $upload_file = array( 'name' => 'file', 'path' => '/path/to/file', ); // アップロード $rs = http_send(POST_URL, $post_data, $upload_file); function http_send($url, $params, $upload_file=null) { $req = new HTTP_Request(); $req->setMethod(HTTP_REQUEST_METHOD_POST); foreach ($params as $key => $val) { $req->addPostData($key, $val); } $req->setURL($url); if ($upload_file) { $res = $req->addFile($upload_file["name"], $upload_file["path"]); if (PEAR::isError($res)) { echo $res->getMessage(); exit; } } if (!PEAR::isError($req->sendRequest())) { return $req->getResponseBody(); } else { return false; } }