symfony(MySQL)で前後の記事(次のレコード)を取得する
ブログとかでよくあるような「前の記事」「次の記事」リンクを表示しようと思ってちょっと悩んだ。
記事リストのページで次のリストを取るような場合は普通にページング処理をすればいいだけなので簡単だが、MySQLで「前のレコード」「次のレコード」を取るようなクエリがないので、記事単位だと以外と面倒なことに気づいた。
前提として、そのサイトは記事の新しい順(降順)で表示している。
没案1
ページャと同じ様に記事リストを取得し、ループを回しながら現在の記事を探して前後の記事を取得する。負荷がかかりそうな上に処理が面倒なので却下
没案2
現在の記事付近の塊を適当に取ってきて、適当に前後の記事っぽいものを取る。適当すぎる上に負荷が(ry
採用案
前の記事(getPreviousEntry)の場合…現在の記事の日時より後の記事を抜き出して、日時の昇順(早い日付順)にするとだいたい前の記事が取れる次の記事(getPreviousEntry)の場合…現在の記事の日時より前の記事を抜き出して、日時の降順(遅い日付順)にするとだいたい次の記事が取れる
この方法の問題点同じ公開日時の記事があると飛ばされることだが、
運用的に秒単位で公開日時の同じ記事というのはほぼほぼありえないので(゚ε゚)キニシナイ!!
symfony1.4 のpropelでmodelを書いたが、他の環境でも考え方は一緒かな。
public static function getPreviousEntry($entryId) { $entry = EntryPeer::retrieveByPk($entryId); $c = new Criteria(); $c->add(self::DELETE, 0); $c->add(self::PUBLISH_AT, $entry->getPublishAt(), '>'); $c->addAscendingOrderByColumn(EntryPeer::PUBLISH_AT); $c->setLimit(1); return self::doSelectOne($c); } public static function getNextEntry($entryId) { $entry = EntryPeer::retrieveByPk($entryId); $c = new Criteria(); $c->add(self::DELETE, 0); $c->add(self::PUBLISH_AT, $entry->getPublishAt(), '<'); $c->addDescendingOrderByColumn(EntryPeer::PUBLISH_AT); $c->setLimit(1); return self::doSelectOne($c); }
結構いい方法な気がする
セレクトボックス選択型リンク
セレクトボックスがあってそっから選んでクリックすると別のページのとばされるタイプのリンク
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>セレクトボックスで選択してURL遷移するテスト</title> </head> <body> <h2>リダイレクト(戻るボタンが効かない)</h2> <form action="" method="GET" name="select"> <select onchange="location.replace(this.options[selectedIndex].value)" > <option>-選択してください-</option> <option value="http://e0166.blog89.fc2.com">ホームページを作る人のネタ帳</option> <option value="http://www.paji.me/">パパパパ</option> <option value="http://www.phpbook.jp/">PHPBook</option> </select> </form> <h2>URL移動(戻るボタンが効かない)</h2> <form action="" method="GET" name="select"> <select onchange="location.href = this.options[selectedIndex].value" > <option>-選択してください-</option> <option value="http://e0166.blog89.fc2.com">ホームページを作る人のネタ帳</option> <option value="http://www.paji.me/">パパパパ</option> <option value="http://www.phpbook.jp/">PHPBook</option> </select> </form> </body> </html>
いじょう
MySQLのクエリキャッシュを削除する
MySQLのクエリチューニングをしている時主に実行時間とEXPLAINの値を見ているが、クエリキャッシュが聞いてると二回目以降はキャッシュにヒットするため実際の実行時間がわからない。
そういう時は以下のコマンドでクエリキャッシュを全削除できる。
RESET QUERY CACHE;
そこそこアクセスのある本番サーバなんかでやると悲惨なので注意。
SELECT文を発行する際にSELECTの後につけて
SELECT SQL_NO_CACHE
とするのも有り
print_rとvar_dumpの違い
配列の話し
$array = array("田村ゆかり"=>"Little Wish", "水城奈々"=>"SECRET AMBITION", "堀江由衣"=>"YAHHO!!", 2=>"あいうえお", 120); var_dump($array); print_r($array);
出力結果(ソース)
array(5) { ["田村ゆかり"]=> string(11) "Little Wish" ["水城奈々"]=> string(15) "SECRET AMBITION" ["堀江由衣"]=> string(7) "YAHHO!!" [2]=> string(10) "あいうえお" [3]=> int(120) } Array ( [田村ゆかり] => Little Wish [水城奈々] => SECRET AMBITION [堀江由衣] => YAHHO!! [2] => あいうえお [3] => 120 )
basic認証時にパスワードを取得する方法がPHPにあるらしい
PHP技術者認定・上級模擬問題
をやっていて知ったのだが、$_SERVER['PHP_AUTH_PW']なるグローバル変数で取得できるらしい。
やってみた
index.php
<?php echo "認証に成功しました<br>"; echo "ID:".$_SERVER['PHP_AUTH_USER']."<br>"; echo "パス:".$_SERVER['PHP_AUTH_PW']; ?>
.htpasswd
kunikiya:GZnkccJy7Ynbo
AuthUserFile .htpasswd AuthName "Please enter your ID and password" AuthType Basic require valid-user
表示結果
認証に成功しました ID:kunikiya パス:pass
昔はセキュリティのためユーザー名は取得できるけど、パスワードは取得できなかったはず・・
変わったのか?勘違いだったのか?
symfony propel:build-model がうまくいかない
symfony1.2でpropel:build-modelをしたらエラーが出た
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 41 bytes) in /usr/share/pear/symfony/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ObjectBuilder.php on line 133 Buildfile: /usr/share/pear/symfony/plugins/sfPropelPlugin/lib/vendor/propel-generator/build.xml [resolvepath] Resolved /home/porvie/symfony/config to /home/porvie/symfony/config
エラー内容通りに解釈して、メモリサイズが足りてないのかと思い、
PHPのmemory_limitを大きくしてみたが、6Gとかにしてもエラーは変わらず
そんだけあって足りないとか何事?と思って調べまくってたら、どうやらpropelのバグだった様子
2011-11-20 symfony propel:build-○○ task でハマった
defaultValue: CURRENT_TIMESTAMP
があるとうまくいかないっぽい…
今回はスキーマからDBを構築することはなくモデルをビルドしたいだけなので、取り合えず消し去る
symfony propel:build-modelしておわり
AIRアプリに自動アップデート機能を実装する
デスクトップアプリの自動アップデート機能を普通に実装するとめちゃめちゃ工数がかかるが、
AIRアプリの場合はAirAutoUpdaterという一行で実装できる便利なライブラリがある。
が、しかし、Flex4.5だと多少変わってたのでメモ
公式サイト
↓
AirAutoUpdaterとは
サンプルにある通り一行追記してみる
<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" windowComplete="init();"> <jx:AirAutoUpdater url="http://jirox.net/as3/BlurHighlight/version.xml"/> <fx:Declarations> <!-- 非ビジュアルエレメント (サービス、値オブジェクトなど) をここに配置 --> </fx:Declarations> <fx:Script> <![CDATA[ ]]> </fx:Script> </s:WindowedApplication>
『エレメント "jx:AirAutoUpdater" の接頭辞 "jx" がバインドされていません。』
ふむ
AIRソフトウェアを自動でネットワークアップデート(1行で!)
だそうなので
<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:jirox="net.jirox.*" windowComplete="init();"> <jirox:AirAutoUpdater url="http://jirox.net/as3/BlurHighlight/version.xml"/> <fx:Declarations> <!-- 非ビジュアルエレメント (サービス、値オブジェクトなど) をここに配置 --> </fx:Declarations> <fx:Script> <![CDATA[ ]]> </fx:Script> </s:WindowedApplication>
『"AirAutoUpdater" 宣言は、デフォルトプロパティの型 "Array" にもエレメントの型 "mx.core.IVisualElement" にも代入できないので、
ふむ
ってことで
<jirox:AirAutoUpdater url="http://jirox.net/as3/BlurHighlight/version.xml"/>
を
<fx:Declarations> </fx:Declarations>
の中に入れてやる
<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:jirox="net.jirox.*" windowComplete="init();"> <fx:Declarations> <!-- 非ビジュアルエレメント (サービス、値オブジェクトなど) をここに配置 --> <jirox:AirAutoUpdater url="http://jirox.net/as3/BlurHighlight/version.xml"/> </fx:Declarations> <fx:Script> <![CDATA[ ]]> </fx:Script> </s:WindowedApplication>
でOK