page_adsence

2010年12月30日木曜日

GULLWINGに乗ってみた感想

年末に初すべりを済ませてきたので、そのときに初めて乗った011 ArtisticのGULLWINGの感想です。

まず最初に思ったのはめっちゃ柔らかい!

オーリーがめっちゃしやすくて、高さも結構出ます。
バター系トリックも思ったとおり結構やりやすくていい感じです。
スピン系のトリックはまだ初すべりだったんでなんともいえない感じですが、
まぁそんなに問題がある感じではなかったです。

全体的にかなり調子いい感じなんですが1点だけ気になったのは、
ターンのときにエッジが刺さりすぎてるってとこです。
センター部分のエッジが雪面に引っかかりすぎて、思ったよりスピードが出ず、
バランスを崩してこけたりすることが何回かありました。
やっぱキャンバーとロッカーで構造が違うのでしょうがないですね。
その辺は慣れだと思いますんでこれから徐々に慣れて行きたいと思います。

とはいえかなり面白い!
相当楽しめる板であることには間違いないので、
今後はスピントリックを色々試してみて乗り味をレビューできたらと思います。

2010年12月27日月曜日

MySQLのmy.cnfの設定に関して

今日会社でたまたま話題に出たので調べてみた。

前の会社ではmy.cnfの設定なんて全く触ってなかったですが、
どういう設定がいいのか調べてみたら、結構いろいろ出てきた。

一応設定例を以下に示す。
ここにあったのをまるっと頂いてきました。

OLTPでメモリ8GB/InnoDBがメインの場合
[mysqld]
# basic settings
port = 3306
socket = /tmp/mysql.sock
user = mysql
character-set-server = utf8
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /var/tmp/mysql
core-file

# buffers
key_buffer = 128M
max_allowed_packet = 16M
table_cache = 1024
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 2M
myisam_sort_buffer_size = 64M
max_connections = 512
thread_cache_size = 128
query_cache_size = 0

# binlog and replication
log-bin = mysql-bin
server-id = 1
max_binlog_size = 256M
# if the system is the master, comment out the following line.
# sync_binlog=1

# InnoDB configurations
innodb_buffer_pool_size=6G
innodb_additional_mem_pool_size=20M
innodb_flush_method=O_DIRECT
innodb_log_file_size=256M
innodb_log_files_in_group=2
innodb_log_buffer_size=64M
innodb_flush_log_at_trx_commit=1


OLTPでメモリ2GB/InnoDBがメインの場合
[mysqld]
# basic settings
port = 3306
socket = /tmp/mysql.sock
user = mysql
character-set-server = utf8
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /var/tmp/mysql
core-file

# buffers
key_buffer = 64M
max_allowed_packet = 10M
table_cache = 512
sort_buffer_size = 1M
read_buffer_size = 256K
read_rnd_buffer_size = 1M
myisam_sort_buffer_size = 64M
max_connections = 300
thread_cache_size = 100
query_cache_size = 0

# binlog and replication
log-bin = mysql-bin
server-id = 1
max_binlog_size = 256M
# if the system is the master, comment out the following line.
# sync_binlog=1

# InnoDB configurations
innodb_buffer_pool_size=1400M
innodb_additional_mem_pool_size=20M
innodb_flush_method=O_DIRECT
innodb_log_file_size=256M
innodb_log_files_in_group=2
innodb_log_buffer_size=64M
innodb_flush_log_at_trx_commit=1


Webのバックエンドでメモリ2GB/MyISAMのみの場合
[mysqld]
# basic settings
port = 3306
socket = /tmp/mysql.sock
user = mysql
character-set-server = utf8
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /var/tmp/mysql
core-file

# buffers
key_buffer = 512M
max_allowed_packet = 10M
table_cache = 4096
sort_buffer_size = 1M
read_buffer_size = 256K
read_rnd_buffer_size = 1M
myisam_sort_buffer_size = 64M
max_connections = 512
thread_cache_size = 128
query_cache_size = 64
query_cache_type = ON

# binlog and replication
log-bin = mysql-bin
server-id = 1
max_binlog_size = 256M
# if the system is the master, comment out the following line.
# sync_binlog=1

skip-innodb


Linuxの場合は、sysctl.confにおいて以下の設定をすること。

といった感じ。
どういった基準でこうなったのかは全く書いてないので、
とりあえず今回話題に上がったinnodb_buffer_pool_sizeに関して調べてみた。

グローバルバッファ
InnoDBのデータやインデックスをキャッシュするためのメモリ上の領域
OS自身がキャッシュしない。
実装メモリの70-80%を目安に設定

innodb_buffer_pool_size=XXX

テーブルやインデックスデータをメモリに展開する際の上限
これを適正な値に引き上げることにより
Disk I/O が減らせ全体的なパフォーマンスアップにつながる。

ってことらしい。
http://www.sapa.ne.jp/manual-mysql51/storage-engines.html
このページ見ると「専用のデータベース サーバ上で、これをマシンの物理的メモリ サイズの最大80% に設定すると良いでしょう。」って書いてあるけど、
「物理的メモリの競合が OS 内でページングを引き起こす可能性があるので、あまり大きく設定しないでください。」とも書いてあって、結局どの位が適正なのかはわからない。

チケット駆動開発に利用されるツール

redmineとtracがメジャー
他にもMantisやcandycane(redmineのPHP版)等もある。

CentOS5.5にSubversionを導入

社内でバージョン管理されていないプロジェクトが以外と多いことを知ったので、
とりあえず自分だけでもバージョン管理をしようと思い、
VMWare上のCentOSにSubversionをインストールすることにした。

今回の要件はこんな感じ。
・subversionのインストール
・WebDAV経由でリポジトリにアクセスできるようにする
・ディレクトリごとに細かくアクセス制限をかける

リポジトリ内のディレクトリ構成は以下のような感じを想定して作ってみる。

/path/to/dir
    └ projects
          ├ project_name
          │      ├ trunk
          │      ├ branches
          │      └ tags
          │
          └ project_name
                  :
                  :


今回自分の環境ではもともとsubversionがインストール済みであったが、
念のためインストールからの手順を示す。(rootユーザー)
といってもyumでインストールするだけなので、特に問題ないかと。
# yum install subversion ← Subversion本体
# yum install mod_dav_svn ← WebDAV


インストールが完了したら、リポジトリ用のディレクトリを切ってからリポジトリの作成
apache経由でアクセスするのでapacheから書き込めるようにオーナーをapacheにしておく。
# mkdir /path/to/dir/projects
chown apache:apache /path/to/dir/projects
# svnadmin create /path/to/dir/projects


そっからWebDAVでアクセスできるようにする。
ここでちょっとはまった。
いろんなサイトを見て回ったけど、モジュールの読み込み部分について触れてないブログが結構多くて、
gracefulで文法チェックするとエラーになってしまっていた。
WebDAVを使用する場合は以下の「mod_dav_svn.so」のモジュールを読み込んであげないとエラーになってしまう。
また、「mod_authz_svn.so」はディレクトリごとに細かくアクセス制限をかけることができるようになるモジュール。
ユーザーを作成し、ディレクトリごとに読み書きを制御できるようになる。
個人で使用する分にはまず必要ないが、勉強のためこれも組み込む。

ディレクトリごとにアクセス制限をかけるための設定ファイル(authzsvn.conf)をsubversion.confで読み込むので、
まずはそのファイルの作成をする。
# vi /path/to/dir/project/authzsvn.conf

[groups] ← グループの管理をしている部分の記述開始
#開発者
developers = kusagaya ← グループ名 = ユーザー名
test = userA, userB, userC

#管理者
manager = kusagaya

[/] ← ディレクトリごとのアクセス制限
#すべての人が読み込み可能
* = r

[projects:/trunk]
#開発者は読み書き可能
@developers = rw

[projects:/branches]
#管理者は書き込みも可能
@manager = rw

[projects:/tags]
#管理者は書き込みも可能
@manager = rw


この設定ファイルに関してのドキュメントが見つからなかったので、とりあえずコピペしたのをおく。

# vi /etc/httpd/conf.d/subversion.conf

LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

<VirtualHost *>
    ServerAdmin your_mail_address
    DocumentRoot /path/to/dir/projects
    ServerName your_server_name
    ErrorLog /path/to/dir/logs/error_log
    CustomLog /path/to/dir/logs/access_log common
    <Location /svn>
        DAV svn
        SVNPath /path/to/dir/projects←svnadminコマンドで作成したリポジトリのディレクトリ

        # our access control policy
        AuthzSVNAccessFile /path/to/dir/projects/authzsvn.conf←mod_authz_svnによるアクセス制限の設定ファイルのパス

        以下はただのBasic認証
        # only authenticated users may access the repository
        Require valid-user

        # how to authenticate a user
        AuthType Basic
        AuthName "Subversion repository(sample)"
        AuthUserFile /path/to/dir/projects/.htpasswd
    </Location>
</VirtualHost>


問題なさそうならapacheの設定ファイルをリロード。
# /etc/rc.d/init.d/httpd reload


これで一応WebDAV経由でアクセスできるようになったはず。

参考文献
http://park1.wakwak.com/~ima/centos4_subversion0001.html

2010年12月22日水曜日

PHP5のabstract class(抽象クラス)に関して

PHP5から追加された機能に抽象クラスを作成できるようになったが、
今まで全く使っていなかったので、ちょっと勉強してみた。

抽象クラスはインスタンス化できないクラスで、必ず継承して使用するようにしているクラスのこと。
抽象メソッドは、抽象クラス内に定義しておくことで、継承クラス内で必ずその関数を作らないといけないようになり、抽象クラスを拡張した形で継承クラス内に処理を記述することができる。

参考文献
http://f3.aaa.livedoor.jp/~matukazu/php5/php5_abstract.php

oracleのインストール(Linux版)

初oracleインストールしたので、その時のメモ。
基本的には以下の通り。
http://blog.goo.ne.jp/h-mori/e/132867c006097f60a35d7ec937dbaed5

最初に設定されているユーザーがrootじゃなくてsystemユーザーってことにビックリ。
ユーザー名がわからなくて、ログインできないかと思った…。

2010年12月21日火曜日

PHP5のfgetcsvに関して

PHP5でShift-JISでエンコードされているcsvファイルをfgetcsvを使うと文字化けしてしまうらしい。
文字コードがSJISのデータを処理させた時に、「"機能"」などというデータがあった場合、「能」の2バイト目が「5C(\)」であるため「"」の部分が「\"」と扱われてエスケープされてしまい、データが正しく取得できないのだ。エスケープ文字として処理された結果「5C」の部分は消えてしまい、結果、データが文字化けしてしまう。
こういった現象を回避するためにyossyさんという方が、fgetcsv_regというバグを取った版の関数を作ってくれている。
が、壊れたcsvや画像ファイルを無理やり読み込ませると無限ループに陥るという欠点がある。
それを修正した版は以下の通り。

<?php
    /**
     * ファイルポインタから行を取得し、CSVフィールドを処理する
     * @param resource handle
     * @param int length
     * @param string delimiter
     * @param string enclosure
     * @return ファイルの終端に達した場合を含み、エラー時にFALSEを返します。
     */
    function fgetcsv_reg (&$handle, $length = null, $d = ',', $e = '"') {
        $d = preg_quote($d);
        $e = preg_quote($e);
        $_line = "";
        while (($eof != true)and(!feof($handle))) {
            $_line .= (empty($length) ? fgets($handle) : fgets($handle, $length));
            $itemcnt = preg_match_all('/'.$e.'/', $_line, $dummy);
            if ($itemcnt % 2 == 0) $eof = true;
        }
        $_csv_line = preg_replace('/(?:\\r\\n|[\\r\\n])?$/', $d, trim($_line));
        $_csv_pattern = '/('.$e.'[^'.$e.']*(?:'.$e.$e.'[^'.$e.']*)*'.$e.'|[^'.$d.']*)'.$d.'/';
        preg_match_all($_csv_pattern, $_csv_line, $_csv_matches);
        $_csv_data = $_csv_matches[1];
        for($_csv_i=0;$_csv_i<count($_csv_data);$_csv_i++){
            $_csv_data[$_csv_i]=preg_replace('/^'.$e.'(.*)'.$e.'$/s','$1',$_csv_data[$_csv_i]);
            $_csv_data[$_csv_i]=str_replace($e.$e, $e, $_csv_data[$_csv_i]);
        }
        return empty($_line) ? false : $_csv_data;
    }
?>

使い方は以下の通り。

<?php
    $row = 1;
    $handle = fopen("test.csv", "r");
    while (($data = fgetcsv_reg($handle)) !== false) {
        $_enc_to=mb_internal_encoding();
        $_enc_from=mb_detect_order();
        mb_convert_variables($_enc_to,$_enc_from,$data);
        $num = count($data);
        echo "

$num fields in line $row:

\n"; $row++; for ($c=0; $c < $num; $c++) { echo nl2br($data[$c]) . " \n"; } } fclose($handle); ?>

携帯のFormタグのaction属性に関して

PCブラウザでactionが空の場合は、自分自身にリクエストを送るような感じになっているが、
携帯の場合はそうもいかないらしい。

例)actionが空で/hoge/fuga.phpのformをsubmitした場合
PC…/hoge/fuga.phpにリクエストが飛ぶ
携帯…/hoge/にリクエストが飛ぶ

SoftbankのC型と言われる携帯だけと書いてある記事を見つけたが、
911SHでも再現したので、携帯でactionを省略することはご法度っぽい。

まぁ、そもそも今までFormタグのactionを空でも動くってことを知らなかったし、
今回たまたま人の書いたソースのメンテをすることになって初めて知ることができた。
規約的にもactionを空で動かそうとするってのは間違っている気がするので、
今後もきちんとactionは書いていこうと思う。

SoftbankのUIDの取得に関して

初めて携帯コンテンツ作っている時にはまったので、メモ。
既存の管理画面を改修して作ったはずなのに、ソフトバンクの携帯のUIDが取れなかった。

$uid = $_SERVER["HTTP_X_JPHONE_UID"];

で取得できるってどのサイトにも書いてあったんですが、なぜか取得できない…。
調べてみたら、SSLの直リンクの場合はUIDが取得できないみたい。
なので、いったん非SSLのページからSSLのページに遷移する必要がある。

UID関係は結構落とし穴が多いみたい。

参考文献
SSL利用時のHTTP_X_JPHONE_UIDの落とし穴

MySQLを高速化する方法

MySQLのチューニングに関してよさそうな記事があったので、とりあえずコピってみた。

1. バッファを増やす、または減らす

チューニングの基本中の基本であるが、適切なバッファサイズを設定することはパフォーマンスチューニングの要である。主なバッファは次の通り。

* innodb_buffer_pool_size・・・InnoDBだけを利用する場合は空きメモリの7〜8割程度を割り当てる最も重要なバッファである。余談だが、実際にはここで割り当てた値の5〜10%ぐらいを多めにメモリを使うので注意が必要だ。
* key_buffer_size・・・MyISAMだけを利用する場合は、空きメモリの3割程度を割り当てるといい。残りはファイルシステムのキャッシュ用に残しておこう。
* sort_buffer_size・・・ソート処理に利用するバッファである。OLTPでは256K〜1Mぐらいを割り当てると良い。これがあまり大きすぎると、メモリの割り当てのオーバーヘッドが大きくなるので注意しよう。DWH系の処理などで大きなソートが必要な場合、セッションごとに動的に調整すると良い。
* read_buffer_size・・・全件スキャンをするときに利用するバッファ。OLTPでは128K〜512Kぐらいを割り当てると良い。
* read_rnd_buffer_size・・・ソート処理でインデックスを利用する場合に利用するバッファ。OLTPでは256K〜1MぐらいをDWH系の処理などで大きなソートが必要な場合、セッションごとに動的に調整すると良い。

バッファは増やせば増やすほどいいかと言えばそうではない。メモリの割り当てがオーバーヘッドになるので、無駄に大きくし過ぎることは禁物である。また、バッファを増やしすぎたためにスワップが発生するとパフォーマンスが悲惨なことになるのでくれぐれも空きメモリ容量には注意しよう。

2. 高速なディスクを利用する

MySQLだけに限った話ではないが、RDBMSのボトルネックは99.99999%がディスクI/Oである。特にディスクのシークタイムによる待ち時間が大きい。理想的にはバッテリーバックアップ付きのRAID装置を利用するのがいい。最近はRAID装置に匹敵するほど高速なSSDが出てきているので楽しみである。

前述のようにバッファを大きくするとディスクI/Oの回数や量が減るので、必ずしも高速なディスクが性能を向上させるというわけではないが、データサイズが大きくてバッファに収まりきらない場合などにはどうしてもI/Oが大量に発生してしまう。そんな時は高速なディスク装置を利用するといい。

3. クエリを最適化する


実は最も大事なのがクエリの最適化である。いくら他の部分を最適化したところで、毎回全件スキャンが発生していたのでは話にならない。適切にインデックスを使ったり、サブクエリをJOINに書き換えたりすることで、フェッチしないといけない行数ができるだけ少なくなるようにクエリを書きかえよう。クエリを最適化するには、まずEXPLAINで実行計画をチェックしよう。EXPLAINの見方についてはいずれ解説しようと思う。

