Posts tagged select

CakePHP Pagination まとめ

2

CakePHP の Pagination に関してまとめてみました。

コントローラでコンポーネント、ヘルパーに Pagination を指定

// 使用コンポーネント名
var $components = array('Pagination');
// 使用ヘルパー名
var $helpers = array('Pagination');

コントローラの一覧表示するアクションでの一覧表示取得方法

$this->Pagination->modelClass = 'Model'; // 使用するモデル
$this->Pagination->sortBy = 'created';	 // デフォルトのソートするフィールド名
$this->Pagination->direction = 'DESC';	 // デフォルトの昇順、降順を指定
$this->Pagination->show = 10;			 // 1ページに表示する件数
$conditions = array(); 					 // 検索条件
list($order,$limit,$page) = $this->Pagination->init($conditions);
$lists = $this->Model->findAll($conditions, $fields, $order, $limit, $page, $recursive);

ビューでのヘルパー使用準備

ビューで Pagination ヘルパーを使用できるようにする
< ?php $pagination->setPaging($paging); ?>

ビューでの総件数と表示している件数の表示

< ?php echo $pagination->result('検索結果:', '/', '?'); ?>件
上記のように指定すると「検索結果:1?10/5253件」と表示されます。

ソートするフィールドを変更するリンクを表示する

< ?php echo $pagination->sortBy('field_name', 'フィールド名', 'ModelName'); ?>
field_name にソートするフィールド名、
フィールド名にリンクに表示する名前、
ModelName にはフィールド名が属するモデル名
を指定します。
モデル名は $this->Pagination->modelClass と同じ場合には省略可能です。

また、sortBy メソッドは
veiws/heplers/pagination.php
function sortBy ($value, $title=NULL, $Model=NULL,$escapeTitle=true,$upText=' ^',$downText=' v')
のように定義されています。見て分かるとおり第5、6引数を指定することにより、ソートしたときのリンクのフィールド名につく「^」「v」の文字を変更することができます。

select タグによってソートを指定したいときは sortBySelect メソッドがあります。
function sortBySelect($sortFields, $t='Sort By: ',$upText=' ^',$downText=' v')

SQL BLOB の容量を計算する方法

1

OpenPNE のカスタマイズをしていて会員毎に画像容量の制限をする必要がでてきました。
quota を使用できれば簡単なのですが、OpenPNE は DB に バイナリデータとして画像を保存しているため使用できません。

そこで SQL で容量を計算する方法を考えました。

LENGTH 関数を使用して
SELECT LENGTH(blobカラム)
とすればバイト数を計算できます。

OpenPNE の場合は c_image というテーブルに画像データが格納されています。
そこで特定の会員の日記に使用した画像の容量を計算するのに下記のようにしてみました。

SELECT SUM(LENGTH(i.bin))
FROM c_image as i
LEFT JOIN c_diary d ON(d.image_filename_1=i.filename OR d.image_filename_2=i.filename OR d.image_filename_3=i.filename)
WHERE d.c_member_id=会員ID

得られる値は byte 数になります。

MySQL で NULL を一番最後にして昇順にソートする

4

2008.2.27 追記
コメントで教えていただきました下記方法で簡単にできました。
is null asc の指定と 通常の asc の指定をするのがポイントですね。

SELECT
  id,
  comment
FROM table
ORDER BY comment IS NULL ASC, comment ASC;

—–追記ここまで—–

MySQL で昇順にソートすると NULL は一番最初に来ます。
それを最後にできないかということで下記のようなSQL を考えてみました。

SELECT
  id,
  comment,
  CASE WHEN comment IS NULL
    THEN 10000
    ELSE ASCII(LEFT(comment,1))
  END AS dummy
FROM table
ORDER BY dummy ASC, COMMENT ASC

comment カラムを昇順でソートして、NULL の場合は一番最後に NULL がきます。
あまりスマートな方法ではないのですが、これで取り合えず NULL を最後にして昇順でソートするということができました。

ORACLE とかだと下記のように簡単にできますね。
ORDER BY comment ASC NULL LAST

