Monthly Archives: 8月 2007

MySQLのLimitはOffsetのみの値を受け付けない

Zend FrameworkでMySQLを使っていて、LimitがNullだとOffsetが効かない症状が出たので調べてみたら、MySQLがそうなんですね。
MySQLのリファレンスを見ると、載っています。

LIMIT 条項は SELECT ステートメントに返された行数を制限するのに利用する事ができます。LIMIT は、負数以外の整数定数でなければいけない、1つか2つの数値引数を取ります。(準備されたステートメントを利用している時以外)
その2つの引数のうち、最初の物は返される最初の行のオフセットを指定し、2つめの物は返される行の最高数を指定します。冒頭の行のオフセットは0です。(1ではありません)
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
全ての行を一定のオフセットから結果セットの最後まで検索するには、2つめのパラメータに大きい数字を利用する事ができます。このステートメントは96番目の行から最後まで全ての行を検索します。
SELECT * FROM tbl LIMIT 95,18446744073709551615;
1つの引数で、その値は結果セットの最初から返される行数を指定します。
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
言い換えると、LIMIT row_count は LIMIT 0, row_count と同等だという事になります。


言い換えると、LIMIT row_count は LIMIT 0, row_count と同等だという事になります。

ふむ。一工夫いる箇所ですね。これはMySQLだけの症状なんでしょうか?

クラスを使うメリット

はてなでこのような質問がありましたが、

PHPを独学で勉強しているのですがclassに関しては全く手を付けていません。
理由として「メリットがイマイチ理解できない」からです。

もちろん使ったほうが何らかのメリットはあると思うのですが、具体的にどのようなメリットがあるのか教えて頂けないでしょうか。

抽象的な表現で「~~なメリットがある」というのは検索するとたくさん出てきますので、もう少し具体的な情報が欲しいです。

PHPなんだから時々はベタに書かないとなー、などと思って作業する時に1番違和感を感じるのは、グローバル変数を使わないといけない状況が増える、ということですね。グローバル変数を使うとリファクタ時に困ってしまいます。

ソースコードチェックツール pixy

pixyというソースコードチェックツールが。

php5系には未対応、マルチバイトで書かれたソースはうまく解析できない場合がある、オブジェクト指向で書かれたソースはうまく解析できないなどの問題があるが、

というのではなかなか現実的ではないかもしれませんが、こういう自動チェックツールというのは嬉しいですね。気をつけてるつもりでも、ミスを犯すのが人間というものですから。

phpMyAdminでリレーションの設定時に「インデックスは設定されていません」とエラーが出る。

うーん、ハマってました。
phpMyAdminでリレーションの設定時に「インデックスは設定されていません」とエラーが出るのです。しっかりインデックスを設定しているのにも関わらず。
原因は、リレーション元と張る先のフィールドタイプが違っていたのでした。とほほ。

members->id が int(10)
hoge->member_id が int(11)

となっているのに、hogeテーブルのmember_idから membersテーブルのidへ懸命にリレーションを張ろうとしていたのです。

それにしても
「インデックスは設定されていません」
という警告は無いだろうと思うのですが、この手のソフトではよくあるコトなのでしょうがありませんね。phpMyAdminのおかげでインデックスや複合ユニーク?などの設定も簡単にできて助かってますし。

Ajax PHP VARIABLE TEST

AjaxでPHPのVariable Testっぽいものを作ってみました。

Variable
PHP VARIABLE TEST

とりあえずサクっと確認したい時に使えるものが欲しかったので。機能的にはまだまだですが、

$x = “vmware”
$y = “xen”

で、$x < $y だったり(最初の文字のアスキーコードで比較、のハズ)

$x = new stdClass(“PHP”);
$y = new stdClass(“PHP”);

で、 $x == $y が True、 $x === $y が False だったりするのが面白いかな、と思いました。

memory_get_usage — PHP に割り当てられたメモリの量を返す

memory_get_usage()でPHP に割り当てられたメモリの量が取得できます。これで自分でどの手法がメモリ使用量が少ないか、などの測定ができますね。デバッガと共に使うとより便利そうです。