また、テーブルから全件フェッチしてからアプリケーション側で行を絞り込むというようなロジックを実装してはいけない。必ずSQL文、つまりWHERE句で行の絞り込みができるようにしよう。

クエリを手当たり次第チューニングしていてはいくら時間があっても足りないだろう。問題のあるクエリだけをチューニングするべきであるが、そのようなクエリを見付けるにはスロークエリログや商用のクエリアナライザを用いると効果的である。

4. テーブルを最適化する


基本中の基本は、適切なデータタイプを使うということである。できるだけカラムサイズが小さくなるようなデータタイプを選ぼう。数値をVARCHAR(桁数)などのデータタイプで格納しているのをたまに見かけるが、これは誤りである。INTまたはBIGINTなどを利用したほうがずっとデータサイズが小さくなるし高速である。

また、適切なカラムに対してインデックスをつけるのも重要である。どのカラムにインデックスをつけるかは、クエリのパターンに因る。インデックスが多すぎると更新時のオーバーヘッドが大きくなるだけでなく、インデックスツリーを格納するためのデータ容量が増えてしまうので、インデックスのつけすぎには注意しよう。たまに全てのカラムにインデックスがついているテーブルを見かけるが、そのようなテーブル設計は誤りである。クエリのパターンによっては、マルチカラムインデックスやパーティショニングが必要になるなどいろいろと工夫が必要になる。

カラム数がが多くなりすぎたら、まずは正規化できるかどうかを検討してみて欲しい。DWH用途などでは逆に非正規化すると性能が向上する場合がある。

5. 目的に合ったストレージエンジンを選択する


これはMySQLの醍醐味である。ストレージエンジンはそれぞれ性能特性がまったく違うので、目的に合ったストレージエンジンを選択すると劇的に性能が向上する場合がある。例えば、OLTPではInnoDB、参照系が多い場合はMyISAM、ログ目的であればARCHIVE、リアルタイム並列処理であれば NDBCLUSTERなど。他にもSun/MySQL以外のサードベンダーやコミュニティからリリースされているストレージエンジン(SPIDER、 PBXT、XtraDB、Q4M、Infobright、Kickfireなど)もあるので、目的に合わせて色々検討してみるといいだろう。

6. レプリケーションで負荷分散する


MySQLほどお手軽に、そして安価にレプリケーションを利用出来るRDBMSは他にないだろう。レプリケーションを用いてたくさんのスレーブへ参照系の処理を負荷分散するテクニックは、Webサイトなどで頻繁に利用されているテクニックである。参照系の負荷分散を行う場合だけでなく、例えばOLTPのデータを元にBIなどの処理を毎日行う場合などにも有効である。スレーブ上でBIを行えば、マスター上のOLTP系の処理に影響を与えることがない。

7. ストアドプログラムを多用しない


残念ながら、MySQLはストアドプロシージャ、ストアドファンクション、トリガなどの性能はあまりよくない。出来るだけそれらを利用せずに、ロジックをアプリケーション側に持っていくといいだろう。

8. ファイルシステムをチューニングする


Linuxであればデフォルトはext3(そろそろext4になっていくだろうか?)であるが、ext3ではなくXFSを利用すると性能が向上する場合がある。また、I/Oスケジューラを変更することで、同じext3であっても性能特性が変化する。SolarisではUFS、ZFS、QFSなどの利用を検討するといいだろう。WindowsならNTFS以外にあまり選択肢はないが、MyISAMの場合はLargeSystemCacheを有効にするなどのチューニングが必要である。

9. コネクションプールを利用する


アプリケーションがDB操作が必要なときに都度MySQLサーバへ接続していたのでは、接続のためのオーバーヘッドが無視出来なくなる。そんなときはコネクションプールを利用するといい。

10. ベンチマークする


どんなチューニングでも、実際に効果があるかどうかは測定してみるまで分からない。また、あるアプリケーションで効果があるチューニングでも、他のアプリケーションの負荷パターンでは逆効果になってしまうということは多々ある。なので、アプリケーションの負荷を擬似的に作り出してチューニングの効果を測定することはとても重要なのである。

11. インテルコンパイラ版を使う。

MySQLのダウンロードサイトではLinux向けにインテルのコンパイラを使って作成されたバイナリが配布されている。インテル版のコンパイラは、もちろん処理によって得手不得手はあるのだが、GCCを利用して作成されたバイナリよりも良い性能を発揮することが多い。インテルコンパイラ版を使うというのは非常にお手軽な高速化テクニックであろう。

ちょうどSourceForge.JP Magazineで「インテル コンパイラーの実力を測る――インテル コンパイラー版MySQLは本当に速いのか?」という記事が書かれているので参照して欲しい。こちらではベンチマークも行っている。

ちなみに、SolarisにはSunStudioというサン・マイクロシステムズ純正のコンパイラがあり、こちらのコンパイラで作成したバイナリもGCCより高速になる場合が多い。残念ながら、SunStudioで作成されたバイナリは配布されていないので、SunStudioを試したい人は自分でコンパイルしよう。SunStudioは無料で配布されている。

12. 同時実行スレッド数を調節する。

ちょっとやそっとの負荷ではあまり問題にならないが、1000のクライアントから一斉に接続してクエリを実行する場合などは同時実行スレッド数を調節するといい。処理を並列に行うとスループットの向上が期待出来るが、同時に実行中のスレッドがあまりに多すぎるとロックの競合が多発してしまって返って性能を落とす原因になってしまう。innodb_thread_concurrencyオプションを利用するとInnoDBが内部的に利用するスレッド数を調節することができる。このオプションはいくつがいいかということについては明確な答えはない。アプリケーションの負荷によるところもあるし、CPU数やOSのスケジューラにも影響されるからである。従って、適切な値を決めるにはベンチマークが必須である。逆に言うと、ベンチマーク時には必須の調整パラメータであると言える。特にCPUコア数が増えた場合には調整することにより性能の向上が見込める。innodb_thread_concurrencyオプションのデフォルト値はバージョンによって異なるが現在は8である。0に設定得るとスレッド数の上限がないことを示す。最大値は1000。まずは0、4、8、12、16、20辺りで変化させて性能を計測するといいだろう。

MySQL 6.0ではさらにスレッドプールが搭載される予定である。InnoDB内部の同時実行スレッド数だけでなく、MySQLサーバの接続スレッドの同時実行数を調節することができるようになる。例えば、同時に実行するスレッド数を100までに限定したい場合には次のように指定する。

thread_handling=pool-of-threads
thread_pool_size=100

現時点ではLOCK_event_loopの競合が発生するという問題があるためスレッドプールによる性能向上は見込めないが、正式版がリリースするまでには問題は解消されスレッドプールによって同時実行性能が改善することだろう。ちなみに、MySQL 6.0のスレッドプールはlibeventで実装されている。スレッドプールもMySQL 6.0のリリースを楽しみにさせてくれる要素の一つである。

13. 適切なサイズでCOMMITする。

一度に大量の更新を行うと、更新している間はその行に対して排他ロックがかけられるためロックの競合が発生する。ロックの競合が多発すると同時実行性能の低下に繋がってしまう。逆に言うと、OLTP系のアプリケーションで用いる場合などは、一回のトランザクションでCOMMITするサイズを小さく調節することでデータベース全体のスループットを向上させるのがいいだろう。

また、更新のサイズがInnoDBのログサイズより大きい場合には、COMMITの前にテーブルスペース内にUndoログを大量に作成する必要が生じるため、I/O性能が低下するという問題が発生する。I/O性能だけでなく、不要になったUNDOログはパージスレッドが回収するまでテーブルスペース内に残り続けてしまうので容量も圧迫してしまう。LOAD DATA IN FILEなどで一度に大量のデータを更新するのは避けた方がいいだろう。

もし新たなInnoDBテーブルにCSVファイルからデータを大量にロードしたい場合にはLOAD DATAコマンドを利用せず、CSVストレージエンジンからInnoDBテーブルにALTER TABLEするという技が存在するのでお勧めである。ALTER TABLE時には1万行ごとにCOMMITしてくれるので、上記のようなUNDOログの問題は発生しない。

MySQL Performance Blogにおいてfifoを使ってLOAD DATAを小刻みに行う方法が紹介されているので、興味のある人は参照して欲しい。

14. InnoDBのログサイズを調整する。

InnoDBのログファイルのサイズが小さすぎるとInnoDBの更新処理の性能が低下してしまう。前述したように大きなデータをロードする際のパフォーマンス低下も問題であるが、ログファイルのサイズが小さいとチェックポイント処理が頻繁に発生することによる影響がとても大きくなってしまう。ならば巨大なログファイルを作ればいいじゃないか?と思うだろうが話はそう簡単ではない。ログファイルのサイズが大きいと今度はクラッシュリカバリ(Redoログ適用)の時間が増えてしまうからだ。特にHA化されたMySQLサーバではクラッシュリカバリの時間が増長するとフェイルオーバーに時間がかかる時間も長くなってしまうので好ましくない。従って、適切なログファイルのサイズを選択することは非常に大切である。

InnoDBのログサイズ調節方法については過去の投稿で説明したので参照して欲しい。

15. 最新版を利用する。

希に「MySQLは4.0が一番性能がよかった」などと嘯(うそぶ)く人を見かけるが、そんなことはない。MySQLもバージョンが上がるごとに性能向上のための機能が追加されている。

* 5.0 GA ... greedyオプティマイザ、Index Merge、InnoDBのTRUNCATE性能改善、NDBのCondition Pushdownなど。
* 5.0.30 ... InnoDBバッファプールのロック改善
* 5.0.50 ... クエリキャッシュのパフォーマンス改善
* 5.0.54 ... InnoDBのCPUスケーラビリティの向上
* 5.1.x ... InnoDBのAUTO-INCロックの性能改善

MySQL 5.0.30と5.0.54で行われた改善については、マイコミジャーナルの記事で詳細な説明が行われているので参照して欲しい。

さらにMySQL 6.0では性能に関するものとして次の新機能が追加される予定である。

* BKA JOIN
* Multi Read Range
* Index Condition Pushdown
* サブクエリ最適化
* スレッドプール(前述)

単純なクエリのレスポンスタイムはあまり変わらないかも知れないし、処理の内容によってはバージョン間で得手不得手が存在するが、システム全体で見た時のスループットは着実に向上しつつある。

16. READ COMMITTED分離レベルを使う。

InnoDBはデフォルトではREPEATABLE READ分離レベルを利用する。REPEATABLE READ分離レベルを利用するとPHANTOM READという問題を防ぐことができるが、ロックの競合がより頻繁に発生するようになってしまう。InnoDBではREAD COMMITTED分離レベルおよびinnodb_locks_unsafe_for_binlogオプションを利用することで、ロックの競合を減らして同時実行性能を向上させることが可能であるので、同時実行性能が重要な場合にはREAD COMMITTED分離レベルを利用しよう。(ちなみに、InnoDBは他のRDBMSとは違ってREAD COMMITTED分離レベルでNON REPEATABLE READは発生しない。)

ただし、ステートメントベースレプリケーション(SBR)しか利用出来ないMySQL 5.0以前のバージョンでは、innodb_locks_unsafe_for_binlogオプション利用時にバイナリログの一貫性を保証できないという問題があった。(そしてinnodb_locks_unsafe_for_binlog利用時には同時実行性能が改善しないというオチがある。)MySQL 5.1では行ベースレプリケーション(RBR)が追加されたため、同時実行性能を保ちつつバイナリログの一貫性を保証することが可能になっている。ただしこの変更により、READ COMMITTED分離レベル利用時またはinnodb_locks_unsafe_for_binlogオプションが有効になっている場合にはRBRの利用が必須となった。

READ COMMITTEDが利用出来るのはどのような場合か?明確なのは一回のトランザクションで複数の処理を行う必要がない場合である。例えばSNSサイトの日記データなどはREAD COMMITTEDで問題ないだろう。更新は日記の文章をINSERT、参照は最新のデータのSELECTをそれぞれ一回行うだけで実装出来るため、一回のトランザクション内で複数の処理を行う機会はあまりない。多くのWebアプリケーションでは一回のリクエストが一回のクエリに対応する。従って、多くの WebアプリケーションでREAD COMMITTEDが利用出来るだろう。

ちなみに、利用出来る分離レベルはストレージエンジンによって異なる。他のストレージエンジン、例えばMySQL ClusterではREAD COMMITTED分離レベルしか利用出来ない。 FalconではREAD COMMITTED、REPEATABLE READ、SERIALIZABLEをサポートしている。

READ COMMITTEDの有効性については別途紹介したい。

17. EXPLAIN以外のチューニングコマンド。

SHOW STATUSコマンドはMySQLサーバ上の統計情報を見ることができるコマンドである。スコープ(GLOBALまたはSESSION)を指定することにより、SHOW GLOBAL STATUSではサーバ全体の統計情報を、SHOW SESSION STATUSではセッションごとの統計情報を見ることが可能である。SHOW GLOBAL STATUSを利用するときは、10分ほど間隔を空けて2回情報を採取し、増分を見ることで単位時間あたりの負荷を測定するのがコツ。(逆にいうと累積情報を見てもあまり意味がない場合が多い。)また、SHOW SESSION STATUSを利用するときは、FLUSH STATUSコマンドを実行することでセッションにおける統計情報をクリアすることができる。特定のクエリ実行時の統計情報を見るときなどに便利である。

SHOW STATUSコマンドで気をつけるべき主な変数は次の通り。

* Created_tmp_disk_tables・・・ディスク上のテンポラリテーブルが作成された回数。
* Handler_read_first・・・フルインデックススキャンの回数。
* (1-Key_reads/Key_read_requests)・・・MyISAMキーバッファのキャッシュヒット率。
* Opened_tables・・・テーブルがOpenされた回数。急激に増えている場合にはテーブルキャッシュを増やす。
* Qcache_*・・・クエリキャッシュ関係。Qcache_insertsに対してQcache_hitsが少ないとヒット率が悪い。
* Select_full_join・・・2つ以上のテーブルにおいて全件同士でJOINした回数。最も致命的な兆候。
* Select_full_range_join・・・片方のテーブルで全件、もう片方のテーブルで範囲検索を行ってJOINした回数。
* Select_scan・・・全件スキャンの回数。
* Sort_scan・・・全件スキャンによるソートの回数。
* Threads_created・・・スレッドが作成された回数。急激に増えている場合にはスレッドキャッシュを増やす。

クエリのチューニングにおける基本コマンドはあくまでもEXPLAINであるが、クエリの実行状況を詳細に確認したい場合にはプロファイリング(SHOW PROFILEコマンド)を利用するといい。プロファイリングについては過去の投稿「プロファイリングで快適MySQLチューニング生活」で解説したのでそちらを参照して頂きたい。

おまけ: Sharding

巷ではGoogle Friend ConnectにおけるShardingの例が紹介されている。

大規模なWebサイトなどで劇的にトラフィックやデータ量が増えてくると、単一のデータベースでは対応しきれなくなってくる。そのような場合、特定のカラムなどによってデータの格納先を振り分けるテクニックが利用されることが多いのだが、そのようなテクニックをShardingと呼ぶ。(MixiのひとはLevel2分散と呼んでいるらしい。)とはいっても、Shardingが必要になるほど大規模なデータベースはどちらかといえば少数派なので、あまり一般的なケースには当てはまらないかも知れないが、そのようなニーズがある人達のためにオマケとしてMySQLにおけるShardingのソリューションを紹介しておこうと思う。

MySQL Cluster・・・サン・マイクロシステムズが提供するオフィシャルなストレージエンジンの一つである。主キーに基づいて内部的にShardingを行うので、ユーザはShardingについて意識する必要がない。

SPIDER・・・STグローバルの斯波氏によるストレージエンジンである。MySQLユーザコンファレンス2009のスライドではShardingという単語は一切登場しなかったが、SPIDERストレージエンジンがやってることはまごう事なきShardingである。SPIDERを利用するとテーブル定義以外でユーザがShardingについて意識する必要がないので便利である。

Spock Proxy・・・MySQL ProxyをベースにしたShardingソフトウェア。Luaスクリプトを利用せずにC/C++でShardingのロジックを実装しているためとても速い。今のところMySQL ProxyではShardingを実装することは出来ない。

その他・・・Hibernate Shards、HiveDB、HBase、BigTable、HScaleなど。

MySQLでやってはいけないこと

MySQLを使用する時点で気をつけておかないといけないことを漢(オトコ)のコンピューター道さんの方で記事があったので、転載させてもらうことにした。

1. 全てのカラムにインデックスをつける

データベース初心者がもっともやってしまいがちな間違いはコレではないだろうか。インデックスはいい。検索がとても速くなるから。しかし、それと引き替えにインデックスは更新するときにコストがかかるし、その分多くのディスクスペースを消費する。特に更新にかかるコストは時に甚大で、該当するインデックスのページがキャッシュ上にない場合はディスクからいったんそのページを読み込まなければいけない。ディスクアクセスは動作にとても時間がかかるので、インデックスが多数、例えば全てのカラムに付いていたりすると「あれ?固まったか?」というような状態になってしまうことがあるだろう。インデックスは必要なカラムにだけつけるようにテーブルを設計しよう。インデックス数が増えてきたら、テーブルの分割や正規化を検討した方がいいだろう。

