カテゴリー : web & pc

携帯サイトでinputタグに入力制限をかける方法

携帯サイトに関わることはほとんどなかったのですが、
今回少しだけページを作る際に勉強になったことをメモ。

携帯でテキストの入力フォームに入力するとき、全角文字とか半角英数字とか
入力モードを切り替えるのってかなり面倒ですよね。
入力状態を最初から適切なものに変更させているとかどうしてるんだろう?
ってことで調べてみたら、すぐに出てきました。インターネット便利ですね。

1
2
3
4
5
// 半角英数字のみにする場合
<input type="text" istyle="3" format="*x" MODE="alphabet"  />
 
// 半角数字のみにする場合
<input type="text" istyle="4" format="*N" MODE="numeric"  />


こちらのサイトで知りました。
http://kidokorock.com/2009/06/webtips/携帯フォームに半角数字だけ半角英数字の入力制.html
ありがとうございます。

あと、驚いたのが input タグの type=”button” が携帯だとtype=”text”のように表示されること。
これを解決する方法ってないようで、type=”button”は利用されていないようです。

VMをつくり直すときに役に立ったサイト

プログラムテスト環境として利用していたVMのハードディスク容量が足りなくなったので、新たに作り直しました。前回は勉強のためとソースからコンパイルして作ったんですが、今回はyumを使った方法を試してみることに。

途中うまく動かない箇所があったんですが、yumリポジトリを変えて再度構築しなおしたら、意図通りに動作する環境ができあがりました。そのときに参考にしたサイトを忘れないようにメモです。

いくつかのサイトを参考にしながら作成しましたが、うまくいったのはこのサイトの方法で構築したときでした。
【VMware Player上のCentOSに開発環境を構築 #2CommentsAdd Star】
http://rewish.org/php_mysql/vm_player_config_2

Gitのインストールの際に参考にしたサイト
【centos5.3でyumを使ってgitをインストールする】
http://d.hatena.ne.jp/uk_oasis/20090807/1249633626


ついでに調べた、Gitのクライアント。
【tortoiseGit】 tortoiseSVNのgit版。Win専用。
http://code.google.com/p/tortoisegit/

【SmartGit】 Win、Mac、Linuxに対応
http://www.syntevo.com/smartgit/index.html
Gitだけじゃなくて、CSV、SVNのクライアントも。慣れたら同じ使い勝手で全部いけるとしたら一番いいのかも。

【Gitti】 Mac専用。画面がいい感じ。
http://www.gittiapp.com/

WordPressのカスタムポストが便利っぽい