Zend Frameworkで多対多のテーブルを簡単に扱う。

いろいろとややこしい多対多のテーブル関連の操作をZend Frameworkで簡単に行えます。
前提として、RDBMS上ですでにリレーションの設定を行っているものを扱います。そちらのほうが簡単なので。

多対多リレーションとか関係テーブルとか、マッピングテーブルとかいわれてるテーブルの設定。

[php]
class BugsProducts extends Zend_Db_Table_Abstract
{
protected $_name = ‘BugsProducts’;

protected $_referenceMap = array(
‘Bug’ => array(
‘columns’ => ‘bug_id’,
‘refTableClass’ => ‘Bugs’,
‘refColumns’ => ‘id’
),
‘Product’ => array(
‘columns’ => ‘product_id’,
‘refTableClass’ => ‘Products’,
‘refColumns’ => ‘id’
)
);

}
[/php]

(設定はZFマニュアルに載っているのを参考に、少し変更しました。あまり深く考える必要は無いのですが、まあ、BugsとProductsの多対多、1つの製品に多数のバグがあり、1つのバグが製品群に横行していることもある、といったテーブルでしょうか)
上記の様に親テーブルにリファレンスを張って、

[php]
$products = new Products();
$bug_list = $products->find(10)->current()
->findManyToManyRowset(‘Bugs’, ‘BugsReports’);
[/php]
で、$bug_listには、多対多テーブルで product_id=10 と関連付けられている (bugsテーブルの)bugのRowsetが入っているという。。
今時のフレームワーク、O/Rマッパーなどでは当たり前の機能なのかもしれませんが、こんなに簡単に操作できて感動しました。

RDBMS上でリレーションを組んでおけば、Zend_Db_Tableの設定で 親側のテーブルに $_dependentTables を指定しなくてもよいので楽です。

マニュアルには、

注意

RDBMS サーバが実装している参照整合性制約によって連鎖操作を行う場合は、 $_dependentTables を宣言しません。 詳細は 項9.8.6. 「書き込み操作の連鎖」 を参照ください。

と書いてあります。$_referenceMapも自動で張ってくれると楽なんですけどねえ。

findManyToManyの書き方は色々とあるようですので、マニュアルを参照してください。

[php]
$row->findVia()
$row->findViaBy()
$row->findViaByAnd()
[/php]

range — ある範囲の整数を有する配列を作成する

以前ハノイの塔のアルゴリズムを書いた時に、1~xまでの整数値を持つ配列を作成していましたが、

[php]
for ($i = 1; $i <= $a; $i++) {
$this->a[] = $i;
}
[/php]
こんな恥ずかしいことをしていましたが、rangeで一発ですね。
[php]
$this->a = range(1,$a);
[/php]
いやー、この手の関数があるとは思っていたんですが、Array~うんちゃらで探してて見つからなかったので諦めてました。

autoloadのほうがrequire_onceよりも早い?

ウノウラボの記事で知ったのですが、

requireはrequire_once()より3-4倍遅い?
空ファイルを forループで1万回呼んだ結果、4倍程度早かった。

元ネタでは

Ilia advises against using magic functions like __autoload() and __get(), but the advantage of __autoload() in particular is obvious in any large project and is used by many php frameworks. My primitive testing, however, shows inverse results. With a simply autoload requiring a class and 10000 loops of new Foo() versus require_once(‘foo.php’); new Foo() shows that __autoload() is ~3.7 times faster.

こう書かれています。うーむ。require_onceで読み込んでからnewしたほうが早いに違いないと思っていましたが、__autoloadなら内部処理で全て賄えるのを、require_onceをスクリプトで実行する分、オーバーヘッドができてしまうということなのでしょうか。これからは__autoloadを気兼ねなく使えそうです。

PHPをネットで学ぶ

PHPを初めて学ぶ初心者がPHPでネットを学ぶためのリンクがあつめられています。
徒手空拳ではじめるよりは、このようなサイトを参考に始めたほうがよいでしょう。こう見ていくと、やはりPHPは取っ付きが良いですね。