2. デフォルトのまま使う

何も足さない。何も引かない。

一切の手を加えずに、デフォルトのままMySQLを使ってしまう。デフォルトの状態でもそれなりのパフォーマンスを発揮出来るが、バッファが足りないので思うように性能が出ないだろう。特に、大きなテーブルを扱う時には大きなバッファが必要である。(テーブルがごく小さなものであばデフォルトのままでも何ら問題ないかも知れない。)バッファが小さいと、キャッシュされないインデックスページが多数存在することになり、特にインデックスページを更新する時にディスクアクセスが生じるのが問題になってしまうだろう。

1との合わせ技で一本。

3. インデックスを利用しない

インデックスなどというこざかしい技は利用しない。オトコは黙って真っ向からテーブルスキャン!!などと馬鹿なことを考えてはいけない。データベースの検索はインデックスを使ってナンボである。インデックスをつけすぎるのも良くないが、インデックスを使わないのはもっといけない。特にインデックスを使わずにJOINをするようなクエリ(FULL JOIN)は強烈に遅いので気をつけよう。

4. バッファを多く割り当てすぎる

バッファは多ければ多いほど高速になる。しかし、欲張って空きメモリをはるかに上回るバッファを割り当ててしまっては元も子もない。スワップが発生してしまうからだ。スワップが発生すると、目を覆いたくなるほど性能が劣化する。MySQLはメモリへアクセスしているつもりでも、ディスクへのR/Wが完了しないと処理を継続することが出来ないからだ。しっかりと空きメモリを確認し、スワップが起きないように気をつけよう。

セッションごとのバッファには要注意だ。これらは負荷に応じて多く割り当てられる可能性があるからだ。システムの負荷がスカスカのときに大丈夫だと安心していたら、負荷がピークになったときにスワップが発生してエライ目にあった・・・などということにならないよう気をつけよう。パッケージに含まれるmy- innodb-heavy-4G.cnfサンプルファイルには注意が必要である。これは、heavyなクエリ、つまり複雑なクエリを処理するための構成であって、セッションごとのバッファが多く割り当てられている。負荷が重いという意味ではないのである。

5. ネストしたサブクエリ

既に解説したように、MySQLのサブクエリは外側から順に評価される。従って、サブクエリをネストしていると、内側のサブクエリは無駄に何回も実行されてしまうことになる。特にIN句を用いているときは注意が必要である。

ネストしたサブクエリのように遅いクエリが存在すると、ロックモードによっては他のセッションの参照や更新がブロックされてしまうことがある。システム全体の足を引っ張ってしまうわけである。その他には、JOIN + ORDER BY + LIMITを合わせて利用する場合、一行ずつINSERTするような場合、ストアドプログラムを多用しているような場合には注意が必要である。

6. ストレージエンジンの用法を間違えている

たまに見かけるのが、InnoDBなのにテーブルロックを利用している場合である。InnoDBは行レベルで排他制御を行うので、テーブルロックを利用するとわざわざ同時実行性能を下げてしまうことになる。

トランザクションが必要なのにMyISAMを利用しているというような場合もある。BEGIN;....COMMIT;などとやっているが、MyISAM ではCOMMITをしても意味がないので意味がないし、ロールバックは一切出来ない。トランザクションが必要なら、トランザクション対応のエンジンを利用しよう。

InnoDBを利用している時にデッドロック時のエラー処理がない場合がある。トランザクションは常にデッドロックによるロールバックの発生を意識して利用しなければならない。MyISAMを利用していたプログラムをInnoDBに変換した場合に、このような過ちを犯してしまいがちなのだろう。

7. バラバラの文字コードを使う

MySQLの便利なところは、文字コードの変換を自動的に行ってくれるところである。それにあぐらをかいて文字コードに無頓着でいると、痛い目を見ることになるだろう。文字コードはテーブルごとに設定することができるが、セッションに対して設定することも可能である。また、システムレベルで利用する文字コードも設定することが可能である。全ての文字コードがバラバラだと、テーブルから行をフェッチ --->文字列処理関数--->クライアントへ送信、という処理を行うような場合に、各ステップの間で文字コードの変換が発生してしまう。全てをアプリケーションが利用する文字コードへ統一しよう。

8. 同時接続数が多すぎる

MySQLは同時接続数が増えても軽快に動作する・・・ということはない。数千の接続が同時にアクティブな状態では、ロックの競合が多発してスラッシングが起きてしまう。適切な接続数を見極めよう。クライアント数が増えた場合には、レプリケーションや MySQL Clusterによるスケールアウトを検討するといいだろう。

上記とは異なる問題であるが、徐々にセッション数が増えてしまい、新規の接続が出来なくなるというような問題をたまに見かける。これは、単にアプリケーションがセッションを閉じない場合に生じる問題であり、例外発生時などに的確にセッションを閉じるように注意されたい。

9. 他のアプリケーションがリソースを食い過ぎる

MySQLが稼働しているホストで、他のアプリケーションも動作している場合には、メモリやCPU、ディスクアクセスなどの資源が枯渇しないように注意を払う必要がある。メモリが足りなくなってしまった場合、MySQLはOOMキラーの格好の餌食となるだろう。(OOMキラーに終了させられないように設定しておくと良い。)

10. いにしえのバージョンを使う

MySQLの開発者達は、日々バグの修正を行って膨大な数の問題を修正している。従って、新しいバージョンのMySQLは新しい機能が追加されているだけでなく、バグが少なく安定している。とても古いバージョン、特に3.xや4.xを使っているような場合には気をつけよう。

古いバージョンにだけしか搭載されていない機能にも要注意である。例えば、かつてはBerkeley DBがストレージエンジンとして搭載されていることがあった。しかし、BDBストレージエンジンが安定することはなかった。MyISAMの前身である ISAMストレージエンジンというのがあるが、ISAMは既にメンテナンスが終了している。MyISAMのRAIDモードなどというものもかつては存在したが、5.0以降のバージョンには搭載されていない。

MySQLだけを最新にしても、OSが古すぎると元も子もない。Linuxカーネル 2.4またはそれ以前、FreeBSD 5.x、Solaris 8など、まだまだ使われている場合も多いが、古いOSを使うメリットはあまりない。OSも出来るだけ新しいものを利用しよう。

2010年12月17日金曜日

ワキシングテーブルが来た!

今年こそはワックスをちゃんとかけようと思い、ワキシングテーブル(eSPORTSオリジナルWAX STAND)を購入しました。

普通にガリウムとかのワックステーブル買うと2万位しますが、これは6000円位と格安でした。
まぁ安かろう悪かろうって感じでそこまで期待してたわけではないんですが、
ワックステーブル本体の作りは悪くなかったです。
しかも下に引くシートみたいなのも付いてきたので、そこそこいい買い物でした。
本体は結構がっしりしてるし、ちょっとやそっとで壊れる感じはしません。
まぁ、細かい部分の作りに関してはちょっとちゃっちい感じがしますが、
普通にワックスかける分には問題なかったです。

ただ、ワックステーブルがクロスする形状になっているので、
幅を広くすると高さが低くなるってしまうので、
板を1枚マジックテープで押さえずにかけようとすると、
ちょっと高さが足りなくなって中腰状態でかけないといけなくなります。
そこが唯一の欠点かな。
それ以外は良好です。

今年は頑張ってワックス掛けるぞー。

2010年12月16日木曜日

セッションとクッキーの違いに関して

よく忘れるのでメモ。
セッションはサーバサイドに保存される値で、クッキーはクライアントサイドに保存される値のこと。

2010年12月15日水曜日

HTMLコーディングをきちんとしていない場合の罠

きちんとHTMLをコーディングしている人と仕事をしている限り100%起こらない現象ですが、
HTMLコーディング初の人と一緒にやった時にはまった。

inputのnameにsubmitって名前があった関係で、JSからformをsubmitしようとしたらエラーになった。

vimで文字コードを自動認識するようにする

以下のソースを.vimrcにコピペすれば自動認識される。

if &encoding !=# 'utf-8'
  set encoding=japan
  set fileencoding=japan
endif
if has('iconv')
  let s:enc_euc = 'euc-jp'
  let s:enc_jis = 'iso-2022-jp'
  " iconvがeucJP-msに対応しているかをチェック
  if iconv("\x87\x64\x87\x6a", 'cp932', 'eucjp-ms') ==# "\xad\xc5\xad\xcb"
    let s:enc_euc = 'eucjp-ms'
    let s:enc_jis = 'iso-2022-jp-3'
    " iconvがJISX0213に対応しているかをチェック
  elseif iconv("\x87\x64\x87\x6a", 'cp932', 'euc-jisx0213') ==# "\xad\xc5\xad\xcb"
    let s:enc_euc = 'euc-jisx0213'
    let s:enc_jis = 'iso-2022-jp-3'
  endif
  " fileencodingsを構築
  if &encoding ==# 'utf-8'
    let s:fileencodings_default = &fileencodings
    let &fileencodings = s:enc_jis .','. s:enc_euc .',cp932'
    let &fileencodings = &fileencodings .','. s:fileencodings_default
    unlet s:fileencodings_default
  else
    let &fileencodings = &fileencodings .','. s:enc_jis
    set fileencodings+=utf-8,ucs-2le,ucs-2
    if &encoding =~# '^\(euc-jp\|euc-jisx0213\|eucjp-ms\)$'
      set fileencodings+=cp932
      set fileencodings-=euc-jp
      set fileencodings-=euc-jisx0213
      set fileencodings-=eucjp-ms
      let &encoding = s:enc_euc
      let &fileencoding = s:enc_euc
    else
      let &fileencodings = &fileencodings .','. s:enc_euc
    endif
  endif
  " 定数を処分
  unlet s:enc_euc
  unlet s:enc_jis
endif
" 日本語を含まない場合は fileencoding に encoding を使うようにする
if has('autocmd')
  function! AU_ReCheck_FENC()
    if &fileencoding =~# 'iso-2022-jp' && search("[^\x01-\x7e]", 'n') == 0
      let &fileencoding=&encoding
    endif
  endfunction
  autocmd BufReadPost * call AU_ReCheck_FENC()
endif
" 改行コードの自動認識
set fileformats=unix,dos,mac
" □とか○の文字があってもカーソル位置がずれないようにする
if exists('&ambiwidth')
  set ambiwidth=double
endif

2010年12月8日水曜日

Flash経由でのクリップボードコピーに関して

Flash Player10からセキュリティの仕様が変わったため、
JSでイベントを取得してFlashに渡す方法が使えなくなってしまった。
解決策としては、Flashを使ってボタンを生成するか、
透過のFlashをボタン等の上にかぶせるような形で実装するしか方法がなくなってしまった。

参考文献
Adobeの文章
http://www.adobe.com/jp/devnet/flashplayer/articles/fplayer10_security_changes_02.html#head4

対応策
http://www.b-r-u.net/flashclipboard.html

2010年12月6日月曜日

fopenのmodeに関して

オペレーティングシステムファミリが異なると行末も異なります。 テキストファイルに書き出し、そこに改行を加えたいとき、 オペレーティングシステムにあわせた正しい改行コードを使用する必要があります。 Unix ベースのシステムでは改行に \n キャラクタを使用します。 Windows ベースのシステムでは \r\n を使用します。 マッキントッシュベースのシステムでは \r を使用します。

間違った改行コードでファイルに書き込むと、 他のアプリケーション上でそのファイルを開いた際に変な風に見えてしまいます。

Windows上では、\nを\r\nに透過的に変換する text-mode変換フラグ('t')が提供されます。 それに対し、'b'を使って強制的にバイナリモードにすることもできます。 その場合データの変換はされません。 このフラグを使用するには、'b' または 't'を mode引数の最後に追加してください。

デフォルトの変換モードは SAPI と使用している PHP のバージョンによって異なります。 したがって、互換性の意味から、常に適切なフラグを指定することが推奨されます。 plain-text ファイルを使用する場合には 't' モードを指定すべきであり、 改行に \n を使用すると、 メモ帳のようなアプリケーションで読めることを期待できます。 それ以外のケースでは 'b' を使うべきです。

バイナリファイルを扱っている際に 'b' フラグを指定しなかった場合、 画像ファイルが壊れたり、\r\n キャラクタがおかしくなる等の問題を抱えてしまうでしょう。

PHPのセッション管理に関して

PHPで$_SESSIONを使用した場合、セッションが不要になった際には必ずセッションを破棄する処理が必要になる。
session_destroyだけでは$_SESSIONに保存されている内容は破棄されないので、
必ず空の配列を代入し、$_SESSIONの内容をクリアする必要がある。
<?php
$_SESSION = array();
session_destroy();

2010年12月3日金曜日

SQLに関してのメモ

SQL文の処理手続きの良しあしは,主にディスク・アクセス回数で判断されます(少ない方が良い)。なぜなら,ディスク・アクセス処理はほかの処理に比べて遅く,全体の処理時間を大きく左右するからです。ディスク・アクセス回数を少なくする最も基本的な技術はインデックスで,主に使われるのはBツリー・インデックスです。Bツリー・インデックスは常に効果が得られるわけではなく,カラム値の種類が少ない場合や,レコード数の少ない場合はほとんど効果がありません。二つのテーブルを検索するとき,ジョインが行われます。

2010年11月27日土曜日

買ってしまった・・・。

やばい、買ってしまいましたよ・・・。
スノボの板とブーツとバイン。
ブーツは元々買う予定だったから全然問題ないのですが、
板とバインはまったくの想定外です!
歯の治療に神田に行っているので、帰りにスノボショップに寄れちゃうのがいけなかった・・・。
011 ArtisticのGULLWINGがどんな板なのかなーと思って見に行ったのが間違いの原因です。
でも、買って後悔はしてないです。
なんてったってGULLWINGはそこらのロッカーボードとはわけが違います。
ダブルキャンバーなんですけど、板のセンター部分はVロッカーみたいになってるんです。
ロッカーだとオーリーやノーリーの反発が弱いってのが弱点ですが、
それをダブルキャンバーにすることで解決したそうです。
早く乗ってみて~!!
バインもFLOWからFLUXに戻して、ハイバックが柔らかめのやつを選びました。
FLOWは楽だけど、ハイバック硬いからスタイルとか出しづらいんですが、
これで色々とやりやすくなりそうです。

ちなみに今年のギアはこんな感じ。
ボード:011 Artistic GULLWING 151
バイン:FLUX TT30
ブーツ:K2 THRAXIS
ウェア:VOLCOM

2010年11月26日金曜日

スノーボードDVDレビュー

今年はスノボのDVDをいっぱい買ったので、ちょっと感想を。

1.THINK DIFFERENT
今年発売した久々の011 Artisticのチームムービー。
みんないい感じでしたが、中でも新原雄蔵すげーわ。
はんぱない。
HIGHLIGHTで初めて見たときからすげーと思ってたけど、やっぱすげー。
さらっとやってるんだけど、プレスとかオーリー、ノーリーとかちゃんとやってる感じの印象。
こんな風に動けたらスノボがもっと楽しくなりそう。

2.ぷちトリ5
ぷちトリシリーズの第5弾。
初めて買ってみた。
前々から気になってたけど、今年は思い切って買ってみた。
いろんな人が出てて、結構面白かった。
How toなんだけど、ゆるい感じがあってちゃんとしたトリックから、
なんじゃこりゃってトリック?なのみたいなやつまで色々あって楽しめました。
今後も買ってもいいかも。

3.テクニシャン6
見た感想としては普通のHow toって感じですね。
ためになるけど、そんなに面白いって感じではない。
来年は内容次第では買わないかなぁ。

1.地形小技
おしゃれ小技シリーズの続編?見たいな感じで発売されたけど、
おしゃれ小技よりは大分How to系の色が濃くなっていて勉強にはなるけど、
日本じゃこんな感じのゲレンデはそうそうないと思った。
スノボに行く時に車で流す感じではないかな。
ちょっと残念な感じです。

2.地形小技2
地形小技と違って、おしゃれ小技に近い感じ。
滑ってる途中にテロップみたいなのでトリック名が出てくる。
特に解説に重点を置いているわけではないので、そこそこ見やすい感じでした。
とはいえ満足するほどではないかも。

3.地形小技3
日本の各ゲレンデをホームにするプロライダーが地形を使って遊んでるといったムービー。
岐阜とかのゲレンデは行かないから知らなかったけど、結構楽しそう。
中でも一番気になったのは野沢温泉の所。
コース外?っぽい感じでどこのコースと書かれてなかったけど、かなり面白そうな地形だった。
行ってみたい!!
ただ、毎年同じ地形だとは限らないので、その辺がどうなのかって気になりました。

2010年11月23日火曜日

windowsでファイル名の一覧を取得する。

対象のディレクトリに移動して以下のようにすると取得可能。

対象のディレクトリにあるファイル名の一覧を取得
特定のファイル名のみ表示させたい場合は*を書き換える

