ザ・コン館閉店 ― 2007年09月23日 11時26分58秒
ああ、20日だったのか
そうか、20日閉館だったのか。もっとも目立つランドマークのひとつだったんだけど、ここまでなくなっちゃうんだもんなぁ。。。
正直、値段が安いわけではないし、あまりここで買い物をした記憶はないんだけども、書籍コーナーが充実しているのでそこだけはよく利用させてもらってた(特に、書泉ブックタワーができる前は)。
あー、あと1階のエスカレータ脇にあったソフトベンダーTAKERUが妙に印象に残ってる。別に利用したことないけど(こればっか)。
実はザ・コン館よりも、すぐ裏手のアソビットキャラシティのほうが思い入れが深く、楽器館だったころはよくシークホー(中古市)に出かけたりしてたな。あとMac OS 8をここで深夜販売で買った気がする。8.5だったかしら。
オノデン坊やも
そういえば、オノデンライフストアのオノデン坊やも先週あたりから解体工事で見えなくなって、これまた寂しい。
再開発が進むにつれて、どんどん知らないアキバになってゆくなぁ。
オマケ
MacOS 8を買った、ってくだりでよいリンク先がないか探したら、こんなところが見つかった。残念ながら、手持ちのブラウザのうちちゃんと閲覧できたのはIE6とOpera9だけ(Safariすらはじかれた)なのだが、わりと良くできてて、すこし懐かしい気持ちになった。
追記
ここみたら余計鬱に... 打ち消し線はつらいなぁ。
ZendFramework入門・その6データベースを扱う・その1 ― 2007年09月23日 15時09分51秒
はじめに
またも1週間のご無沙汰になりましたが、前回の予告どおり、データベース機能の説明に入ります。
DBMSに関しては、前回に予告したとおりSQLiteを対象としますので、先にこちらの番外編を参考にして、コンソールアプリケーションを導入しておくとよいでしょう。
また、この記事はあくまでZend Framework入門ですので、SQLに関する細かい説明などはあまりしない予定です(まぁ、シンプルな使い方しかしない予定ですが)。データベースになれていない方は、他のSQL入門記事なども参考にされるとよいと思います。
それでは本文へまいりましょう。
データベース関連クラス
Zend Frameworkのデータベース機能はZend_Db名前空間に集約されていて、以下のようなクラス群で構成されています。
| クラス名 | 役割 |
|---|---|
| Zend_Db_Adapter | DBアダプタ。データベースへの接続やZend_Db_Statement・Zend_Db_Selectのファクトリとして機能する、Zend_Dbの主要クラス。 すべてのDBアダプタは抽象クラス「Zend_Db_Adapter_Abstract」から派生し、DBMSごとの機能の違いを吸収する |
| Zend_Db_Statement | DBMSへの問い合わせを行うステートメントオブジェクト。Zend_Db_Adapterと同様に、基本の抽象クラスから派生した固有のクラスがDBMS間の違いを吸収する。主にZend_Db_Adapter::query()をファクトリとしてインスタンスを取得する |
| Zend_Db_Select | オブジェクト操作によるSELECTステートメントを組み立てるためのビルダクラスで、__toString()による文字列化でSQLステートメントを出力する |
| Zend_Db_Table | データベースの表(Table)を表現する抽象クラスで、Zend_DbにおけるO/Rマッピングを実現する。基本的にはDBMS上のテーブルと対になるクラスをZend_Db_Tableから派生させる。データベースへの問い合わせや更新もこのクラス(および関連のRow/Rowset)から行えるが、扱い方がZend_Db_AdapterやZend_Db_Statementと異なる点に注意 |
| Zend_Db_Table_Row | データベースの行(Row)を表現する抽象クラス。Zend_Db_Tableの操作により生成される。データベースの列(Column)に相当するプロパティを備えており、プロパティ値の変更 → save()メソッドの実行 で行を更新することができる。 |
| Zend_Db_Table_Rowset | 複数のZend_Db_Rowを扱うためのIteratorクラスで、Zend_Db_Tableによる問い合わせの結果として取得する。 |
アプリケーション構成
今回は「zdb1」という名前のアプリケーションを作成しましょう。構成はシンプルに、以下のようにします。
- htdocs/
- zdb1/
- application/
- controllers/
- IndexController.php
- views/
- index/
- index.phtml
- index/
- controllers/
- index.php
- .htaccess
- zdb1.db
- create_table.sql
- application/
- zdb1/
肝心のアプリケーションですが、ものすごくシンプルなブックマークにしてみます。以下の情報を扱うことにします。
- タイトル
- URL
- 登録日時
- コメント
| キー | カラム | 型 | 備考 |
|---|---|---|---|
| PK | id | INTEGER | AUTO INCREMENT |
| title | VACHAR (100) | ||
| IDX1 | url | VARCHAR (255) | |
| IDX2 | registDate | TIMESTAMP | |
| comment | TEXT |
データベースを作成する
まずはテーブルを作成する「create_table.sql」です。テーブル作成とインデックスの作成、初期データの挿入をしています。
CREATE TABLE bookmarks (
id INTEGER PRIMARY KEY,
title VARCHAR (100),
url VARCHAR(255),
registDate TIMESTAMP,
comment TEXT
);
CREATE INDEX idx_bookmarks_1 ON bookmarks(url);
CREATE INDEX idx_bookmarks_2 ON bookmarks(registDate);
INSERT INTO bookmarks
(
title,
url,
registDate,
comment
)
VALUES
(
'dara-j',
'http://dara-j.asablo.jp/blog/',
( select datetime('now') ),
'だらだらとしたブログ'
);
INSERT INTO bookmarks
(
title,
url,
registDate,
comment
)
VALUES
(
'dara-clip',
'http://dara-j.tumblr.com/',
( select datetime('now') ),
'dara-jのtumblr。ぬこ分多目。'
);
作成したcreate_table.sqlをsqlite3で以下の要領で実行する手順です。 まずは今回のアプリケーションディレクトリからコマンドプロンプトを起動します。この例では D:\wwwroot\zdb1 がそれにあたります。そして、そこからsqlite3を実行します。
D:\wwwroot\zdb1>sqlite3 zdb1.db SQLite version 3.4.2 Enter ".help" for instructions sqlite>次に、「.read」コマンドで、先ほど作成したcreate_table.sqlを実行します。
sqlite> .read create_table.sql
sqlite>
.readコマンドはエラーがなければなにも表示しないので、sqlite_master(メタデータテーブル)を確認してみます。
sqlite> select * from sqlite_master;
table|bookmarks|bookmarks|2|CREATE TABLE bookmarks (
id INTEGER PRIMARY KEY,
title VARCHAR (100),
url VARCHAR(255),
registDate TIMESTAMP,
comment TEXT
)
index|idx_bookmarks_1|bookmarks|3|CREATE INDEX idx_bookmarks_1 ON bookmarks(url)
index|idx_bookmarks_2|bookmarks|4|CREATE INDEX idx_bookmarks_2 ON bookmarks(regi
stDate)
sqlite>
テーブル・2つのインデックスとも定義されていればOKです。ついでに同時に実行したinsertが正常にできているかを、以下のように確認します。
sqlite> select * from bookmarks; 1|dara-j|http://dara-j.asablo.jp/blog/|2007-09-23 05:01:25|だらだらとしたブログ 2|dara-clip|http://dara-j.tumblr.com/|2007-09-23 05:01:25|dara-jのtumblr。ぬこ分 多目。 sqlite>datetime()関数は、CURRENT_TIMESTAMPと同様にロケールを考慮しないので、GMTでデータが挿入されてしまいますが、これは初期データなのでまぁ気にしないでください(^^; 確認できたらsqlite3を終了しましょう。
sqlite> .quit
データベースへ接続の接続と基本的な問い合わせ
今度はPHP側のコードを作成していきましょう。まず起動スクリプト「index.php」ですが、これは「ZendFramework入門・その2 アクションメソッドの追加とリンクの扱い方」で決定したものをそのまま流用できます(つまり、zf2のもの)。
IndexControllerは次のようになります。
<?php
require_once 'Zend/Controller/Action.php';
// Zend_Dbをrequre
require_once 'Zend/Db.php';
// IndexController
class IndexController extends Zend_Controller_Action {
// initメソッド。初期化処理用のフックメソッド
// アクセスレベルが「public」な点に注意
public function init() {
// リクエストオブジェクト(Zend_Controller_Request_Abstract)を取得
$request = $this->getRequest();
// ベースURLを取得
$baseUrl = getApplicationUrl( $request );
// ビューへ割り当てる
$this->view->assign( 'baseUrl', $baseUrl );
}
// indexアクション
public function indexAction() {
// Zend_Db_Adapterを生成
$db = Zend_Db::factory(
// Zend_Db_Adapter_Pdo_Sqlite クラスを使用する
"Pdo_Sqlite",
// 生成パラメータ。SQLiteは接続先を示す'dbname'のみでOK
array(
'dbname' => 'zdb1.db'
)
);
// SELECTステートメントを実行
$result = $db->fetchAll( 'SELECT * FROM bookmarks ORDER BY registDate DESC' );
// 実行結果をビューへ割り当てる
$this->view->assign( 'rows', $result );
}
}
- Zend_Dbを使用するために、'Zend/Db.php'をrequireしている
- Zend_Db_Adapterを取得するためにZend_Db::factoryスタティックメソッドを使用している
- Zend_Db_Adapter::fetchAll()メソッドでSQLステートメントを実行している
クラス名は暗黙で「Zend_Db_Adapter_」プレフィックスがつけられますので、今回の例の「PdoSqlite」はZend_Db_Adapter_Pdo_Sqlite」を作成することを意味しています。
第二引数の初期化パラメータ配列ですが、SQLiteの場合は他のオプションがほとんどないのでキー'dbname'のみを指定していますが、他のDBMSの場合は「username」「password」などがあります。たとえばローカルで動作しているMySQLのスキーマ「mydb」に接続する場合は以下のようになります。
$db = Zend_Db::factory( "Pdo_MySql", array( 'host' => 'localhost', // 接続するMySQLサーバのホスト名 'dbname' => 'mydb', // 接続するデータベース(スキーマ) 'username' => 'mysqluser', // 接続するユーザID 'password' => 'passwd' // 接続パスワード ) );
そして、index.phtmlです。まずは、Zend_Db_Adapter::fetchAll()が何を返すのかを単純に確認するため、以下のようにvar_dump()を使ったシンプルな実装をしてみましょう。(手抜き、ともいう)
<html> <head> <title>zdb1</title> <!-- base要素の出力。末尾の「/」に注意 --> <base href="<?php echo $this->baseUrl; ?>/"></base> </head> <body> <h3> bookmarksの内容 </h3> <hr> <!-- var_dumpしてみる --> <pre> <?php var_dump( $this->rows ); ?> </pre> </body> </html>
bookmarksの内容
array(2) {
[0]=>
array(5) {
["id"]=>
string(1) "2"
["title"]=>
string(9) "dara-clip"
["url"]=>
string(25) "http://dara-j.tumblr.com/"
["registDate"]=>
string(19) "2007-09-23 05:01:25"
["comment"]=>
string(28) "dara-jのtumblr。ぬこ分多目。"
}
[1]=>
array(5) {
["id"]=>
string(1) "1"
["title"]=>
string(6) "dara-j"
["url"]=>
string(29) "http://dara-j.asablo.jp/blog/"
["registDate"]=>
string(19) "2007-09-23 05:01:25"
["comment"]=>
string(20) "だらだらとしたブログ"
}
}
これを単純なテーブル表示にするには、index.phtmlを以下のように変更します。
<html>
<head>
<title>zdb1</title>
<!-- base要素の出力。末尾の「/」に注意 -->
<base href="<?php echo $this->baseUrl; ?>/"></base>
</head>
<body>
<h3>
bookmarksの内容
</h3>
<hr>
<!-- テーブルで表示 -->
<table border="1" cellpadding="0" cellspacing="0">
<?php
foreach( $this->rows as $i => $row ) {
if( $i == 0 ) {
// 最初の行のみ
?>
<tr>
<?php
// ヘッダ行出力
foreach( $row as $key => $value ) {
echo '<th>' . $this->escape( $key ) . '</th>';
}
?>
</tr>
<?php
// if 終わり
}
?>
<tr>
<?php
// 行出力
foreach( $row as $key => $value ) {
echo '<td>' . $this->escape( $value ) . '</td>';
}
?>
</tr>
<?php
// foreach終わり
}
?>
</table>
</body>
</html>
実行結果は各自で確認してみてください。
Zend_Db_Adapter::fetchAll
参考までにですが、Zend_Db_Adapter::fetchAllについて少し解説します。Zend_Db_Adapter::fetchAllメソッドは以下のように定義されています。
/**
* Fetches all SQL result rows as a sequential array.
* Uses the current fetchMode for the adapter.
*
* @param string|Zend_Db_Select $sql An SQL SELECT statement.
* @param mixed $bind Data to bind into SELECT placeholders.
* @return array
*/
public function fetchAll($sql, $bind = array())
そして、肝心の処理内容は、以下のように記述されています。
$stmt = $this->query($sql, $bind);
$result = $stmt->fetchAll($this->_fetchMode);
return $result;
あとがき&次回予告
ともかくデータベースの内容を表示するところまでやってみましたが、いかがでしたでしょうか?
このままでは面白くもなんともないので、次回はこれにデータを追加する機能を作成してみたいと思います。そのために「Zend_Db_Table」の解説をする予定です。
それではまた次回。
仮想メモリの情報? ― 2007年09月23日 16時32分45秒
久々のトラバネタ。こんなタイトル。
仮想メモリ最適または設定、増やし方紹介します
はい、例によってsbloです。AutoPagerizeの記事へのトラバでした。メモリ消費がすごい
とかに反応したのか?
なんでも、
仮想メモリの最適または設定や増やし方を紹介していきます。 初心者必見です。わかりやすく解説します。だそうな。わかるようなわからんような、微妙な日本語っぷりがスパムたる所以でしょうか。
どっかからのコピペなんだろうけど、わりと充実気味のコンテンツでした。相変わらず意味わからん。

最近のコメント