以前ZendFramework勉強会でご一緒させていただいたNullyさん(http://blog.nully.org/)がTwitterでつぶやかれていた”カスタムポスト”という言葉を見ました。

前後の投稿からWordPress関連なのはわかったのですが、どういうものかさっぱり???なので、質問してみると、機能の内容を教えていただいて、参考サイトまで教えてもらいました。それがこちら。
http://wpxtreme.jp/how-to-use-custom-post-types-in-wordpress-3-0-beta1

うん便利そう。作る側よりも使う側が便利そう。
今度、友達になんか頼まれごとしたときに利用できそうならやってみようと思います。
カテゴリ選んでーとかよりも理解しやすいですよね。きっと。

このブログ、WordPressのtipsがいっぱいあって超いいです。
http://wpxtreme.jp/how-to-use-cusom-taxonomy-with-wordpress-versions-lower-than-3
これとか勉強になります。タクソノミーって、確かに自分で使ってみようってしてなかったので。

safariの機能拡張一覧

safari5から機能拡張(firefoxのアドオンみたいなの)が利用できるようになると、どこかで読んだ気がしてたのですが、アップルのサイト内に一覧ページができてました。

http://extensions.apple.com/

早速Gmail関連のもの、firebugs、delicious関連のものを導入。
他のものも英語しか説明がないので、ぼちぼち試していこうと思っています。

safariでtumblr投稿できる機能拡張

今、メインのブラウザはfirefoxなので、Tumblrへの投稿は、http://journal.mycom.co.jp/series/tumblr/010/index.htmlで見つけた「Tumblr Post」というアドオンを使っています。

こういう簡単にTumblrに投稿できるものがsafariにもないのかなと検索して、http://www.moongift.jp/2010/05/tumblrful/を見つけました。

導入手順は、こんな感じ。
1. SIMBLを導入する
 http://www.culater.net/software/SIMBL/SIMBL.phpからダウウンロードしてきて、.pkg をダブルクリックしてインストール

2. Growlを導入する
 http://growl.info/からダウンロードしてきて、.pkg をダブルクリックしてインストール

3. Tumblrfulを導入
 http://github.com/yamaya/Tumblrful/tree/master//Release/から”Tumblrful.bundle”ダウンロードして、”Macintosh HD”=>”ライブラリ”=>”Application Support”=>”SIMBL”=>”Plugins”を開いて、ここに置きます。

4. safariを再起動

これで、右クリックメニューにTumblrの投稿ができるようになります。
Tumblr Postのように投稿時にタグを指定したときは、右クリックメニューの”Share….”から投稿すると、タグなどを入力できる画面が現れます。”Share – Link”とかを使うと、タグも何も指定されずにすぐに投稿されてしまうので、タグ管理している方はご注意ください。


「Tumblrful」を見つけている途中に見つけたfirefoxのアドオン「tumboo」もよさそう。
http://www.moongift.jp/2008/04/tombloo/

Xmarksが2011年1月でサービス終了

人に教えてもらってから、愛用していたブックマーク同期サービスXmarks。
Gmailと同じくらいなくては困るものになっていたんですが、来年頭でサービス停止という知らせがきました。こんな便利なサービスなのに残念です。

会社で2台のPCを利用しているので、それらのブックマークを同期させていたのです。
同じような同期サービスがないか調べてみたところないようです。
firefox同士、chrome同士なら同期できるよう。
http://mozilla.jp/blog/entry/5633/(firefox)
http://tokuna.blog40.fc2.com/blog-entry-1862.html(chrome)
http://googlejapan.blogspot.com/2010/01/google-chrome-40-web.html(chrome)

safariは現在のところブックマークを同期する方法は、MobileMeを利用する(有料)のみのよう。
http://plaza.rakuten.co.jp/macevan/diary/20080915/

異なるブラウザ間で同期させる方法はないようなので、これを機にメインブラウザを何にするかを考える人も増えそうです。気分で今日はこっちーってやっても、ブックマークがないのですから。

Macならこういうツールもありました。
ツールを通して、異なるブラウザのブックマークを一度に参照でき、ブックマークを選択すると、ブックーマクデータをもっているブラウザが起動されるそうです。
http://www.moongift.jp/2007/12/allbookmarks/
http://agilewebsolutions.com/

Xmarksと同等の機能を持つサービスが早くでてきてほしいですね。

MySQL複合INDEXの威力

予想以上の効果がでたので記事に残します。
DBの情報を元に統計を行うSQLとプログラムの性能改善で、複合INDEXを試してみました。
MySQLは、4.2です。

対象となったSQLは複数ありますが、そのうちほとんどは4つのテーブルをJOINしています。取得条件を変えながら情報を取得し、最後に目的別に合算するっていうことをやっています。4つのテーブルのうち3つはデータ数200万オーバー、1つは100万オーバー。

最初は、こんな状態

1
2
3
4
5
6
7
8
+----+-------------+-------+--------+----------------------------------------------+
| id | select_type | table | type   | Extra                                        |
+----+-------------+-------+--------+----------------------------------------------+
|  1 | SIMPLE      | tb    | range  | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | tc    | ref    | Using where                                  |
|  1 | SIMPLE      | tp    | ref    | Using where                                  |
|  1 | SIMPLE      | td    | eq_ref | Using where                                  |
+----+-------------+-------+--------+----------------------------------------------+


まずは、一番最初に検索されている tb に複合インデックス(検索条件カラム、取得カラム全部、合計11カラム)を設定してみるも結果変わらず。カラムを検索条件だけにしてみたり、更に減らしたりと試すも結果変わらず。

とりあえず、最初に設定した複合インデックスを設定して、tcにも複合インデックス(全8カラム)を設定してみる。

すると変化が現れた。

1
2
3
4
5
6
7
8
+----+-------------+-------+--------+----------------------------------------------------------+
| id | select_type | table | type   | Extra                                                    |
+----+-------------+-------+--------+----------------------------------------------------------+
|  1 | SIMPLE      | tc    | ref    | Using where; Using index Using temporary; Using filesort |
|  1 | SIMPLE      | tb    | ref    | Using where                                              |
|  1 | SIMPLE      | tp    | ref    | Using where                                              |
|  1 | SIMPLE      | td    | eq_ref | Using where                                              |
+----+-------------+-------+--------+----------------------------------------------------------+


tc に設定したINDEXが利用されてuse indexが出てきたのはわかるが、テーブルをJOINする順番が変わっている!!気になって、tb に設定した複合INDEXを削除すると、またtb からJOINされるようになった、possible key(利用可能index)にはいて、key(利用index)にはでてこないけど、なんらかの影響は及ぼしているようだ。

td tpにも同じ要領で検索対象、取得対象のカラムに複合INDEXを設定する。その結果、td tpにもuse indexが表示されるようになった。

1
2
3
4
5
6
7
8
+----+-------------+-------+------+----------------------------------------------------------+
| id | select_type | table | type | Extra                                                    |
+----+-------------+-------+------+----------------------------------------------------------+
|  1 | SIMPLE      | tc    | ref  | Using where; Using index Using temporary; Using filesort |
|  1 | SIMPLE      | tb    | ref  | Using where                                              |
|  1 | SIMPLE      | tp    | ref  | Using where; Using index                                 |
|  1 | SIMPLE      | td    | ref  | Using where; Using index                                 |
+----+-------------+-------+------+----------------------------------------------------------+


だが、肝心のusing temporary、using filesortが消えない。using filesortって、今回のSQLにはgroup by は入っているけど、order byは入っていない。いくつかサイトを見たけど、order by には言及してあるものが多かった。そこで、order by をgroup by に読み替えて、実験してみることにした。
http://www.mysqlpracticewiki.com/index.php/Extra_field
上記のサイトと、リンク先を読んでいて今回のケースに当てはまりそうなものは、最初にJOINされるテーブルではないカラムで、group by を掛けていること。tbのカラムでかけていた。
幸いtc tbは1対1対応のテーブルでで、group by をtc のカラムでかけても取得結果は変わらないので、試してみることに。

その結果がこれ

1
2
3
4
5
6
7
8
+----+-------------+-------+------+--------------------------+
| id | select_type | table | type | Extra                    |
+----+-------------+-------+------+--------------------------+
|  1 | SIMPLE      | tc    | ref  | Using where; Using index |
|  1 | SIMPLE      | tb    | ref  | Using where              |
|  1 | SIMPLE      | tp    | ref  | Using where; Using index |
|  1 | SIMPLE      | td    | ref  | Using where; Using index |
+----+-------------+-------+------+--------------------------+


消えた!やった!
ってことで、実行されるSQL(20ちょいくらい)にexplainをかけてみた。サブクエリ以外でexplainをとってみると、ほとんどのものでusing temporary、using filesortが消えていた。消えなかったのは、取得したいデータの量的にどうしようもなさそうなもの(データの半分以上を一旦取得するもの)くらい。

これで統計プログラムを実行したところ、実行時間が40分オーバーから5分前後へ!
かなり早くなった。予想以上の結果にびっくりしたので、メモ!

複合INDEXについては、以下のサイトも参考にさせていただきました。
http://d.hatena.ne.jp/k_yamamot/20100831/1283262245
http://txqz.net/blog/2006/12/13/0943
http://dev.seesaa.net/article/238633.html

Macで使えるメモツール

会社ではWin、家ではMacをメインで使っていますが、Winで使っている「紙copi」のようなメモツールが必要になったので、探してみたところ見つけたのが「JustNote」。

「紙copi」のようにフォルダは作れないけれど、あとは同じような使い方ができます。
もともとがほんとにメモ用で、TipsとかSQLの例とか、仕事の思いつきのまとめとかに使っていたので、その範囲内(テキストメモ)での使い勝手が似たようなもんってことです。
Webページの貼り付けとかにはつかってなかったので、そのあたりはよくわかりません。

紙copi Netの利用も考えたのですが、パスワードが分からないと閲覧されないはずとはいえ、ネット上に置いてていいのか?と思える内容もあるので、今回は対象外としました。とはいえ、なんかで使えるかもしれないと思って、アカウントだけは作成しました。

ネット上のメモツールは、Quill.toを使ってたんですが、特にここが不便って思ったりしないまま、あまり使わなくなり、紙copi に全部書くようになっていったんです。iPhoneもAndroid端末も持っていない今だと、家でも会社でも常に更新したいような事柄がない限り、ネット上に保存して共有できるメリットよりも、ブラウザ立ち上げて認証するっていう手間のデメリットが大きく感じる気がします。プログラムの仕様をまとめるときとかには重宝してました。

なので、JustNoteもネット上のメモサービスであるSimpleNoteと同期をとるっていう機能がついていますが、SimpleNoteとは連携せずに使っていくつもりです。

iPhoneとかもっていて、PCでもiPhoneでも、iPadでも全部からアクセスしたいって方にはいいかもしれません。クライアントも充実しているようです。
http://simplenoteapp.com/downloads/

Zendを使ってZip解凍

以前、Zendを使ってZip圧縮という記事を書きましたが、今回は逆のZendを使ってZip解凍についてです。

前回は、Zend_Filter_Compressというクラスを使いましたが、今回はZend_Filter_Decompressというクラスを使います。
使い方は以下です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$filter = new Zend_Filter_Decompress('Zip');
$filter->setArchive('圧縮ファイルのパス付ファイル名')
    ->setTarget('圧縮ファイルの解凍先ディレクトリパス');
$filter->filter('hoge');   // hogeはnullじゃなければ何でもいいです。
 
または
 
$filter = new Zend_Filter_Decompress('Zip');
$filter->setTarget('圧縮ファイルの解凍先ディレクトリパス');
$filter->filter('圧縮ファイルのパス付ファイル名');
 
または
 
$filter = new Zend_Filter_Decompress(array(
            'adapter' => 'Zip', 
            'options' => array(
                            'archive' => '圧縮ファイルの解凍先ディレクトリパス', 
                            'target'   => '圧縮ファイルの解凍先ディレクトリパス'
                         )
));
$filter->filter('hoge');   // hogeはnullじゃなければ何でもいいです。
 
または
 
$filter = new Zend_Filter_Decompress(array(
            'adapter' => 'Zip', 
            'options' => array('target'   => '圧縮ファイルの解凍先ディレクトリパス')
));
$filter->filter('圧縮ファイルのパス付ファイル名');
 
または
 
$filter = new Zend_Filter_Decompress();
$filter->setAdapter('Zip')
       ->setAdapterOptions(array(
             'archive' => '圧縮ファイルの解凍先ディレクトリパス', 
             'target'   => '圧縮ファイルの解凍先ディレクトリパス'))
       ->filter('hoge');    // hogeはnullじゃなければ何でもいいです。


解凍、圧縮共に Zip の部分を Gz, Lzf, Rar, Tar, Bz2 に変更するとそれぞれの形式で圧縮解凍ができます。
今回疑問に思ったのは(何で前回思わなかったのか。。)、なんで、こんな感じでかけないのかということ。

1
2
3
4
5
6
7
8
9
10
$filter = new Zend_Filter_Decompress('Zip');
$filter->setArchive('圧縮ファイルのパス付ファイル名')
    ->setTarget('圧縮ファイルの解凍先ディレクトリパス');
       ->filter();
 
または
 
$filter = new Zend_Filter_Decompress('Zip');
$filter->setTarget('圧縮ファイルの解凍先ディレクトリパス');
       ->filter('圧縮ファイルのパス付ファイル名');


不思議に思ってプログラムを観てみると、setTargetとかsetArchiveから返ってきているオブジェクトが、Zend_Filter_Decompressではなくて、Zend_Filter_Decompress内部で持っているZip処理のアダプターZend_Filter_Compress_Zipでした。
Zend_Filter_Compress_Zipにはfilterっていうメソッドはないので、エラーがでてたんですね。

Zend_Filter_Decompressの中で、

1
2
3
4
5
6
7
8
9
10
    public function __call($method, $options)
    {
        $adapter = $this->getAdapter();
        if (!method_exists($adapter, $method)) {
            require_once 'Zend/Filter/Exception.php';
            throw new Zend_Filter_Exception("Unknown method '{$method}'");
        }
 
        return call_user_func_array(array($adapter, $method), $options);
    }


ってなっている部分を

1
2
3
4
5
6
7
8
9
10
11
    public function __call($method, $options)
    {
        $adapter = $this->getAdapter();
        if (!method_exists($adapter, $method)) {
            require_once 'Zend/Filter/Exception.php';
            throw new Zend_Filter_Exception("Unknown method '{$method}'");
        }
 
        call_user_func_array(array($adapter, $method), $options);
        return $this;
    }


ってしたら、やりたい書き方ができそうだけど、どんな弊害があるのかは細かく調べてないのでわかりません。ざっとみたところなさそう。アダプター使いたいなら、getAdapterで取得できるので、不具合もなさそう。なんで、アダプターを返すような作りにしたんだろう?読み取れてない意図があるのかな。

ZendでDbのMeta情報をキャッシュする

なんのこっちゃ?って感じですよね。僕もそう思います。

ZendFrameworkを利用する場合、Zend_Db_Table(Row、Rowsetも)を利用することが多いと思います。Zend_Db_Table_Abstractを継承して、テーブル名と他テーブルとのリレーションを定義するだけで、DBの登録、更新、削除ができてしまう優れものです。個人的にはこれだけ、ZendFrameworkを使ってみようってきっかけになりました。

これらがテーブル名とリレーションだけしか定義してないのに、存在しないカラム名を指定して処理しようとすると、”そんなカラムはないよ!”ってエラーを出してくれます。賢いです。これができるのって、テーブル関連の処理をするたびに”describe”が実行されて、テーブルの情報を取得しているからなのです。気がきいてます。

ただ1点、”describe”が実行される量が多すぎるんです。これが処理が遅くなる原因になることがあります。ここででてくるのがDbのMeta情報のキャッシュ。DbのMeta情報というのは、”describe”の実行結果です。なので、これをキャッシュとして保持しておくと、”describe”をしなくても、情報が手に入るため余計なSQLをDBに実行しなくてすみます。

たかが”describe”ですが、実行回数がほんとに多いので、だいぶ変わります。
Zend_Db_Table使うときは、セットで設定するくらいでいいのではと思っています。

Bootstrap.phpの中にこんな感じで書いておくと使えます。

1
2
3
4
5
6
7
    protected function _initDbCache()
    {
        $frontendOptions = array('automatic_serialization' => true);
        $backendOptions = array('cache_dir' => APPLICATION_PATH . 'cacheディレクトリへの相対パス');
        $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
        Pb_Db_Table_Abstract::setDefaultMetadataCache($cache);
    }

%d人のブロガーが「いいね」をつけました。