dir *

aから始まるファイル名を取得
dir a*

ファイル名だけ取得したい場合

dir * /b

ファイル名だけを表示させたい場合

dir r* /b/a-d

フォルダ名だけを表示させる

dir r* /b/ad

サブフォルダも検索させる(ファイルパスのみ表示する)

dir r* /b/a-d/s

MySQLで文字コード確認

メモ。
文字コードの確認方法は以下の通り。
> status
--------------
mysql  Ver 14.14 Distrib 5.1.50, for redhat-linux-gnu (i686) using readline 5.1

Connection id:          2848
Current database:       brooklyn
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         5.1.50 MySQL Community Server (GPL) by Utter Ramblings
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 119 days 2 hours 25 min 24 sec

Threads: 1  Questions: 20732  Slow queries: 0  Opens: 184  Flush tables: 1  Open tables: 10  Queries per second avg: 0.2
--------------

2010年11月22日月曜日

linuxの日付を設定する

いつも忘れるのでメモ。

date -s "月/日 時間 年"

例)
date -s "12/22 15:48 2010"

2010年11月8日月曜日

javascriptで現在選択されているテキストを取得する方法

こんな感じになります。

function getSelectedText() {
    if (window.getSelection) {
        // 最も標準的な取得方法
        return window.getSelection().toString();
    } else if (document.getSelection) {
        // 上記では取得できない場合はここで取得する(やや古めのブラウザだとこれで取れる)
        return document.getSelection();
    } else if (document.selection) {
        // IEの場合
        return document.selection.createRange().text;
    }
}

ただし、上記の場合はinputやtextarea等のvalueの中で選択されているテキストを取得することはできない。

携帯用メーリングリスト

最近携帯用のメーリスが欲しいなぁーと思っていたので、どれがいいのか調べてみた。
有名所だとfreeml。
広告入りだけど、無料で使える。
携帯で使うことを想定してるから、使いやすい感じ。

iphone3Gとiphone4のメモリー開放方法

今まで再起動するか有料アプリ買うしかないと思ってたけど、実はそうじゃないみたいです。
iphone3Gはホームボタンを10秒位長押ししていると、メモリーが開放されるそうです。
また、iphone3GSとiphone4は電源ボタン長押しして、電源オフ画面が表示された状態でホームボタン長押しでメモリーが開放されるそうです。
メモリーが開放されたかどうか確認したい場合は無料アプリを使って確認できます。
iMemGraphやSysStats Lite,SystemInfo等の無料アプリを使って確認しましょう。
iphone4では開放されてたみたいですが、3Gのほうは開放できてないっぽい。
全然Free Memoryの容量が増えませんでした・・・。
やっぱ再起動しないとだめかも知れない・・・。

2010年10月27日水曜日

さくらレンタルサーバではまった。

さくらレンタルサーバはもう使いたくないってくらいへんな仕様が多い・・・。
hoge.htmlというファイルがあって、「http://www.hogehoge.jp/hoge」のようなURLのリクエストがあった場合、
通常であれば404 Not Foundになるはずなのに、
拡張子の前までの文字のファイルを検索して、マッチしたファイルを表示してしまう。
つまり下記の2つは一緒のファイルが表示される。

http://www.hogehoge.jp/hoge
http://www.hogehoge.jp/hoge.html

この仕様のせいでsymfonyがうまく動かなくて、手間取った。
routing.ymlに書いてあるにも関わらず、デフォルトのルールにマッチしてしまい、
404 Not Foundになってしまうということが起きた。
apacheのmod_rewriteのせいとか色々疑ってみたけど、symfony内部の処理のせいだった。
sfWebRequest.class.phpの中を修正しないとちゃんと動かない。

/**
 * Retrieves the path info for the current web request.
 *
 * @return string Path info
 */
public function getPathInfo()
{
  $pathInfo = '';

  $pathArray = $this->getPathInfoArray();
  // simulate PATH_INFO if needed
  $sf_path_info_key = $this->options['path_info_key'];
  if ( !preg_match('/^(.*)\.php$/', $this->getScriptName(), $matched) ) unset($pathArray[$sf_path_info_key]);
  if (!isset($pathArray[$sf_path_info_key]) || !$pathArray[$sf_path_info_key])
  {
    if (isset($pathArray['REQUEST_URI']))
    {
      $qs = isset($pathArray['QUERY_STRING']) ? $pathArray['QUERY_STRING'] : '';
      $script_name = $this->getScriptName();
      if ( !preg_match('/^(.*)\.php$/', $script_name, $matched) ) $script_name .= '.php';
      else $script_name = $matched[1];
      $uri_prefix = $this->isAbsUri() ? $this->getUriPrefix() : '';
      $pathInfo = preg_replace('/^'.preg_quote($uri_prefix, '/').'/','',$pathArray['REQUEST_URI']);
      $pathInfo = preg_replace('/^'.preg_quote($script_name, '/').'/', '', $pathInfo);
      $prefix_name = preg_replace('#/[^/]+$#', '', $script_name);
      $pathInfo = preg_replace('/^'.preg_quote($prefix_name, '/').'/', '', $pathInfo);
      $pathInfo = preg_replace('/\??'.preg_quote($qs, '/').'$/', '', $pathInfo);
    }
  }
  else
  {
    $pathInfo = $pathArray[$sf_path_info_key];
    if ($relativeUrlRoot = $this->getRelativeUrlRoot())
    {
      $pathInfo = preg_replace('/^'.str_replace('/', '\\/', $relativeUrlRoot).'\//', '', $pathInfo);
    }
  }

  // for IIS
  if (isset($_SERVER['SERVER_SOFTWARE']) && false !== stripos($_SERVER['SERVER_SOFTWARE'], 'iis') && $pos = stripos($pathInfo, '.php'))
  {
    $pathInfo = substr($pathInfo, $pos + 4);
  }

  if (!$pathInfo)
  {
    $pathInfo = '/';
  }

  return $pathInfo;
}

上記のように赤文字になっている部分の処理を修正する必要がある。

2010年10月26日火曜日

apacheのmod_rewriteに関して

よく忘れるのでメモ。

mod_rewriteのQSAフラグ。
QSAとはQuery String Appendの略で、リクエスト時のURLに含まれているクエリストリングを書き換えたURLの後ろに引っ付けてくれるものである。
RewriteRule ^(.*)$ index.php [L]
RewriteRule ^(.*)$ index.php [QSA,L]

2010年10月23日土曜日

2010年10月19日火曜日

phpでtruncateが文字化けた

truncateの処理をPHPで実装してたら、切れ目の文字にマルチバイトがあると文字化けしてしまった。
mb_substrに文字コード指定してやると直るみたいでやってみたらちゃんと直りました。

if ( $length == 0 ) return '';
if ( mb_strlen($string) > $length ) return mb_substr($string, 0, $length, 'utf-8').'・・・';
else return $string;

2010年10月6日水曜日

doctrineでWhereとandWhereは書き分ける必要はない

doctrine使っていて、条件によってWhereを付加する場合に、WhereとandWhereを書き分けなきゃいけないと思ってたけど、
違うみたい。

$qeury = Doctrine_Query::create()->from('ModelName');
$qeury->andWhere('hoge = ?', $hoge);
$qeury->andWhere('fuga = ?', $fuga);

と、こうやって書いても問題なく動く。
Propelと違ってわかりずらいと思ったけど、まぁ解決したのでよしとする。

2010年10月4日月曜日

doctrineで実行されるSQLを事前に確認する方法

getSqlQueryで確認できる。

$q = Doctrine_Query::create();
$q->from('TableName');
echo $q->getSqlQuery();

doctrineでcreated_atとupdated_atに自動で日付を入れる方法

今回初めてdoctrineを使っていて、作成日と更新日に時間が自動で入っていないことに気づいた。
Propelの場合は何もしなくても、勝手に入れてくれていたが、doctrineはそうではないらしい。
調べてみるとschema.ymlに以下のような記述を追加すればできるみたい。

モデル名がTableName、テーブル名がtable_nameに対して自動で日付を入れる場合
config/doctrine/schema.ymlを開いて以下のように「actAs: { Timestampable: ~ }」の行を追加する。

TableName:
  actAs: { Timestampable: ~ }
  connection: doctrine
  tableName: table_name
  columns:
    table_id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
      :
      :

といった感じ。
Timestampableの値が「~」ってなってて、なんだこれと思ったけど、追加してみるとちゃんと動いた。
追加した後はモデルを再生成する。
そうするとBaseTableNameクラスのsetUpという関数の中に以下の記述が追加される。

$timestampable0 = new Doctrine_Template_Timestampable();
$this->actAs($timestampable0);

これで変更作業は完了。
あとはsaveメソッドで保存したものに関しては作成日付と更新日付が自動で挿入されるようになる。

2010年10月3日日曜日

GOM Playerの複数音声の切り替え方法

GOM PLAYERで複数の音声データ(通常音声とコメンタリーなど)を持つWMVやASFファイルを再生したとき、音声を選択できない、または強制的にコメンタリー(副音声)が再生されてしまう問題があります。
通常複数の音声データを持つMKVファイルやOGMファイルでは再生時に音声の切り替えが可能ですが、WMVの場合にこの操作をできない現象です。

複数の音声データを持つWMVファイル、ASFファイル再生時に強制的にコメンタリーが再生されてしまう場合には、下図の設定変更をしてWindows標準のフィルタ(コーデック)で再生すれば通常音声の再生が可能になります。
逆にコメンタリーを再生したい場合には、GOM PLAYER内蔵フィルタ(コーデック)で再生することで再生が可能になります。

※通常音声とコメンタリーを切り替える場合には、設定変更後にWMV(ASF)ファイルを改めて最初から再生する必要があります。

GOM PLAYER起動後[F5]キーを押して表示される、環境設定画面内の[フィルタ]画面にて設定をおこなってください。

2010年9月14日火曜日

doctrineで生成するschema.ymlに関して

symfonyのタスクでデータベース上に保存されているデータをfixture形式でダンプを取ってくれるタスクがあり、
それを実行してみた。

symfony doctrine:data-dump

すると、
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'v.id' ~
v.idってカラムがないらしい。
そもそもidなんてカラム作ってないのになんでこんなことになってるんだと思って調べてみたら、
エラーが出たのはViewの部分の記述だった。
そこで、schema.ymlを見てみた。
中を見てみると

VHoge:
  connection: doctrine
  tableName: v_hoge
  columns:
    id:
      type: integer(8)
      autoincrement: true
      primary: true
    fuga_id:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: true
      default: '0'
      notnull: true
      autoincrement: false
idってカラムがありました・・・。
なんでこんなカラムが追加されてるんだと思いながらも、削除してみた。
モデルも再生成して、もっかい実行。
同じエラーが・・・。
カラムは削除したはずなのになーと思いながらも、primaryがtrueになっているカラムがないといけないのではないかと思い、fuga_idのprimaryをtrueにして、モデルを再生成して実行してみたら成功しました。

どうやらschema.ymlには必ずprimaryがtrueになっているカラムが1つないとエラーになるみたいです。
あとでソースを追って、ちゃんとした原因を突き止めよう。

2010年9月9日木曜日

iphone4のケースが来た。

思ったよりだいぶ早かった。
到着予定日が10月1日だったのに、今日届いた。
iphone4の時もこのくらい早ければよかったのに…。

ケース自体はまぁまぁいい感じかも。
背面はプラスティックで、側面がシリコンになってる。
結構しっかり作りで以外だった。
今回頼んだケースは黒なんで、気分によって付け替えるとしよう。
とりあえずしばらくはこのケースを使ってみようと思います。

2010年9月8日水曜日

mb_strlenがUndefined function

フォームで入力された文字数チェックしようと思ってmb_strlenを使ったら、Undefined functionって出てきた。
あれっと思ってphpinfo見てみたら…。

ない!!

php-mbstringがインストールされてませんでした…。
最初の段階でちゃんとチェックしておかないと、後々面倒ですね。
yumからサクっとインストールして解決しました。

2010年9月5日日曜日

php.iniのX-Powered-Byについて

HTTPヘッダに付加されているX-Powered-By。
これにPHPのバージョンが表示されている。
セキュリティ面を考えると、サービスイン後のこういった表示は控えるべきだと思われる。
ってことで、その表示を出さないようにする方法は以下のとおり。

php.iniを以下のように書き換えてやればよい。

expose_php = On → Off

で、書き換え後に保存して、Webサーバーを再起動させる。
以上で完了。

2010年9月3日金曜日

symfonyのセキュリティの設定に関して

最近ちょくちょくsymfonyを触るようになってきたので、一度セキュリティに関して調べてみた。
今回気になったのは下記の記事。

http://blog.symfony.jp/2009/03/05/178

この記事ではsf_charsetがUTF-8で、なおかつescaping_methodをESC_ENTITIESにすると問題があるというものです。
古いバージョンのsymfonyではデフォルトがESC_ENTITIESになっていましたが、
1.2以降のsymfonyではデフォルト値がESC_SPECIALCHARSに書き換えられているようですので、
自分で意図的に変更しない限りはトラブルに見舞われることはないと思われますが、一応念のため記事にしておくことにしました。

symfonyでは標準でHTML出力のエスケープ処理が組み込まれており、テンプレートにスカラ、配列、オブジェクトのメソッド呼び出しの結果など、あらゆる値がエスケープされるようになっています。
そのエスケープメソッドがhtmlentitiesであると問題が発生するよということ。
このhtmlentitiesですが、マルチバイトでなければ何の問題もありませんが、
マルチバイトでUTF-8の文字コードの場合に未定義の文字参照が生成されてしまうおそれがあります。
こちらのブログでは「∵」(U+2235)がその該当の文字だということで、取り上げられています。

symfony1.4ではescaping_strategyはデフォルトtrue、escaping_methodもESC_SPECIALCHARSとなっているので、
特に心配する必要はありません。
とはいえ、古いsymfonyを使っている案件の更新とか、途中からアサインされた場合に設定がESC_ENTITIESになっている可能性が0ではないので、一応覚えておこうと思う。

・リファレンス
http://www.symfony-project.org/reference/1_4/ja/04-Settings#chapter_04_sub_escaping_strategy

2010年8月27日金曜日

symfonyのフロントコントローラーとrouting.ymlにはまった

symfonyでフロントエンドと管理画面のアプリを作成しようと思った時にrouting.ymlに記述した変数が取得できなくて、
なんで取得できないのかさっぱりわからなくて、いろいろ検証してみた。



最初の状態はこんな感じ

web/index.php ← フロントエンド用のフロントコントローラー
web/manager.php ← 管理画面用のフロントコントローラー


まず、新しくプロジェクト作成してまっさらな状態できちんと取れるか試してみた。

routing.ymlはこんな感じ

testIndex:
url: /test
param: { module: test, action: index }

test:
url: /test/:value
param: { module: test, action: index }


この場合は特に問題なく取得することができた。



次にルーティングのURLの階層を増やしてみたが、これも問題なかった。



testIndex:
url: /dummyA/dummyB/test
param: { module: test, action: index }

test:
url: /dummyA/dummyB/test/:value
param: { module: test, action: index }


管理画面用のフロントコントローラーの場所を一階層下に変えてみた。



web/manager/index.php


それに伴い.htaccessを書き加えた。



RewriteRule ^manager(.*)$ manager/index.php [QSA,L]


こうするとvalueが取れなくなった。

mod_rewriteのせいなのかもしれない。

が、これをどう書き直せばrouting.ymlがちゃんと取ってくれるのかがわからない…。

そこで、フロントコントローラーのファイル名と場所を元に戻し、.htaccessを以下のように修正してみた。



RewriteRule ^manager(.*)$ manager.php [QSA,L]


こうすると取得できるようになった。

とりあえずこれでよしとする。

2010年8月25日水曜日

symfonyのWebデバックツールに関して

symfonyでプロジェクトとアプリケーションを1つ作成すると、webディレクトリ以下にindex.phpなどのファイルができ、symfonyのデフォルトページを表示させることができるようになるが、この画面で使用されている画像や、webデバックツール(デバックモードで画面右上に表示されるツールバー)に使用されている画像などは初期状態ではパスが違っているため、読み込みできない。
違っている理由としてはスケルトンが用意されており、そこからパスを変更せずにコピーしてくるためである。
それを回避するために、シンボリックリンクを張っていたんですが、バーチャルホストのAliasに書くほうがすっきりしてていい気がしてきたので、これからはその方法でやっていきたいと思う。

2010年8月24日火曜日

iphone4のケースプログラムの注文成立のメールが来た。

お届け予定日は10月1日。
ケース1個届けるのにこんなに時間がかかるのか…。
まぁ、気長に待ってみます。

2010年8月23日月曜日

True Image Homeってかなり使えるかも