NULLS FIRST
NULL 値を順序の最初にするソートを行なう
NULLS LAST
NULL 値を順序の最後にするソートを行なう

ランダムに抽出する SQL

4

ランダムに10件 SELECT する SQL です。
ORDER BY RAND() でランダムにソートして LIMIT 句で取得したい件数だけ取得します。
SELECT * FROM table ORDER BY RAND() LIMIT 10;

ランダム関数は MySQL, PostgreSQL, SQLServer で使用できます。
ランダム関数は
MySQL, SQLServer は RAND()
PostgreSQL は RANDOM()
です。

ランキングを取得するSQL

3

ランキングを取得するSQL です。
同じスコアの場合は同じ順位にするなどの必要があるため結構面倒ですが、
下記SQL でイッパツで取得できます。

実際に携帯ゲームのランキングを取得するのに使用しているSQLです。

ranking テーブル

CREATE TABLE ranking (
  id bigint(20) NOT NULL auto_increment,
  name varchar(20) NOT NULL,
  score bigint(20) NOT NULL,
);

SQL

SELECT
    r1.name,
    r1.score,
    (SELECT count(r2.score)
     FROM ranking as r2
     WHERE r2.score>r1.score)+1 as rank
FROM ranking as r1
ORDER BY r1.score DESC
LIMIT 10;

rank というカラム名で順位が計算されます。
同じスコアの場合は順位は同じになります。

上記SQL はトップ10を取得していますが、実際にはLIMIT句を変更することにより
ページング処理などで下位のランキングを見れるようにしています。

副問い合わせで順位を計算しています。
MySQL ではバージョンが4.1 以降でないと副問い合わせが使用できないので注意してください。

※本運用ではインデックスを適宜作成しています。

optionタグを選択不可にする disabled 属性を IE6 でも有効にする方法

0

optionタグを選択不可にする disabled 属性で紹介したように option タグに disabled 属性を指定することにより選択不可にすることができるのですが、IE6 では選択できてしまいます。

JavaScript で解決する方法です。

Select, Option, Disabled And The JavaScript Solution

上記の参考サイトに詳しくやり方が書かれていますので、簡単に手順だけ紹介。

  • 参考サイトの「Implementing」にある download リンクより JavaScript コード(select-option-disabled-emulation.js)をダウンロード
  • select-option-disabled-emulation.js を適当な場所に保存
  • html 内で select-option-disabled-emulation.js を読み込む
  • 選択不可にしたい option タグに disabled 属性を指定する

DHTML で解決する方法です。

これは上記参考サイトの補足で紹介されていたサイトです。
apptaro’s blog: Emulating Disabled Options in IE with DHTML Behaviors

こちらも上記URL に詳しいやり方が書かかれていますので、簡単にご紹介。

  • 参考サイトの中央よりやや下にある Download よりファイル一式をダウンロード
  • 適当な場所に css, htc ファイルを保存
  • html で上記 css を読み込む
  • 選択不可にしたい option タグに disabled 属性を指定する

これで IE6 でも option タグの disabled 属性が使えるようになりました。

optionタグを選択不可にする disabled 属性

2

フォーム画面を動的に表示してある条件のときにはラジオボタンなどを disabled にしたりします。
今回もあるフォームを作成していて在庫が0のときに select タグで表示する項目を選択できないようにしたかったので調べてみたところ、option タグにも disabled 属性がありました。

そこで下記のようにしてみたところ

<form action="">
<select>
<option>オプション1</option>
<option disabled="disabled">オプション2</option>
<option>オプション3</option>
<option>オプション4</option>
</select>
<input type="submit">
</form>

option-desiabled

うまく選択不可になりました。
ところが Firefox では OK だったのですが、IE6では選択可能に。。。

調べてみると
Disable Option’s In A Select (Dropdown) Element ? Post Archive ? www.lattimore.id.au