最近PCの調子があまりよくなくて、起動するまでにやたら時間がかかるようになってしまった。
1ヶ月前位に再インストールしたばかりなのに・・・。
再インストールはとても面倒な作業で、時間もかかる。
しかもその間は作業が一切できなくなってしまうというデメリットが大変多い。
とはいえ、毎回毎回アプリの起動に時間がかかったり、いきなりシャットダウンされたりとかってのはきつい。
なので仕方なく再インストールするんですが、その時間を極力すくなくできるツールを教えてもらいました。
それがTrue Image Homeです。
このソフトは現在の状況をそのままイメージにしてバックアップをとっておくことができるってソフトです。
で、このバックアップをリストアすれば、バックアップ取った状況が再現できる。
なので、OSを再インストールして、windows updateをして、必須アプリを一通りインストールした状態でバックアップをとっておけば、いつでもその状態に戻すことが可能になります。

2010年8月22日日曜日

再インストール時にやんなきゃいけないこと

1.iTunesのバックアップ
C:\Documents and Settings\ユーザー名\My Documents\My Musicの中のiTunesフォルダをバックアップ

2.Chromeのバックアップ
C:\Documents and Settings\ユーザー名\Local Settings\Application Data\Google\Chromeの中のUser Dataフォルダをバックアップ

3.Adobe製品ライセンス認証を解除する。
Adobe製品のいずれかを立ち上げて、ヘルプ→ライセンス認証の解除をクリック

4.VMWareのVirtual Machinesをバックアップ
C:\のVirtual Machinesをバックアップ

5.その他、必要なファイルをバックアップ

とりあえずこの程度。

iphone4のケースプログラムが8/22で締め切り。

7月23日以前に購入した人達への、ケースプログラムの締め切りが本日中ということであわててケースを選びました。
最初に欲しいケースがなかったので待っていたんですが、結局「コレほしい!!」って感じのやつがありませんでした。
なのでamazonのレビューがあった「Griffin Reveal Etch iPhone 4 Graphite」にしました。
届くまでかなり時間がかかるので、気長に待ちます。

2010年8月17日火曜日

iphone4の近接センサー問題

父親がiphone4のケースを作ってて、そのケースに入れてから通話終了ボタンが押せないって話。
ググってみたら結構いました。
iphone4の前面カメラの右上に近接センサーがあり、その部分がケースに隠れていたため、タッチスクリーンが無効化されてしまい、通話終了ボタンが押せないという現象が起こった。
iphoneのケースを選ぶ際には気をつけないといけないですね。

iphoneの初期化手順

ちょっとしたことからiphone4の初期化しないといけないってことになって調べてみた。

初期化の手順は以下の通り。
1.PCとiphoneを接続しておき、iTunesを起動しておく。
2.ホームボタンとスリープボタンを電源が切れるまで長押しする。
3.電源が切れたらホームボタンは押したままでスリープボタンは離す。
4.iTunesにiphoneが認識されると「リカバリーモードのiPhoneを見つけました」というメッセージが出てくるので、OKをクリックします。

これで初期化は完了。
意外と簡単にできた。

エアー免震ってすごいなー

革命×テレビでエアー免震についてやっていた。
空気の力で住宅を基礎から浮かばせて免震しようという技術です。
しかも導入費用は250万~ってのがすごい!
僕も将来家建てられるようになったら導入したいなー。

※2011年6月7日追記
とはいえ、このエアー免震は直下型地震にはまだ対応できていないみたいです。
今後の改良に期待。

2010年8月14日土曜日

GOM Playerの広告を削除する方法

OS再インストールしたのでGOM Playerをダウンロードしようとしたら、他のキーワードに「gom player スパイウェア」って引っかかっていたので、見てみたらスパイウェアの疑惑があるみたいです…。
かなり前から疑惑があったみたいなんですが、まったく知りませんでした…。
一応ウイルス対策ソフトでアプリのネットワーク利用は禁止しているのですが、それでもちょっと不安なので、GOM Player利用をやめようかとも思ったんですが、結構使える動画再生ソフトだし、長年使っているので多少は愛着もある。
そしたら、GOM Playerのインストール済みディレクトリ内のファイルをいじることで、広告も削除できるし、勝手にインターネットに接続することをできないようにすることができるようです。

やり方は以下の通りです。(今回使用したGOM Playerのバージョンは2.1.25.5015です)
1.「C:\Program Files\GRETECH\GomPlayer」の「GomWeb3.dll」「GrLancher.exe」「GrLancher.ini」を一応バックアップを取って削除します。
この3ファイルは自動アップデートをしているとされているファイルだそうです。
別に自動アップデートする必要はないと思っているので、削除しておきます。

2.「C:\Program Files\GRETECH\GomPlayer」内の「setting.ini」をエディタで開いて「AD_FILE_URL」「AD_HTML_URL」と書かれている行をすべて削除します。
国別のURLが書かれています。多分日本語に設定しているので[URLJPN]と書かれている部分だけ消しておけば問題ないかも知れないですが、念のためすべて削除しておきます。
削除が完了したら上書きされないように読み取り専用にしておきます。

一応ここまでで広告の削除は完了です。
以降はplayerの環境設定の上部に表示されているURL表示を消すための手順です。

1.「C:\Program Files\GRETECH\GomPlayer\skins\basic」内の「SKIN.XML」をエディタで開いて以下の行を修正・削除します。
131行目の「ShowControl("ID_AD_HTML", 0);」を「//」でコメントアウトします。
141行目の「ShowControl("ID_AD_HTML", 1);」を「//」でコメントアウトします。
293行目の「<staticcontrol ID="ID_AD_HTML_STATIC" StaticControlType="transparent" Align="client" FontName="INFO_FONT" FontColor="#FFB945" TextAlign="left,singleline,vcenter,endellipsis,noprefix" InnerGaps="13,0,13,0" Show="1" MinSize="50,0">」の「Show="1"」を「Show="0"」に書き換えます。
294行目の「<browsercontrol ID="ID_AD_HTML" URL="" OffURL="./INFOLINE/infoline.html" Align="client" Show="1" Gaps="13,5,13,3" MinSize="50,0"/>」の「Show="1"」を「Show="0"」に書き換えます。
281行目の「<buttoncontrol Tooltip="" OnEvent="OpenHomepage('http://www.gomplayer.jp/home.html?type=home');" ButtonControlType="bitmap" Image="BTN_CH.BMP" Split="-3" Align="none" Width="autosize" Height="autosize" Gaps="84,3,0,0"/>」を削除します。
334行目の「<flashcontrol CID="CONTROLID_FLASH_MAIN" URL="./GomMain_JPN.swf" Align="client" Gaps="0,0,0,0" />」を削除します。

以上で修正は完了です。
こちらも保存して読み取り専用にしておきます。

この状態で起動すると、広告も表示されず、URLも消すことができました。
またこれで安心して使えそうです。

2010年8月2日月曜日

GoodReaderにファイルをUSB経由で転送する方法

GoodReaderは言わずと知れた有名なアプリですが、ファイル転送に関してはちょっと問題がありました。
最初はUSB転送でファイルのやり取りができたんですが、Appleに言われてその機能を使えないように修正してしまったみたいなんです。
で、それを使えるようにするために色々と面倒なことをしないといけなかったんですけど、
ついに公式で認められたみたいです。
ファイルの転送方法は以下の通りです。

1.iPohneをPCに接続して、iTunesを起動します。

2.デバイスの中にあるiPhoneをクリックします。

3.Appのタブをクリックします。

4.Appの画面を下のほうにスクロールすると、ファイル共有という場所があります。
その下にAppと書かれていて、GoodReaderのアイコンがあるので、それをクリックします。

5.GoodReaderのアイコンをクリックすると右側の画面が「GoodReaderの文書」という表記に変わりますので、変わったことを確認したら、右側の画面下のほうにある「追加」のボタンをクリックして、追加したいファイルを選択します。

6.ファイルの選択が終わって、「GoodReaderの文書」という表に、選択したファイルが表示されていれば追加は完了です。

以上が手順になります。
ここまでやってみて、いくつか問題がありました。
まず一番大きな問題。
ファイルしか追加できない。
フォルダごと追加することはできません。
これを回避するには、一度フォルダをzip形式で圧縮して、iPhoneのGoodReaderで解凍するという作業が必要になります。
また、zipファイル自体に日本語を使うことは可能ですが、zipファイル内のフォルダやファイルに日本語を使うとGoodReader上で文字化けしてます。解凍したら全部見事に文字化けていました・・・。
リネームすれば日本語は問題ないみたいです。
テキストファイルを読むときの文字コードは変更できますが、それ以外では変更できそうな感じのところはありませんでした。

次に大きな問題はiTunesからファイルを追加する時に表示されている階層以外には移動できないってことです。
なのでいちいちファイルを追加した後に、GoodReaderで移動させる必要があります。
まぁそこまでたいした手間ではないですが、できれば改善してほしいですね。

最後にちっちゃな問題。
iTunes上ではフォルダを追加したりすることができません。
フォルダの管理はすべてGoodReaderでやることになりそうです。

と、ここまでつらつら書いてみました。
こんな感じで手間をかけてUSB転送するか、Wifi経由で転送するのかどっちがいいのやら・・・。
もろもろの機能が改善されることを祈っています。

2010年7月27日火曜日

doctrineで生成されるBase~.class.phpと~.class.phpと~Table.class.phpの棲み分けについて

doctrineでmodelを生成すると1つのテーブルに対して以下の3ファイルが生成されます。

例)テーブル名がhogeだった場合に作成されたモデルクラスの場合

base/BaseHoge.class.php
Hoge.class.php
HogeTable.class.php

これらのファイルにはそれぞれ違った役割があり、
それを意識することで綺麗なコードが書けるようになると思います。

BaseHoge.class.phpに関して
こちらはbuildするたびに書き換えられてしまうので、触らないようにしましょう。
もし修正してもbuild-modelのコマンドを実行した時点で新しいファイルに差し替わってしまいます。

HogeTable.class.phpに関して
このクラス内ではテーブルからレコードを取得する処理を記述する。
ようは、テーブルに対して行う処理に関しては全てここに記述する。

Hoge.class.phpに関して
HogeTable.class.phpで取得したレコードに対して処理を実行する場合はこちらに記述する。
つまり、テーブルにレコードを直接取得するような記述は書かない。
あくまでHogeTable.class.phpで取得してきた取得結果に対しての処理を記述するのがこっち。

以上が棲み分けになる。
なぜこのようになるかというのは、継承関係が以下のようになっているからってことみたいです。
・Doctrine_Record > sfDoctrineRecord > Hogeクラス
・Doctrine_Table > HogeTableクラス

・参考文献
http://www.kazu.tv/blog/archives/000954.html

2010年7月26日月曜日

ペースト時にvimのオートインデントを無効にする方法

vimにオートインデントをつけている場合、
複数行にわたるテキストをコピペすると大惨事になります。

これを回避するためにオートインデントをいちいちオフにするとかありえないので、
どうしたもんかと思っていましたが、ググってみたら簡単に出てきました。

やり方は以下の通り。
1.vimでファイルを開き、コマンドモードにしておく。
2.コマンドモードの状態で「:a」と入力してEnter。
3.入力できそうな雰囲気になったら、その状態でペーストしたい内容を貼り付け。
4.Escキーを押すと反映されます。

といった感じでオートインデントを無効にした状態でのペースト可能です。
ちなみにググった時に一緒に出てきたのですが、「:a」でもオートインデントが回避できない場合は
「:a!」と入力してやってみるといいみたいです。
vimのバージョンによって変わるみたいです。

2010年7月25日日曜日

symfonyでContent-Typeを指定する

Conotent-TypeにあるcharsetはApacheで設定したAddDefaultCharsetが基本的には設定されるが、
この部分がコメントアウトされている場合にはcharsetが指定されずにHTTPリクエストヘッダがやりとりされる。

Content-Type text/html

といった感じ。
が、文字化けを防ぐためには、Content-Type内にcharsetを指定しておくほうがいいと思う。
でも、Apacheで設定しまうと、1台のサーバで複数のサイトを運営していた場合に不都合がでる可能性がないとも言い切れない。
そこでsymfonyではview.ymlにContent-Typeが指定できるようになっているので、
これを利用することにする。
以下はview.ymlの記述を抜粋したものである。

default:
  http_metas:
    content-type: text/html

このようになっている部分を以下部分の記述を追加してやる。

default:
  http_metas:
    content-type: text/html; charset=sjis

この用にすればアプリケーションレベルで文字コードを設定することができる。

2010年7月24日土曜日

iphoneアプリの制限

iphoneアプリの価格と容量には制限があるみたいです。
値段は999ドル、容量は2GBが最大みたいです。
一応メモ

2010年7月23日金曜日

いったい何時になったら商品届くんだ、佐川・・・。

先日amazonでゲームを購入したのですが、amazonのアカウントサービスを確認すると、「お近くの配達店まで輸送中です。」と出るんですが、佐川急便のHPにあるお荷物問い合わせサービスで伝票番号を入力すると、「お問い合わせのデータは登録されておりません。」と出てくる。
これが数時間とかならいいんですが、すでに1日たったにも関わらず、まだ登録されない。
いったいいつになったら登録されるんでしょうか・・・。
ちなみに、同日に楽天で買ったサンダルは3時間くらいで登録されていました。
けど、大阪を夜10時過ぎにでて、翌日の15時過ぎても商品が届かないどころか、まだ配達店にも届いてないって・・・。
どういった配達の仕方をしているんでしょうかね。
買った商品は早く手元に欲しいといった客の心理を全く無視したものだと思います。
個人商店などはしょうがないですが、amazonはヤマト1本にして欲しいです。

追記
結局amazonのほうが先に到着し、伝票番号が登録されることはありませんでした・・・。
楽天のほうは19時くらいに到着しました。
大阪からここまで約20時間って・・・。

2010年7月20日火曜日

iphoneアプリについて調べてみた。

もしかしたらiphoneアプリを作ることになるかも知れないので調べてみた時のメモ。

1.iphoneアプリの開発は基本的にMacのXcodeで開発を行う必要がある。
なのでwindowsユーザーはMacへの買い替えを迫られる。

2.日本語が一切使われていないApple IDが必要になる。
(ただし、実機で検証やアプリの配布を考えていない人には必要ありません。ようは、Mac上のエミュレーターで動かしたいだけの人は必要ないということです。)
iphone Developer Programの登録の際、Apple IDアカウントに日本語が使われているとエラーになるので、新しく作るか、Appleに問い合わせるしかないみたいです。

3.開発は基本的にiphoneのエミュレーターを使って開発する。

4.iphone実機で検証する場合には「iphone Developer Program」に登録する必要があり、スタンダードプランで年間10800円する。

5.実機で検証する場合も、検証に使用する実機のデバイス情報を登録する必要があります。
1台ごとにデバイス情報を登録する必要があるので、
数台にインストールしたい場合などはこの作業を繰り返し行う必要があります。

ざっと調べてみた感想を書くと、「めんどくさい」の一言に尽きる。
僕みたいに日本語Onlyの開発者にとっては敷居が高い。
とりあえすググれば問題解決できる程度に資料があるからまだいいけど・・・。


参考ページ
iphoneアプリの開発から販売まで
Mac未経験からのiphoneアプリ開発→申請できるようになるまでの流れ

2010年7月19日月曜日

iphone4はやっぱり早い

しばらく使ってみてやっぱり早いって再度実感しました。
特に速度の違いを実感できたのはGoodReaderでpdfファイルを読み込んだ時でした。
3Gの場合は1ページ読み込むのに4,5秒かかってましたが、4の場合は1秒かからないくらいで表示されます。
画面も縦か横でロックできるようになったし、
GoogleMapもコンパスがついたおかげで道に迷う心配もありません。
これからも色々と使い倒していきたいと思います。

2010年7月16日金曜日

iphone4が来た!

予約開始からほぼ1ヶ月。
長かったですが、ようやく手に入りました!
とりあえず速攻でケースを買いに行って、これから3Gから4へと環境を移行しました。
iphone4すげー早い!!
いやー、ホントにサクサク動きますね。
goodreaderで書籍読んだりしてたんですけど、1ページのロードにかかる時間が全然違う。
ハンパねぇ~。
これからちょっとずついじっていきたいと思います。

あと、使えなくなったiphoneはipodとして使おうかなと思ってます。
au携帯とiphone4とiphone3G。
荷物がまた増えました。

2010年7月15日木曜日

クリップボード拡張アプリの落とし穴

PCを再インストールしてから入れてなかったクリップボード拡張アプリを久々に入れてみた。
今回入れたのはCLCLというアプリ。
スタートメニューに入れて常時起動している状態にしていた。

で、今回ハマったのはリモートデスクトップ上の大容量のファイルをコピーする場合、
コピーするのにやたら時間がかかるということでした。
最初は何でだかさっぱりわからなかったんですが、リモートデスクトップ上の大容量のファイルをカットもしくはコピーすると
「貼り付け情報を準備しています。」
と出てきて200分とかでてきたりした。
なんでこんなに時間がかかんだ?って謎だったんですが、自分の環境に新しく追加したものといえばCLCL位しかないしってことで、CLCLを終了させてみた。
そしたらあっという間にコピペできました。

リモートデスクトップ上のファイルをコピペした場合でも、
接続元のほうのクリップボード使ってるみたいだから、それが大容量でこんなになったのかとも思ったのですが、
であれば、CLCLは関係ないってことになる。
でもそんなことはないはずなので、原因は本来のクリップボード+CLCLのクリップボードにコピーしてるから倍以上の時間がかかってるんじゃないかと思われる。
テキストだけ履歴に入ればいい気がするので、それ以外は履歴に入れないようにしようかな。

iphone4入荷の連絡がついに来た!!

本日16時半頃にようやくソフトバンクショップから連絡が来て、
明日の13時以降に入荷が確定したみたいです。
あー、本当に長かった・・・。
予約一時停止する18日の16時頃に予約して、まさか1ヶ月近く待たされることになるとは。
いつ来るのか気になって気になって、発売日以降毎日2chのiphoneスレを確認してしまいましたよ。
普段2chなんて全くみないのに。

手に入るまでに時間がかかった分、色々と聞きたくないような情報まで伝わってきましたね。
接着剤が乾いてないから液晶が黄ばんでるとか、カメラで写真をとると中心部分が青くなるとか。
液晶の黄ばみは時間が解決してくれるみたいですし、写真に関しても実は普通の携帯の場合でもあるみたいです。
しかも青くなる条件として画面一杯の白い写真を撮ると、画像を綺麗にするために青丸現象が発生するとか。
まぁ特定の条件下だし、これに関してはソフトウェア側の問題っぽいので、後からの対応でもいいかな。
やはり一番の問題はアンテナ問題ですね。いったいどうなるんでしょう?
17日(現地時間だと16日)にappleが会見開くみたいだけど、どんな内容の話になるんだか・・・。
もしリコールするって話になったらまた1ヶ月位待たされることになりそうだし、
かといってそのままの状態でホントに大丈夫なのかって感じではある。
ケースに入れて使えば問題ないとの記事がいくつか書かれているし、
友達が一足先にiphone4手に入れて使ってたけど、そんなに気にしてなかったし・・・。
大丈夫だと願いたいです。

まぁなんにせよすぐにケースを買わねば!

2010年7月13日火曜日

mod_rewriteが効かない

symfonyでrouting.ymlに記述しているにも関わらず、全然効いてない。
キャッシュかなと思ったけど、symfony ccしてみたけど直らない。
で、mod_rewriteがちゃんと効いてるかどうか確認してみたら、これが効いてなかった・・・。
AllowOverrideはちゃんと書いたのになんでだろうと思って、
httpd.confをよく見てみたら

<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>

になってた・・・。
Directoryは記述された階層で書いた設定が、それ以下のディレクトリ全体に反映される。
つまり今回の場合は全てのディレクトリでAllowOverrideは使えないよって状態になっていた。
前からこんなの書いてあったっけと思いつつもこのDirectoryの部分をコメントアウト。
apache再起動。

Internal Server Error

あれっと思ってエラーログを確認すると、

[Wed Jun 16 18:19:22 2010] [alert] [client 192.168.XXX.XXX] /path/to/directory/web/.htaccess: Option FollowSymLinks not allowed here

FollowSymLinksは有効になってないからだめってことみたい。
ちなみにFollowSymLinksとはシンボリックリンクが有る場合はそのリンク先の参照を許可するって設定。

$ vi web/.htaccess
Options +FollowSymLinks +ExecCGI

<IfModule mod_rewrite.c>
RewriteEngine On

# uncomment the following line, if you are having trouble
# getting no_script_name to work
#RewriteBase /

# we skip all files with .something
#RewriteCond %{REQUEST_URI} \..+$
#RewriteCond %{REQUEST_URI} !\.html$
#RewriteRule .* - [L]

# we check if the .html version is here (caching)
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f

# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

確かにsymfonyの初期状態で生成される.htaccessにはFollowSymLinksの指定が追加されている。
じゃあこれを消せば問題解決のはず。
$ vi web/.htaccess
Options +ExecCGI
以下略


で、アクセスしてみたら問題なかった。

2010年7月12日月曜日

Apacheを再起動しようと思ったらエラーになった。

設定ファイルをリロードしようと思って、

# /etc/rc.d/init.d/httpd reload

としたけど、どうせだから再起動するかと思ってapacheの再起動をかけてみたら下記のようなエラーがでた。

# /etc/rc.d/init.d/httpd restart
httpd を起動中: (98)Address already in use: make_sock: could not bind to address [::]:80
(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs
[失敗]

再起動に失敗・・・。
何が原因なんだと思ってググってみた。
どうやら原因は何かしらのプロセスが80番ポート使ってるから、再起動できませんってことみたいです。
なんか他に使うようなことしてたっけかなーと思って確認してみた。
80番と443番ポートをオープンしているプロセスを表示

# lsof -i:80,443
httpd 9326 root 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9326 root 6u IPv6 63291 TCP *:https (LISTEN)
httpd 9328 apache 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9328 apache 6u IPv6 63291 TCP *:https (LISTEN)
httpd 9329 apache 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9329 apache 6u IPv6 63291 TCP *:https (LISTEN)
httpd 9330 apache 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9330 apache 6u IPv6 63291 TCP *:https (LISTEN)
httpd 9331 apache 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9331 apache 6u IPv6 63291 TCP *:https (LISTEN)
httpd 9332 apache 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9332 apache 6u IPv6 63291 TCP *:https (LISTEN)
httpd 9333 apache 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9333 apache 6u IPv6 63291 TCP *:https (LISTEN)
httpd 9334 apache 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9334 apache 6u IPv6 63291 TCP *:https (LISTEN)
httpd 9335 apache 4u IPv6 63286 TCP *:http (LISTEN)
httpd 9335 apache 6u IPv6 63291 TCP *:https (LISTEN)

なんかいっぱいでてきた。
でもこれ全部apacheのプロセスじゃん・・・。
restartする時にちゃんとプロセスが終了しなかったのが原因っぽい。
なぜちゃんとプロセスが終了しなかったのかは今のとこ不明。

対応としてはapacheのプロセスをいったん全部killしてあげる。
killコマンドとはプロセスに対してシグナルを送るコマンド。
このシグナルの中にプロセスを終了させる意味のあるシグナルが含まれている。

# kill 9326

で、プロセスが全部終了しているか確認。

# lsof -i:80,443

何も出なければOK。
apache再起動する。

# /etc/rc.d/init.d/httpd restart

これで問題は解決。
よかったよかった。

2010年7月11日日曜日

よく使うLinuxコマンドをまとめてみた(ファイルの操作関連)

前回、僕がよく使うけどよく忘れるコマンドをいくつか書いたんですが、
どうせならまとめるかと思ってまとめてみました。
とりあえず今回はファイルの操作関連に関するコマンド。
次回以降に続きを書く予定。
予定は未定・・・。


cat
ファイルの中身を表示する。

オプション
-n 行番号を付加する
-b 行番号はつけるが空白行をカウントしない

書式
cat [オプション] ファイル名

例)fileAを行番号を付加した状態で表示する。
$ cat -n fileA



pwd

カレントディレクトリの絶対パスを表示する

オプション
なし

書式
pwd

例)カレントディレクトリのパスを調べる。(/var/www/html以下にいた場合)
$ pwd
/var/www/html



cd
カレントディレクトリを切り替える

オプション
なし

書式
cd 移動先のディレクトリパス(相対でも絶対でもOK)

例)現在のディレクトリから、/var/www/htmlに移動する。
$ cd /var/www/html



ls
ディレクトリ内にあるファイルやディレクトリを表示する。

オプション
-a ドットファイルも含めて表示する
-F 分類記号を付加して表示する。「/」がディレクトリ、「@」がシンボリックリンク、「*」が実行可能ファイル
-l 最終更新日時やファイルやディレクトリのオーナー、パーミッションなどを表示する。
-t ファイルをアルファベット順のソートから最終更新日時でソートしたものを表示する
-R ディレクトリ内を再帰的に表示します。
-C 1行に複数のファイルやディレクトリを表示します。「-1」オプションと同時指定はできない
-1 1行に1つのエントリを表示します。

書式
ls [オプション] (ディレクトリ)

例)現在のディレクトリ内に存在するファイルを全て表示し、パーミッション等を調べる
$ ls -la


cp
ファイルまたはディレクトリをコピーする。windowsでいうコピペができる。

オプション
-i 同名のファイルが存在する場合に確認のメッセージを表示する
-f ユーザーには確認せずに、全て上書きします
-r ディレクトリごとコピーします
-d シンボリックリンクとハードリンクをそのままコピーします
-p 日付やフラグなどのファイル情報をできるだけそのままコピーする
-a コピー元ファイルの構成と属性を可能な限り保持してコピーする。-dprと同義
-u 同名ファイルが存在する場合、コピー元のファイルがコピー先のファイルより新しい場合だけ上書きコピーする

書式
cp [オプション] コピー元のファイルもしくはディレクトリ コピー先のディレクトリ

例)/var/www/html/test.htmlをコピーして/var/www/html/test2.htmlを作成する
$ cp /var/www/html/test.html /var/www/html/test2.html


mv
ファイルまたはディレクトリの移動をする。windowsでいうカット&ペーストやリネームができる。オプションはcpコマンドと同じものが多い。

オプション
-i 同名のファイルが存在する場合に確認のメッセージを表示する
-f ユーザーには確認せずに、全て上書きします
-v ファイルの移動先や変更後のファイル名を表示する
-b ファイルを上書きする場合はファイル名の末尾に「~」チルダがついたファイル名でバックアップを残す
-u 同名ファイルが存在する場合、コピー元のファイルがコピー先のファイルより新しい場合だけ上書きコピーする

書式
mv [オプション] 移動元ファイル 移動先ファイル

例)現在のディレクトリにあるtest.htmlをindex.htmlにリネームしたい
$ mv test.html index.html

例)現在のディレクトリにあるindex.htmlを/var/www/htmlの下に移動させたい
$ mv index.html /var/www/html/index.html


mkdir
新しくディレクトリを作成する。
複数のディレクトリを作成したり、引数に指定したディレクトリが存在しない場合、そのディレクトリを含めて作成することもできる。

オプション
-m パーミッションを指定してディレクトリを作成する
-p 引数に指定したディレクトリが存在しない場合、途中のディレクトリも含めて作成する

書式
mkdir [オプション] ディレクトリ名

例)複数のディレクトリを一度に作成する場合
$ mkdir dir1 dir2 dir3

例)多階層に渡ってディレクトリを作成する場合(/var/www/htmlがあり、/var/www/html/sites/sitenameとディレクトリを作成したい場合)
$ mkdir -p /var/www/html/sites/sitename

例)/var/www/html以下にtestというディレクトリをパーミッション777で作成する
$ mkdir -m 777 /var/www/html/test


rmdir
ディレクトリを削除する。
ただしこのコマンドは空のディレクトリのみ削除できる。
削除対象ディレクトリ内にファイルが存在した場合は、rmコマンドの「r」オプションを利用して削除する必要がある。

オプション
-p 中間ディレクトリを含めて削除する

書式
rmdir [オプション] ディレクトリ名

例)現在のディレクトリ内にあるtestディレクトリを削除する
$ rmdir test


rm
ファイルを削除する。
「r」オプションを利用することでrmdirコマンドと同様の処理が可能。

オプション
-i 削除するかをユーザーに確認してから削除する
-f 削除するかをユーザーに確認しないで削除する
-r ディレクトリを削除する

書式
rm [オプション] ファイル名

例)現在のディレクトリにあるindex.htmlを削除する
$ rm index.html

例)testディレクトリ以下のファイルを全て削除する
$ rm -r test


touch
ファイルの更新日時を変更する。

オプション
-c 引数に指定したファイルが存在しない場合、新規ファイルを作成しない
-m 最終更新日時を変更する
-r file 最終更新日時をfileの日時に合わせる
-t time 最終更新日時をtimeに変更する

書式
touch [オプション] ファイル名

例)index.htmlの最終更新日時を現時刻に変更する
$ touch index.html

例)最終更新日時を2010年7月13日23時59分にする
$ touch -t 201007132359


whereis
プログラムが存在するパスを調べる
似たようなコマンドでwhichがあるが、whichはコマンドのパスのみを表示します。

オプション
-b プログラム(バイナリ)が存在するパスのみ表示する
-m オンラインマニュアルが存在するパスのみ表示する
-s ソースファイルディレクトリが存在するパスのみ表示する
-B path プログラム(バイナリ)検索に使うパスをpathに変更する
-M path オンラインマニュアル検索に使うパスをpathに変更する
-S path ソースファイルディレクトリ検索に使うパスをpathに変更します
-f -B,-M,-Sのオプションを使ってパス指定した場合には、パス指定の終了を表すために使う必要がある

書式
whereis [オプション] プログラム名

例)phpがどこにあるのか調べる
$ whereis php
php: /usr/bin/php /etc/php.d /etc/php.ini /usr/lib/php /usr/share/php /usr/share/man/man1/php.1.gz

例)phpのプログラムファイルが存在するパスだけ表示する
$ whereis -b php
php: /usr/bin/php /etc/php.d /etc/php.ini /usr/lib/php /usr/share/php


2010年7月10日土曜日

よく使うけどよく忘れるコマンド

僕がよく使うコマンドなんですが、よく忘れるのでメモ。


ln
リンクを貼る

オプション
-s シンボリックリンクで別名をつける
-f 同名のファイルがある場合に上書きする
-i 同名のファイルがある場合に上書きするかユーザーに確認する

書式
ln [オプション] オリジナルファイル リンクファイル名

例)/path/to/directory/vendor/pear/data/symfony/web/sfのデータを/path/to/directory/web以下にシンボリックリンクを貼りたい場合
$ ln -s /path/to/vendor/pear/data/symfony/web/sf /path/to/directory/web/



find
ファイルもしくはディレクトリを検索する
検索は再帰的に行われるため開始ディレクトリを指定すれば、
そのディレクトリ以下のファイルやディレクトリが全て検索の対象となる。

検索条件
-name name ファイル名nameで検索する
-mtime n 更新時刻n日前のものを検索する
-user user ファイルのオーナーがuserのものを検索する
-regex regexp パス名の全体が正規表現にマッチするファイルを検索します
-path ptn パス名の全体が文字列ptnにマッチするファイルを検索します

処理方法
-print 検索結果を表示する(デフォルト)
-ls 検索結果のファイル情報を表示する
-exec command [arg] \; 検索結果に対してコマンドcommandを実行する。引数argに"{}"を指定すると、検索結果に置き換えられる
-ok command [arg] \; 検索結果に対してコマンドcommandを確認つきで実行する。引数argに"{}"を指定すると、検索結果に置き換えられる

書式
find 開始ディレクトリ 検索条件 処理方法

例)現在のディレクトリ以下のindex.htmlがどこにあるかを検索し表示する
$ find ./ index.html

例)現在のディレクトリ以下の.svnのファイルを全て削除する
$ find ./ -name ".svn" -exec rm -rf {} \;



grep
ファイル内の文字列を検索する

オプション
-v 指定した文字列パターンを含まない行を表示する
-n 行番号を付加して表示する
-l 指定した文字列を含むファイル名を表示する
-i 大文字と小文字の区別をせずに検索する
-r ディレクトリ以下のファイルを再帰的に読み込んで検索する
-s エラーメッセージを表示しない
-z gzip形式などで圧縮されたファイルを解凍して検索する

書式
grep [オプション] 文字列パターン (ファイル名)

例)index.htmlの中にtestという文字が含まれているか検索
$ grep test index.html

例)psコマンドの実行結果の中からphpを含む業を検索して表示
$ ps auxw | grep php



しかし、Linuxのコマンドを全くもって使いこなせてないし、覚えられてないなー。
もっと色々なコマンドを使うようにならないと・・・。

2010年7月9日金曜日

画像の色を調べる

画像の色と背景色を一緒にしたくて、どうにかして一緒の色にできないかと思って調べてみた。
photoshopのスポイトツールを使うと出来るみたいです。
CS5のWebPremiumにphotoshopがついていたので、今回はそれを使ってやってみた。
スポイトツールを選択して、右クリックすると「カラーをHTMLコードとしてコピー」をクリックすると、
クリップボードに「color="#16進コード"」がコピーされます。
また、「カラーの16進コードをコピー」を選ぶと「16進コード」がクリップボードにコピーされます。

例)白の場合
カラーをHTMLコードとしてコピー
color="#ffffff"

カラーの16進コードをコピー
ffffff

2010年7月7日水曜日

タイムライン上にActionScript書いたらコンパイルエラーになった

初めてタイムライン上にASを書いてみた。
そしたらコンパイルエラー・・・。

「1180: 未定義である可能性が高いメソッド addFrameScript の呼び出しです。」

なんじゃこりゃ。
コメントだけ入れてみてもエラーのまま。
何が原因なんだろうと思って調べてみたら、ドキュメントクラスはSpriteで定義されているのにも関わらず、
stageがMovieClipになっていることが原因みたいです。

自分なりに噛み砕くとドキュメントクラスはSprite(タイムラインを持たない)で定義してあるのに、
Flash IDE上のタイムラインにソースがあるのはおかしいってことみたいです。

なので、対応方法は2つ。
1つめはドキュメントクラスをSpriteからMovieClipに変更する。