It never ceases to amaze me how a browser like IE6, managed to not implement something as trivial as an attribute like disabled. The IE team managed to implement it against the <select> element, but some how overlooked the <option> element. They implement the readonly attribute against the appropriate elements – yet some how the disabled attribute managed to be overlooked when they implemented it. More surprising is that, since the HTML4.01 specification came out in late 1999, IE has been updated and upgraded for various things literally hundreds of times. Why hasn’t this made it into an update? You’d begin to think that Microsoft aren’t aware of it, however the thought of that just seems too far fetched.

どうも IE6 のバグのようです。

PEAR の DB から MDB2 への移行メモ

0

やっとMDB2 へ移行したので、その時のメモ。

DBからMDB2への移行は結構いろいろなサイトで書かれていますね。
PHPのテクメモ | pearのDBとMDB2の違い
DB-2-MDB2

これらを参考にさせていただいたのですが、
私はよくプレイスホルダをよく使用しています。

$db->getOne('SELECT * FROM users WHERE id=?", array($id));

MDB2では queryOneメソッドではプレイスホルダが使用できないので(queryRow,queryAllなども同様)移行に手間がかかってしまいます。

少し調べてみると下記のようにすることにより、MDB2 でもプレイスホルダが使用でき、しかも getOne や getAll などのメソッド名もそのまま使用できます。

$db->getOne('SELECT * FROM users WHERE id=?", array($id));
$mdb2->getOne('SELECT * FROM users WHERE id=?", null, array($id));

ただ、

require_once 'MDB2.php';
require_once 'MDB2/Extended.php';

と Extended をロードする必要があります。

CakePHP SQL を書いて実行する方法

1

CakePHP ではSQL を書かなくてもだいたいなんでもできるのですが、
ちょこっとSQLを書いて実行したいことがあり調べたメモです。

/cake/libs/model/model_php5.php
を眺めていると findBySqlメソッドがありました。
引数はSQLを文字列で受け取ります。
これだ!っと思ったらただ単に

function findBySql($sql) {
return $this->query($sql);
}

となっている。。。
queryメソッドにSQLを投げればいいんですね。

$sql = "SELECT NOW()";
$foo = $this->HogeModel->query($sql);

CakePHP HTMLヘルパーで select タグを表示する

2

HTML ヘルパーで select タグを表示したかったが、
マニュアルを見ても書かれていなかったので、調べたメモ

/cake/libs/view/helpers/html.php

を見ると selectTag というメソッドがり、

/**
* Returns a formatted SELECT element.
*
* @param string $fieldName Name attribute of the SELECT
* @param array $optionElements Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the SELECT element
* @param mixed $selected Selected option
* @param array $selectAttr Array of HTML options for the opening SELECT element
* @param array $optionAttr Array of HTML options for the enclosed OPTION elements
* @param boolean $show_empty If true, the empty select option is shown
* @param  boolean $return         Whether this method should return a value
* @return string Formatted SELECT element
* @access public
*/
function selectTag($fieldName, $optionElements, $selected = null, $selectAttr = array(), $optionAttr = null, $showEmpty = true, $return = false) {

と定義されている。

よく指定しそうな引数は

  • $fileName にフィールド名
  • $optionElements に option タグに表示するもの配列
  • $selected にデフォルトで選択状態にする $optionElements のキー
  • $showEmpty は一番最初の option タグを空 <option value=”"> </option> で表示するか

コントローラで

$this->set('questions', array(
    '卒業した学校名',
    '好きなチーム名',
    'ペットの名前',
    '両親の旧姓',
    '免許証の下4桁',
    '好きな映画の題名',
    )
);

として

<?php echo $html->selectTag('Post/question', $questions, null, null, null); ?>

とすればOK.

よく「選択してください」などの文言が option タグの先頭にある場合があるが、
そのように表示したい場合は

array(
'選択してください',
'卒業した学校名',
'好きなチーム名',
'ペットの名前',
'両親の旧姓',
'免許証の下4桁',
'好きな映画の題名',
)

として、$html->selectTag の6番目の引数に false を指定すれば空の option タグが表示されなくなる。
必須選択にしたい場合は「選択してください」の値が0なので、0以外の数字でバリデーションチェックすればいい。

Go to Top