例)ドキュメントクラスがMainだった場合
public class Main extends Sprite

public class Main extends MovieClip

2つめはタイムライン上のスクリプトを削除する。
削除というのはコメントアウトということではなく、
タイムライン上に記述されているスクリプト全てを消すことである。

一応この2通りの対応方法がある。

2010年7月6日火曜日

dispatchEventに任意のパラメータを渡す

dispatchEventにパラメータを渡したい場合は自分で拡張するしかないらしい。
FlexSDKには元々mx.events.DynamicEventというものがあるみたいで、それを使えば出来るらしい。
なので、それを元にASのコードを書いてあげればOKみたいです。
ただし、受信側と送信側のどちらにパラメータをつけたいかで実装が変わるようです。
これがDynamicEventクラスの実装。
package {
import flash.events.Event;

public dynamic class DynamicEvent extends Event {
public function DynamicEvent(type:String, bubbles:Boolean = false,cancelable:Boolean = false) {
super(type, bubbles, cancelable);
}

override public function clone():Event {
return new DynamicEvent(type, bubbles, cancelable);
}
}
}


dynamicクラスになっている理由はコンパイルエラーを回避するためらしい。
現在は未検証。

送信側でパラメータを渡したい場合は以下の通り
var event:DynamicEvent = new DynamicEvent("eventName");
event.param1 = "文字列";
event.param2 = [1, 2, 3]; // 配列もOK
dispatchEvent(event);


受信側の設定は以下の通り
// イベントリスナーの設定
addEventListener("eventName", callbackFunction );

// コールバック側
private function callbackFunction(event:DynamicEvent):void {
trace(event.param1);
}


受信側でパラメータを渡したい場合は以下の通り
package {
import flash.display.Sprite;
import flash.events.Event;

public class MyClass extends Sprite {
// constructor
public function MyClass() {
var counter:int = 0;
//addEventListener()の第二引数をクロージャとして渡している
stage.addEventListener("click", function(event:Event):void {
clickHandler(event, counter++);
});
}

// コールバックメソッド
private function clickHandler(e:Event, counter:int):void {
trace( e.type + ':' + counter );
}
}
}


参照元:http://blogs.yahoo.co.jp/k3_labs/4399737.html

2010年7月5日月曜日

AS3のfor文で次の繰り返しに行く

AS3のfor文で次の繰り返しへいきたい場合は「continue」を使う。
JavaScriptと同じだけど、最近はJqueryばかり使っていたので「return false」とか書いてしまった・・・。
一応メモ。

var b = [1,2,3,4,5,6,7,8,9,10];
for ( var a in b ) {
if ( a > 5 ) continue;
trace(a);
}
// 出力
1
2
3
4
5

2010年7月2日金曜日

adobe製品のクロスアップグレード

Win版で無償アップグレード付きのCS4買ったけど、将来的にはMacにしたいなぁーと思って色々調べてみたら、
実はWin版からMac版へのクロスアップデートは可能らしい。
こんな記事が出てきました。
クロスアップグレードって出来ないものだと思っていたので、ちょっとびっくり。
大々的に言っていないだけでカスタマーサポートポータルから連絡入れれば出来るみたいです。
Win版のCS4のWeb Standard買った時点でMac版は諦めてしまっただけにちょっとショック・・・。
CS6が出たら参考にしよう。

AS3でswf自身のパスを取得する

swf自身が設置されているパスを取得するには以下の通り。
ドキュメントクラスの場合は
root.loaderInfo.url;

で取得することが可能。

2010年7月1日木曜日

Flash CS5のActionScriptエディター

Flash CS4のActionScriptエディターがあまりにも使いにくかったので、
CS5には期待してたんですが、やっぱFlashDevelopの方が使いやすいかも。
関数とかクラス名とかの色や、コードアシストとかもFlashDevelopの方が僕的には使いやすいですね。
これからもFlash CS5とFlashDevelopの両方を駆使して作っていこうと思います。

2010年6月30日水曜日

Adobe CS5 Web Premiumアップグレード版が届きました!

申し込んでから約1ヶ月。
ようやく届きました。
申し込みをしてから20日後に無償アップグレードの承認がされ、
さらにそこから1週間待ってようやく届きました。
Adobe製品を初めて買って、初めてアップデートの申し込みをしてみましたが、
正直面倒くさい上に、届くまでに時間かかるし、メールアドレス取ってるくせにメールでの連絡はない。
毎回AdobeのHP見に行って自分のAdobe IDでログインしてカスタマーサポートポータルで問い合わせ状況を確認しないと現状がわからない。
1ヶ月気長に待てる人はいいけど、自分みたいに買ったものはすぐに欲しいタイプの人は待ち遠しくて結構イライラします。
承認完了してからも商品発送の連絡もこないし・・・。
とはいえ本日届いたので、早速これからインストールしてみます。

2010年6月29日火曜日

マスクをかける

画像の端をぼやっとした感じにするためにはマスクとやらをかければいいらしい。
画像の編集とかしたことないからとりあえず用語の意味から調べてみた自分なりの見解。

「マスク」はマスキングテープなどで使われている「マスク」と同義で、
「マスク」とは保護するといった意味がある。

なるほど。
たしかに、昔プラモデルを作る際にマスキングテープを実際使っていたが、
色の境目になる部分にマスキングテープを貼り、先に塗ってある色を保護した状態で、
新しい色を上塗りすることで、綺麗に色の境目を表現することができるようになる。

Flashなどではこのマスキングテープを色々加工できて、
マスキングテープを加工することで保護しているレイヤーを加工しなくても
同様の効果が得られるようになっているって感じだと思われる。

今回はASを使ってマスクをかけてみた。
といってもできることはFlashの方で作業しておく。

手順1

まずマスクをかけたいレイヤーの上にマスク用のレイヤーを追加する。

手順2

追加したレイヤーにマスク用のシンボルを作成する。
このシンボルはどういったマスクをかけるかによって、形や効果の設定を変える必要がある。
今回は画像全体を角丸っぽくしつつ、画面四隅にぼかしを入れる。
なので矩形プリミティブツールを選択してステージ全体よりちょっと小さめに四角を配置する。
矩形オプションで角丸具合を調整してムービープリップシンボル化し、インスタンス名(今回はmask_mcとする)をつける。

手順3

手順2で追加したmask_mcに対してプロパティパネルの下にあるフィルタプロパティにぼかしを追加する。
ぼかしXとぼかしYは任意で調整する。
また表示のブレンドを標準にし、ビットマップとしてキャッシュにチェックをつける。

手順4

マスクをかけたいレイヤーを選択し、そこにあるムービークリップ(main_mc)に対してもプロパティパネルの表示のブレンドを標準にし、ビットマップとしてキャッシュにチェックをつける。

※注意
グラデーションマスクをかける場合は必ずマスクをかける側とかけられる側の両方にビットマップとしてキャッシュの部分にチェックをつける必要がある。

手順5

ASでMovieClipに対してマスクをかける処理を追加する。

main_mc.mask = mask_mc;

以上でグラデーションマスクをかけることができる。
なお、ビットマップとしてキャッシュにチェックをつける代わりに、
AS側で

main_mc.cacheAsBitmap = true;
mask_mc.cacheAsBitmap = true;

としても実現することが可能。

2010年6月28日月曜日

AS3でのxmlの扱い

読み込んだXMLの各ノードやテキストへのアクセス方法。

読み込んだXMLファイルは以下

<?xml version="1.0" encoding="UTF-8"?>
<imageList>
<image display="show">
<main><![CDATA[./img/main1.jpg]]></main>
<thumnail><![CDATA[./img/thumnail1.jpg]]></thumnail>
</image>
<image display="show">
<main><![CDATA[./img/main2.jpg]]></main>
<thumnail><![CDATA[./img/thumnail2.jpg]]></thumnail>
</image>
<image display="hide">
<main><![CDATA[./img/main3.jpg]]></main>
<thumnail><![CDATA[./img/thumnail3.jpg]]></thumnail>
</image>
<image>
<main><![CDATA[./img/main4.jpg]]></main>
<thumnail><![CDATA[./img/thumnail4.jpg]]></thumnail>
</image>
</imageList>


読み込んだXMLファイルをXMLオブジェクトに格納する

var xmlLoader:URLLoader = new URLLoader();
xmlLoader.dataFormat = URLLoaderDataFormat.TEXT;
xmlLoader.addEventListener(Event.COMPLETE, onXMLLoadHandler);

var urlReq:URLRequest = new URLRequest(url);
xmlLoader.load(urlReq);

private function onXMLLoadHandler(event:Event):void
{
var my_xml:XML;
my_xml = new XML(xmlLoader.data);
}


で、このmy_xmlに対して色々していく。
imageノードにアクセスする
trace(my_xml.image);

出力:
<image display="show">
<main><![CDATA[./img/main1.jpg]]></main>
<thumnail><![CDATA[./img/thumnail1.jpg]]></thumnail>
</image>
<image display="show">
<main><![CDATA[./img/main2.jpg]]></main>
<thumnail><![CDATA[./img/thumnail2.jpg]]></thumnail>
</image>
<image display="hide">
<main><![CDATA[./img/main3.jpg]]></main>
<thumnail><![CDATA[./img/thumnail3.jpg]]></thumnail>
</image>
<image>
<main><![CDATA[./img/main4.jpg]]></main>
<thumnail><![CDATA[./img/thumnail4.jpg]]></thumnail>
</image>


mainの中のテキストにアクセスする
trace(my_xml.image.main.text());

出力:
./img/main1.jpg./img/main2.jpg./img/main3.jpg./img/main4.jpg


imageノードのdisplay属性にアクセスする。
trace(my_xml.image.@display);

出力:
showshowhide


imageの1番目にアクセスする
trace(my_xml.image[0]);

出力:
<image display="show">
<main><![CDATA[./img/main1.jpg]]></main>
<thumnail><![CDATA[./img/thumnail1.jpg]]></thumnail>
</image>


imageのdisplay属性がshowになっているものだけにアクセスする
trace(my_xml.image.(hasOwnProperty("@display") && @display == "show"));

出力:
<image display="show">
<main><![CDATA[./img/main1.jpg]]></main>
<thumnail><![CDATA[./img/thumnail1.jpg]]></thumnail>
</image>
<image display="show">
<main><![CDATA[./img/main2.jpg]]></main>
<thumnail><![CDATA[./img/thumnail2.jpg]]></thumnail>
</image>


とりあえず今回使ったのはこんな感じ。

iphone4予約後に連絡が来ない・・・。

iphone4を18日の営業終了前に滑り込みで予約。
店員の話だと6月中位には渡せそうとの話だったが、6月もあと2日で終わり。
6月中は無理でもいいから、とりあえず入荷予定日知りたい・・・。

画像のサイズ変更

Loaderを使って画像を読み込んだ後に、画像のサイズを指定のサイズにしたい場合は以下のようにする。
ちなみに画像はStageやMovieClipに追加した後には変更できないらしい。
かといってloadの直後に実行するとまだ画像が読み込み終わってない場合もあり、確実ではない。
なのでlode完了後、addChildする前にサイズを指定する必要がある。
やり方は以下の通り。

var loder = new Loader();
loader.addEventListener(Event.COMPLETE, onLoadImg);

var request:URLRequest = new URLRequest(url);
loader.load(request);

private function onLoadImg(event:Event){
loader.height = 100;
loader.width = 100;
addChild(loader);
}

MovieClipのインスタンス名からMovieClipインスタンスを取得する

読み込んだ画像を指定のMovieClipに追加しようと思ったが、どうやってMovieClipを取得するのかわからなかったので調べた。
MovieClipのインスタンス名を記述するだけじゃMovieClipObjectは取得できないので、
getChildByNameを使う。

var mc:MovieClip = MovieClip(getChildByName('movieClipName'));
mc.addChild(loder);

パッケージ名について

FlashDevelop使っていろいろやっていたらpackageのとこに勝手にディレクトリ構造がドットシンタックスで書かれた状態で追加されていた。
なんだろうと思ってパッケージ名について調べてみた。

パッケージとは
パッケージとはクラスファイルが保存されているフォルダまでのパスのこと
パッケージは省略可能

命名規則
反転ドメイン命名規則を使う。
接頭辞(com、netなど)は小文字のみ。接頭辞以外で単語を続ける時は区切りを大文字。

だそうです。
ふむ、とりあえず誰かに公開する予定もないし、省略しておいていいかな。

2010年6月25日金曜日

外部のasファイルでドキュメントクラスを変更する場合

例)ドキュメントクラスをTestからTest2へ変更する場合

ドキュメントクラスを変更する場合は左の画像のようにクラスをTestからTest2に修正して保存する。
あと、ASファイル名をTest.asからTest2.asに変更して保存する。
これでドキュメントクラスの変更は完了。

Adobeってひどい

Adobe CS5の無償アップグレードの申し込みをしてから20日間、ようやく変化が・・・。
といっても商品が発送されたのではなく、ただアップグレードの受付が完了したとのこと。
しかもメールで連絡が来るわけでもなく、カスタマーサポートポータルで確認しにいって
ようやく受付完了とわかった。
でも、商品がいつ発送するかはわからない。

「製品のお届けは、お申込みの受付順に順次発送しております。
お申込み多数による在庫切れや流通事情により、発送が遅れる場合が
ございますので、あらかじめご了承ください。」

目安の日数すら書かれていない。
いったい何日待てば届くのだろうか・・・。
はやく使ってみたいなぁ~。

2010年6月21日月曜日

関数の引数に初期値を与えておく

こうやるみたい。
まぁ普通だ。

function dummy(test:string='aaa', flag:Boolean=true){
code...
}

Flashの文字コード

Flashで扱える文字コードはUnicodeとShift-JISの2種類。
Unicodeと言っても標準的に使われている文字コードはUTF-8なので、
現実的にはUTF-8とShift-JISの2種類といっていいと思われる。

FlashでShift-JISを使用する場合にのみ
System.useCodePage = true;

と記述する必要がある。
デフォルトでUTF-8を使うことが想定されているので、
UTF-8を使用する場合には特にこれを意識する必要はない。

2010年6月20日日曜日

flash.display.Spriteとflash.display.MovieClipの違い

Spriteクラスは表示リストの基本的要素で、
グラフィックを表示でき、子を持つこともできる表示リストノード。
ただしSpriteオブジェクトはタイムラインを持たない。

MovieClipクラスはSprite、DisplayObjectContainer、InteractiveObject、DisplayObject、EventDispatcher の各クラスを継承している。
MovieClipオブジェクトには、Spriteオブジェクトとは違ってタイムラインがある。

まぁ最大の違いはタイムラインがあるかないかってことみたい。
タイムライン制御が入っている分、パフォーマンスが悪くなるみたいなので、
Spriteクラスで実現できなかった場合にMovieClipクラスを使うようにしよう。
よく使うと思うので覚えておくことにする。

2010年6月19日土曜日

AS3のループ処理のコストに関して

XMLファイルに書かれている内容を順番に取り出そうと思ってループ処理について調べてみた。

まず書き方。
Arrayクラスの場合(JavaScriptとかと同じ)
arrayName:Array = new Array();
arrayName:Array = [];


Vectorクラスの場合
arrayName:Vector.<typeName> = new Vector.<typeName>();


正直このVectorクラスの書き方は違和感ありまくりです。
ちょっと疑問に思ったのはVectorクラスの場合、短縮形の書き方ないのかなぁ。
調べた感じでてこなかったし、試しに[].<typeName>;って書いてみたけど見事にエラーになったから無理なのかも。ちょっと残念。

次に速度。
wonderflにベンチマークがありました。
for inとfor each inではfor each inの方が早いみたいですね。
ただしfor each inは配列のキーが取得できないので、もしキーが必要な場合は必然的にfor inを使う必要があります。

また、ArrayクラスとVectorクラスでも速度が変わってきます。
Vectorクラスは1つのデータ型のみ格納可能で、0から順に格納することしかできませんが、その分高速に動きます。
なので、優先順位としてはまずVectorクラスを、無理であればArrayクラス使うように癖をつけた方がよい。

今回のXMLファイルのロードに関してはURL:Stringを配列に突っ込むだけの処理だったので、
一番高速なVectorクラスにfor each inで値を格納してみました。
一応理論上は高速なはず。

2010年6月18日金曜日

iphone4を予約してきた

本日の営業終了後に予約を一時停止するとのことだったんで、予約してきた。
入荷日がどのくらいになるのか聞いてみたが、何の情報もないので推測しかできないとのこと。
それでも6月中には渡せるんじゃないかと思うとのこと。
楽しみだ~。

2010年6月16日水曜日

symfony1.4.5でアドミンジェネレーターを作成

楽に管理画面が作れるって聞いてたので使ってみた。
まず結果。

できませんでした・・・。

今回はフロントエンドなしの状態から管理画面を作ろうとしました。
まずこのページにやりかたが書いてあったので、これをベースに進めていきます。
1.プロジェクト作る。
$ ./symfony generate:project test_project

2.database.ymlをデータベースに接続できる状況にする。
$ vi config/database.yml

all:
doctrine:
class: sfDoctrineDatabase
param:
dsn: mysql:host=localhost;dbname=test
username: your_database_username
password: your_database_password

3.管理画面用にアプリケーションを作る。
$ ./symfony generate:app test_project test_app

4.schema.ymlを作るんですが、今回はMySQL_Workbenchを使ってsqlを作っておいたので、
それをデータベースに入れてからbuild-schemaでschema.ymlを作ります。
$ ./symfony doctrine:build-schema

するとconfig/doctrine/schema.ymlができます。
5.fixtures.ymlを作ります。データはとりあえず1つだけ作ります。
$ vi data/fixtures/fixtures.yml

Tablename:
Tablename_1:
field_name1: field_value
:
:

6.doctrine:build-all-reloadってタスクを実行しているのですが、僕の作った環境にはなかったので、
順番に実行していきました。何度も実行するなら自分でタスク作ったほうがいいと思います。
データベースを削除

データベースを新規作成

モデルの作成

モデルからsqlの作成

フォームクラスを作成

フィルターフォームクラスを作成

fixtures.ymlの読み込み

7.apps/test_app/config/routing.ymlに記述を追加
your_database_table_name:
class: sfDoctrineRouteCollection
options:
model: your_database_table_model_class_name
module: your_app_modlue_name
prefix_path: なぞ
column: primary_key_id ← これを書かなかったらエラーになったので追加した。
with_wildcard_routes: true

8.管理画面を作成するタスクを実行する
$ ./symfony doctrine:generate-admin test_app module_name

とりあえずこんな感じで管理画面自体は見れるようにはなったが、以下のような不具合があった。
・cssが読み込まれていなかった→これは
・日本語が文字化けしてる。
・データベースのフィールド数が多い場合リスト表示のテーブルと詳細表示のテーブルが重なって見えない

いろいろよくわからなくて調べた時の資料。
- filterとかformをgenerateし忘れたときにでたエラーの回答
http://samsami2u.wordpress.com/2009/04/06/class-formfilter-not-found-in-symfony/
- デバックモード時にでるconfigのタブの中にあるUserのリストの中のdefault_cultureやcultureを変更しようとした時に調べた資料。結局未解決
http://www.symfony-project.org/jobeet/1_4/Propel/ja/19
http://www.symfony-project.org/reference/1_4/ja/04-Settings
http://www.symfony-project.org/reference/1_4/ja/05-Factories
http://www.kazu.tv/blog/archives/000929.html
http://www.pistolfly.jp/weblog/2006/11/default-culture.html
http://www.pistolfly.jp/weblog/2006/12/userculture.html

シンボリックリンクの張り方

毎回どっちがリンク元で、どっちが設置先か忘れるのでメモ。
今回はsymfonyの画像やスタイルが読み込まれないのを対応するためにリンクを張った

$ ln -s リンク先 設置先(ファイルorディレクトリ)

実際はこんな感じ

$ ln -s /home/username/sites/sitename/vendor/pear/data/symfony/web/sf /home/username/sites/sitename/web/

MySQLでフィールドの一覧を確認するには

以前教えてもらって忘れてたのでメモ。

今までMySQLでフィールドの一覧を取得する時には

mysql> show fields from tablename;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| test_id | int(11) | NO | PRI | NULL | |
| title | varchar(255) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+

とこのようにしていたのですが、もっと短く書けるみたいです。

mysql> desc tablename;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| test_id | int(11) | NO | PRI | NULL | |
| title | varchar(255) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+

このように同じ結果が返ってきます。
これでテーブル確認する時間が短縮できます。

2010年6月15日火曜日

MySQLのテーブルタイプ

よくMyISAMかInnoDBを使うか迷うのですが、この記事を見て大抵の場合はInnoDBでいいのでは?と思いました。
記事に書かれている通り、MyISAMを使うケースは以下の場合にくらいらしいです。

・完全に検索Onlyの場合(基幹系とかから一定間隔で検索用テーブルを再構築する。それ以外の時間は検索のみのようなケース。)
・ログ系のテーブルを出力のみする場合(insertは3~15倍程度MyISAMが高速)

この記事は各種のベンチマークがとってあり、ほとんどの場合にはMyISAMとInnoDBの速度はほぼ変わっていませんでした。
InsertやUpdate、Deleteなどに関してはトランザクションの処理があるため速度が落ちていますが、
正常に処理をするためにはトランザクションは必須だと思いますので、必然的にテーブルタイプはInnoDBということになります。

yumのリポジトリ追加

今回はremiのリポジトリを追加したいと思います。
リポジトリの追加方法は以下の通り。

1.追加したいリポジトリのGPGキーを追加します。

# rpm –import http://rpms.famillecollet.com/RPM-GPG-KEY-remi

2.リポジトリファイルを追加します。(今回はwgetで取得することとする)

cd /etc/yum.repos.d
# wget http://rpms.famillecollet.com/remi-enterprise.repo

3.ファイルの中身を確認して、enabledが0になっているかを確認します。
# vi /etc/yum.repos.d/remi-enterprise.repo

[remi]
name=Les RPM de remi pour Enterpise Linux $releasever - $basearch
baseurl=http://rpms.famillecollet.com/el$releasever.$basearch/

http://iut-info.univ-reims.fr/remirpms/el$releasever.$basearch/

enabled=0
gpgcheck=1
gpgkey=http://rpms.famillecollet.com/RPM-GPG-KEY-remi
failovermethod=priority

[remi-test]
name=Les RPM de remi en test pour Enterpise Linux $releasever - $basearch
baseurl=http://remi.collet.free.fr/rpms/test-el$releasever.$basearch/
enabled=0
gpgcheck=1
gpgkey=http://rpms.famillecollet.com/RPM-GPG-KEY-remi

4.remiのリポジトリを使用する。
# yum --enablerepo=remi install XXXX

2010年6月12日土曜日

yumからPHPのアップデート

CentOS5の公式レポジトリは対応が遅いため、最新のプロジェクトがインストールできなかったりします。

そういった場合には新しいリポジトリを追加して、そのリポジトリから最新版を取得するように設定します。

設定方法は以下の通り。

今回新たに追加するリポジトリはUtter Ramblingsという名前のリポジトリです。

まずUtter RamblingsのURL(www.jasonlitka.com)からRPM-GPG-KEYをインストールするコマンドを実行します。

# rpm --import http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

Utter Ramblingsのリポジトリ情報をyumに追加するため

/etc/yum.repos.d/utterramblings.repo を作成し、下記の内容を記載します。

# vi /etc/yum.repos.d/utterramblings.repo

ファイルの中身は以下の通り

[utterramblings]
name=Jason’s Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=0
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

これでyum updateを実行するとバージョンの古いアプリケーションが全て更新されるのですが、必要なものだけ更新するにはyum updateのあとにパッケージ名を指定します。



更新可能な全てをアップデートする場合。

yum --enablerepo=utterramblings update

更新するパッケージを指定してアップデートする場合。(バージョン指定はしなくても問題ない)

例)PHP5.2.13

yum --enablerepo=utterramblings update php-5.2.13

pear経由でsymfonyのインストール手順

まずpearがインストールされているかを確認。

$ which pear
/usr/bin/pear

pearがインストールされていることを確認。

でpearコマンドを使ってsymfonyをインストールする。

環境依存を極力なくすためにライブラリはすべてプロジェクトディレクトリ内にインストールすることが好ましい。

なので今回は以下のようなvendorディレクトリを作成し、その下にsymfonyをインストールする。

$ mkdir project_dir/vendor
$ cd vendor

$ pear config-create /path/to/project_dir/vendor .pearrc
Configuration (channel pear.php.net):
=====================================
Auto-discover new Channels auto_discover
Default Channel default_channel pear.php.net
HTTP Proxy Server Address http_proxy
PEAR server [DEPRECATED] master_server
Default Channel Mirror preferred_mirror
Remote Configuration File remote_config
PEAR executables directory bin_dir /path/to/project_dir/vendor/pear
PEAR documentation directory doc_dir /path/to/project_dir/vendor/pear/docs
PHP extension directory ext_dir /path/to/project_dir/vendor/pear/ext
PEAR directory php_dir /path/to/project_dir/vendor/pear/php
PEAR Installer cache directory cache_dir /path/to/project_dir/vendor/pear/cache
PEAR data directory data_dir /path/to/project_dir/vendor/pear/data
PHP CLI/CGI binary php_bin
PEAR test directory test_dir /path/to/project_dir/vendor/pear/tests
Cache TimeToLive cache_ttl
Preferred Package State preferred_state
Unix file mask umask
Debug Log Level verbose
PEAR password (for password
maintainers)
Signature Handling Program sig_bin
Signature Key Directory sig_keydir
Signature Key Id sig_keyid
Package Signature Type sig_type
PEAR username (for username
maintainers)
User Configuration File Filename /path/to/project_dir/vendor/.pearrc
System Configuration File Filename #no#system#config#
Successfully created default configuration file "/path/to/project_dir/vendor/.pearrc"

pearコマンドを使ってsymfonyのpearチャンネルを登録し、バージョンを指定してインストールを行う

$ pear -c .pearrc channel-discover pear.symfony-project.com
Adding Channel "pear.symfony-project.com" succeeded
Discovery of channel "pear.symfony-project.com" succeeded

symfonyの1.4.5をインストール

$ pear -c .pearrc install -a symfony/symfony-1.4.5
symfony/symfony requires PHP extension "dom"
No valid packages found
install failed

今度はdomがないのでrootユーザーになってyumでインストール
# yum install php-dom

もう一度symfonyをインストール
$ pear -c .pearrc install -a symfony/symfony-1.4.5
downloading symfony-1.4.5.tgz ...
Starting to download symfony-1.4.5.tgz (3,171,881 bytes)
.............done: 3,171,881 bytes
install ok: channel://pear.symfony-project.com/symfony-1.4.5

あとはvendorディレクトリから、プロジェクトルートディレクトリに戻り、インストールしたsymfonyパッケージからプロジェクトの初期化を行う

$ vendor/pear/symfony generate:project example

これでインストールは完了。

Subversionを使用している場合にはプロジェクトディレクトリ内をsvn addしてからsvn ciする

PEAR MDB2をインストール

PEARのMDB2をインストールしようとしたら

pear install MDB2

こっちは問題なく成功。

pear install MDB2_Driver_mysql

としたら

pear/MDB2_Driver_mysql requires PHP extension "mysql"
No valid packages found
install failed

というエラーが。
PHPのモジュールの中にmysqlがないよって話。
ということでphp-mysqlをインストール

yum install php-mysql

完了したら、再び

pear install MDB2_Driver_mysql

無事インストールが完了しました。

pear upgradeに関して

久々にpearをインストールして見た。
といってもyumからインストールしたので、たいした作業ではないはずだった。
スーパーユーザーになってから

yum install php-pear

で、インストール完了。
インストール後に気がついた。
バージョン指定してない・・・。
なのでupdateする。

pear upgrade php-pear

とすると

WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
pear/Archive_Tar requires PEAR Installer (version >= 1.5.4), installed version is 1.4.9
pear/PEAR dependency package "pear/Archive_Tar" installed version 1.3.1 is not the recommended version 1.3.7, but may be compatible, use --force to install
No valid packages found
upgrade failed

なんか依存関係があってうまくupdateしてくれない。
調べたらバージョン指定してupdateすればOKとのことだったので、最新版の1.9.1を指定してupdateしてみた。

pear upgrade PEAR-1.9.1

と打ったら

pear/Archive_Tar requires PEAR Installer (version >= 1.5.4), installed version is 1.4.9
pear/PEAR dependency package "pear/Archive_Tar" installed version 1.3.1 is not the recommended version 1.3.7, but may be compatible, use --force to install
No valid packages found
upgrade failed

同じエラー・・・。
なんだこれ。
とりあえず1.5.4を指定してupgradeしてみた。

pear upgrade PEAR-1.5.4

そしたら無事にupgradeができました。
んで、こっからさらに最新版である1.9.1にupgrade。
先程と同様に、バージョンを指定。

pear upgrade PEAR-1.9.1

無事完了しました。

2010年6月8日火曜日

FlashCS4とFlashDevelopの連携

FlexSDK+FlashDevelopで開発しようと思っていた関係で、FlashDevelopをせっかくインストールしたのに消しちゃうのがもったいないなーと思っていたら、
FlashとFlashDevelopを連携して開発している人がいるみたいです。
まだちょっとしかFlash触ってないけど、FlashよりFlashDevelopのエディタの方がいい感じな気がする。
extendsするとimport文を勝手に生成してくれるし、他にもいろいろと小技があるみたいです。
ちょっとこの2つを使っていろいろ開発してみようと思います。

2010年6月6日日曜日

vimの設定ファイル(.vimrc)を作る

vimの設定を初期状態から変更する場合はホームディレクトリに「.vimrc」というファイルを作る。
中身はとりあず適当なサイトからコピペ。
"----------------------------------------------------
" 基本的な設定
"----------------------------------------------------
" viとの互換性をとらない(vimの独自拡張機能を使う為)
set nocompatible
" 改行コードの自動認識
set fileformats=unix,dos,mac
" ビープ音を鳴らさない
set vb t_vb=
" バックスペースキーで削除できるものを指定
" indent : 行頭の空白
" eol : 改行
" start : 挿入モード開始位置より手前の文字
set backspace=indent,eol,start

"----------------------------------------------------
" バックアップ関係
"----------------------------------------------------
" バックアップをとらない
set nobackup
" ファイルの上書きの前にバックアップを作る
" (ただし、backup がオンでない限り、バックアップは上書きに成功した後削除される)
set writebackup
" バックアップをとる場合
"set backup
" バックアップファイルを作るディレクトリ
"set backupdir=~/backup
" スワップファイルを作るディレクトリ
"set directory=~/swap

"----------------------------------------------------
" 検索関係
"----------------------------------------------------
" コマンド、検索パターンを100個まで履歴に残す
set history=100
" 検索の時に大文字小文字を区別しない
set ignorecase
" 検索の時に大文字が含まれている場合は区別して検索する
set smartcase
" 最後まで検索したら先頭に戻る
set wrapscan
" インクリメンタルサーチを使わない
set noincsearch

"----------------------------------------------------
" 表示関係
"----------------------------------------------------
" タイトルをウインドウ枠に表示する
set title
" 行番号を表示しない
set nonumber
" ルーラーを表示
"set ruler
" タブ文字を CTRL-I で表示し、行末に $ で表示する
set nolist
" 入力中のコマンドをステータスに表示する
set showcmd
" ステータスラインを常に表示
set laststatus=2
" 括弧入力時の対応する括弧を表示
set showmatch
" 対応する括弧の表示時間を2にする
set matchtime=2
" シンタックスハイライトを有効にする
syntax on
" 検索結果文字列のハイライトを有効にする
set hlsearch
" コメント文の色を変更
highlight Comment ctermfg=DarkCyan
" コマンドライン補完を拡張モードにする
set wildmenu

" 入力されているテキストの最大幅
" (行がそれより長くなると、この幅を超えないように空白の後で改行される)を無効にする
set textwidth=0
" ウィンドウの幅より長い行は折り返して、次の行に続けて表示する
set wrap

" 全角スペースの表示
highlight ZenkakuSpace cterm=underline ctermfg=lightblue guibg=darkgray
match ZenkakuSpace / /

" ステータスラインに表示する情報の指定
set statusline=%n\:%y%F\ \|%{(&fenc!=''?&fenc:&enc).'\|'.&ff.'\|'}%m%r%=
" ステータスラインの色
highlight StatusLine term=NONE cterm=NONE ctermfg=black ctermbg=white

"----------------------------------------------------
" インデント
"----------------------------------------------------
" オートインデントを無効にする
"set noautoindent
" タブが対応する空白の数
set tabstop=4
" タブやバックスペースの使用等の編集操作をするときに、タブが対応する空白の数
set softtabstop=4
" インデントの各段階に使われる空白の数
set shiftwidth=4
" タブを挿入するとき、代わりに空白を使わない
set noexpandtab

"----------------------------------------------------
" 国際化関係
"----------------------------------------------------
" 文字コードの設定
" fileencodingsの設定ではencodingの値を一番最後に記述する
"set encoding=utf-8
"set termencoding=utf-8
"set fileencoding=utf-8
"set fileencodings=ucs-bom,euc-jp,cp932,iso-2022-jp
"set fileencodings+=,ucs-2le,ucs-2,utf-8
set encoding=utf-8
set termencoding=utf-8
set fileencoding=japan
set fileencodings=iso-2022-jp,utf-8,euc-jp,ucs-2le,ucs-2,cp932

"----------------------------------------------------
" オートコマンド
"----------------------------------------------------
if has("autocmd")
" ファイルタイプ別インデント、プラグインを有効にする
filetype plugin indent on
" カーソル位置を記憶する
autocmd BufReadPost *
\ if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal g`\"" |
\ endif
endif

"----------------------------------------------------
" その他
"----------------------------------------------------
" バッファを切替えてもundoの効力を失わない
set hidden
" 起動時のメッセージを表示しない
set shortmess+=I

とりあえずこれで使ってみて、後から調整しよう。