vim – 設定&編集

Linuxの定番エディタvimの設定

vimrc

set fileencodings=utf-8
set encoding=utf-8
set termencoding=utf-8

UTF-8環境の設定。 termencodingはbashrcとあわせる(デフォルトのbashはeuc-jpになっている)

set autoindent
set tabstop=4

オートインデントの有効化と、ハードタブの文字数。 編集中に一時的に無効化する場合

set number

行数を表示する。

set showmatch

検索でヒットした部分をハイライトする。

vimの基本操作

:w

保存

:q

終了
合わせ技で:wq(保存終了)とか。
編集内容を破棄して終了するなら!をつけて、:q!にする。

gg
GG

ファイルエンドトップ/エンドへ

/検索語

検索。 検索後はnで次のヒットへ、Nで前のヒットへ

%s/検索語/置換/オプション

置換。 オプションはgでファイル全体、cで確認表示(確認+ファイル全体ならgc) 正規表現を使って高度な置換が出来る。

u

元に戻す。 戻しすぎたら、ctrl+r

yy
dd
p
P

1行コピー、1行削除、次の行に貼り付け、前の行に貼り付け。
ddで削除すると、削除内容が自動でバッファに入るので、yy>dd>pの動作をするとコピーしておいた内容が消えるので順序に注意。
複数行ならy行数 enter, d行数 enterとか。

(196)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

PHP 関数がどこから呼ばれたか調べたり & PHP定数

 PHPで共有ファンクションを使っているけど、それがどこから呼ばれているか知らなきゃならないことがある。
 こういうときに利用できる関数がdebug_backtrace()というファンクション。
 PHPでFatalエラーが出たときとかに呼び出し関係を表示したり出来るのはこの仕組みが働いている。
var_dump(debug_backtrace());
とか埋め込んでおくと、その関数が呼ばれたときに、呼び出し関係と各要素のダンプがみられる。

あまりスマートではないけど、ある関数で、特定のコードから呼び出されたら処理を変更したいって言うことがあるが
$backtrace = debug_backtrace();
if($backtrace[2][‘args’][0][‘logic_file’]==’parts/stockman.php’)
の様にして、バックトレースの要素を使って分岐すると言うことも出来る。

PHPの便利な定数。
PHPには便利な変数($_SERVER等)があってよく使われているけど、定数もいくらかそろっていて、これがデバッグ向けの物がほとんどなので、debugネタのついでにメモ。
__LINE__ 行番号。 「__LINE__.’で問題が発生しました’」みたいに例外を投げてみたり。
__FILE__ ファイルのフルパスとファイル名。 変数からも取得できるけどこっちの方が書きやすい。
__DIR__ ファイルの存在するディレクトリ。 dirname(__FILE__)と同義。
__FUNCTION__ 現在の関数名。
__CLASS__ 現在のクラス名。 継承した時に、継承元で定義してある__CLASS__を使ったメソッドを、継承先で呼び出しても継承元のクラス名が戻ってくる点に注意(継承先でも同じメソッドを定義して__CLASS__を呼んでやれば、継承先のクラス名がとれる) これに対して、get_class($this)を呼ぶと、継承先で呼び出せば継承先のクラス名が戻ってくる(まぁ、インスタンスの名前だから当たり前だが)
__METHOD__ 現在の(クラス)メソッド名。
__NAMESPACE__ 現在の名前空間。 名前空間が実装されたのが最近なんで使ったことがない。

(3208)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], PHP | コメントをどうぞ

ディスプレイの違い

 開発って言うかデザイン?
 Webサイトを作る時って、デザイナーが作るわけだけど、彼らの使うディスプレイって、色の良く出るVAやIPSの良質なディスプレイな事が多いし、ビデオカードもQuadroとかFireProとかが載ってたりする。
 他方、ライトユーザはオンボードビデオに安いTNディスプレイを使っていたりして、発色がめちゃくちゃなことがある。
 作業場のPCで淡いカラーリングを施したページを家電量販店の安いPCで表示したら真っ白って事があったり。
 昔は、デザイナーの作業の最終地点が印刷物で、AdobeカラーマッチングしたCMYKで作って、色分解して印刷所に出せば、印刷機とマッチングできているから綺麗に出てきていたわけだけど、今の最終地点はWebが多く、ここのクライアント環境は色々な物があるので、ある程度色をきつめに作っておかないとダメだったり、色がおかしく(良くある青白いもの意外に、赤傾向や緑傾向な環境もあったり)なったりすることもあるのだが、まぁ、この辺は作る側じゃどうしようもないんで、せいぜい、淡い色をちょっと濃い目にして、発色の弱い環境でも消えないようにするくらいしかないな(デザイナーがいくらマッチングしても、結局、クライアントがマッチングできていないのだから)

(83)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

MySQLと文字コードと

まじめも:collationでUTF8日本語を使う場合、候補にutf8_general_ciとutf8_unicode_ciのどちらを選ぶか迷う事がある

これについては、
MySQL5.5ユニコードキャラクタセットの説明
の中程に

For any Unicode character set, operations performed using the xxx_general_ci collation are faster than those for the xxx_unicode_ci collation.

A difference between the collations is that this is true for utf8_general_ci:
ß = s
Whereas this is true for utf8_unicode_ci, which supports the German DIN-1 ordering (also known as dictionary order):
ß = ss

generalはunicodeに比べて高速だと書かれている。
挙動の違いとして、上記エスツェット(ドイツ語拡張文字)の違いが挙げられているが、現在の書法ではss(unicodeの挙動)が正しい。
しかし、日本語の扱いの違いが上げられていないが、実際に評価すると以下の様な挙動を示す。

test_table
id name
1 ユニコード
2 ゆにこーど
SELECT * FROM test_table WHERE name LIKE ‘%ゆにこーど%’;
collation設定 id name
unicode 1 ユニコード
2 ゆにこーど
general 2 ゆにこーど

utf8_unicode_ciにすると、なんとカタカナとひらがな表記が同じであると判定されてしまうのだ。
これだと、実運用上問題が生じることが多いだろうから、一般的には、utf8_unicode_ciではなくutf8_general_ciを使う様にした方がいい。

(306)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], MySQL | コメントをどうぞ

WordPressページ送りが表示されない – MySQLでEXPLAINが毎回実行される

このWordPressを動かしていてページ送り(古い記事へ・新しい記事へ)が動作しない問題が発生した。
MySQLで全SQLログを取得してみると、SELECT文の前に必ず’EXPLAIN 実行予定SELECT文’が実行されていた。
WordPressでは、ページ数を取得するために、MySQLのFOUND_ROWS()を実行して取得している。 これは

SELECT SQL_CALC_FOUND_ROWS * FROM stock LIMIT 0,10;
SELECT FOUND_ROWS();

このように実行すると、SQL_CALC_FOUND_ROWS キーワードをつけたSELECT文のLIMITをつけなかった場合の件数(SELECT count(*) FROM stockの結果に同じ)を得られるのだが、このFOUND_ROWS()は直近の文を読むので、今回の様にEXPLAINが挿入されると↓のようになってしまうので、FOUND_ROWSの戻り値が0になってしまう。

SELECT SQL_CALC_FOUND_ROWS * FROM stock LIMIT 0,10;
EXPLAIN SELECT FOUND_ROWS();
SELECT FOUND_ROWS();

で、このEXPLAINがどこから来ているのか。 WordPressの全ソース検索をしても出てこない。
色々調べて、PHPに行き着いた。
PHP5.3.5ソース
php_mysql.c:1431-1432

int newql = spprintf (&newquery, 0, “EXPLAIN %s”, query);
mysql_real_query(mysql->conn, newquery, newql);

これで実行されていた。 これが実行される条件は、
php_mysql.c:1426

if (MySG(trace_mode))

の条件が指定されていて、このtrace_modeは
php_mysql_structs.h:125

long trace_mode;

で定義されていて、php.iniの

mysql.trace_mode

で設定することが出来て、On(=1)の場合にEXPLAINが自動実行されて、Off(=0)なら実行されないため、WordPressを実行するサーバではmysql.trace_mode=Offとする(php.iniでグローバル設定する以外に、wpの設置ディレクトリに.htaccessを配置してphp_flag mysql.trace_mode Offの記述を入れてもOK)か、WordPressのquery.phpでカウントするSQLをcount()を使う様に修正しなければいけない。

(423)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], MySQL | コメントをどうぞ

MySQLトリガとか

テーブルstockでレコードが削除されるとき自動でバックアップテーブルに挿入するトリガ

DELIMITER ..
CREATE TRIGGER stock_auto_backup
BEFORE DELETE ON stock FOR EACH ROW
BEGIN
INSERT INTO stock_backup(code, name, num, deleted_on) VALUES (OLD.code, OLD.name, OLD.num, unix_timestamp());
END..
DELIMITER ;

MySQLのunix_timestamp()関数により削除時間(now)を追加して記録することが出来る。
全てのUPDATE操作をログしたいとき、DELETEをUPDATEに書き換えれば、トリガでログしておけるので、操作側の修正の手間が省ける。

更に、一定以上古いバックアップを削除する機能もつける場合、END..の前に

DELIMITER ..
CREATE TRIGGER stock_auto_backup
BEFORE DELETE ON stock FOR EACH ROW
BEGIN
INSERT INTO stock_backup(code, name, num, deleted_on) VALUES (OLD.code, OLD.name, OLD.num, unix_timestamp());
DELETE FROM stock_backup WHERE unix_timestamp(deleted_on)<(unix_timestamp()-60*60*24*7); END.. DELIMITER ;

の様にすれば、トリガ実行タイミングで7日より前のレコードをバックアップテーブルから自動削除できる。

なお、MySQLでは同じテーブルの同じ条件に複数のトリガを設定できないので、同じ条件に機能追加する場合は

DROP TRIGGER stock_auto_backup

のようにしてトリガを一度削除する。

とあるテーブルのAUTO_INCREMENT値を変更する。

ALTER TABLE stock AUTO_INCREMENT = 1;

この場合はstockテーブルを1にしている。

(142)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], MySQL | コメントをどうぞ

MySQLアップデート - epel/remiリポジトリ

 開発用にMySQLの全ログを取りたいのでmy.cnfに

log-slow-queries = /var/log/mysql-all-sql.log
long_query_time = 0

を追記して

#touch /var/log/mysql-all-sql.log
#chown mysql:mysql /var/log/mysql-all-sql.log

として、0秒以上かかるクエリをスロークエリログに入れる(=全て記録する)設定をしたらMySQL起動エラーが出た。 古いMySQLでは、ロングクエリタイムは1秒以上を設定しなければならず、0秒指定は5.1系にしないとダメらしい。
 早速、yumでMySQLを更新しようとするが、デフォルトのリポジトリだとMySQLは5.0.77が最新。 ソースを取ってきてビルドするのもありだが、今回は手軽にyumから入れたいので、リポジトリの追加で対応する。
 新しいバージョンが登録されているリポジトリとしては、epelやremiがメジャーだ。

#wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
#wget http://rpms.famillecollet.com/enterprise/5/remi/i386/remi-release-5-8.el5.remi.noarch.rpm
#rpm -Uvh remi-release-5-8.el5.remi.noarch.rpm epel-release-5-4.noarch.rpm

※release-x-yの部分はバージョンなので、新しいのが出ると変わるので、エラーが出るときはブラウザでディレクトリを覗いてファイル名を確認する。
 これで各リポジトリの情報が登録される。
 各リポジトリの情報が追加されただけで、yumコマンドを打っただけでは有効にはならないので

yum –enablerepo=epel,remi list

等の様に、–enablerepoで使用するリポジトリを指定する(標準で有効にすることも出来るが、自動アップデートで更新されると都合の悪いときもあるので、コマンドで指定した方が安心)

yum –enablerepo=remi install MySQL

 
 で導入すると5.1.55に更新出来るが、依存関係でPHPも更新しなければならないようだ。 PHPを更新しても特に不都合はないので、まとめて更新した。
MySQLをバージョンアップしたので、おまじない

#mysql_upgrade –password=パスワード

を実行して、データベースをアップグレードしておく。
 PHPの更新で、date系関数でタイムゾーンを設定していないとWarnが出るようになっているので/etc/php.iniの修正が必要になる。

date.timezone=’Tokyo/Asia’

 設定を済ませてapache/mysqlを再起動

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

 今回の更新ではセッション関連のエラーが出た。
初期設定でroot:apacheだったphpの実行がdaemon:daemonになっていたので、session保管場所のパーミッション不足でエラーが出ていた。
実行権限をrootに戻しても良いが、daemon:daemonで実行した方がセキュリティ的によさげなので

chown daemon:daemon /var/lib/php/session
rm /var/lib/php/session/*

して、対応した。
 なお、phpMyAdminを使っている場合、2.11系になっていると思うが、PHP5.3では推奨されない機能を使用しているためDeprecatedメッセージが出るので、こちらも対応のバージョンに更新する(remiリポジトリに3.3系が入っている; php.ini設定でDeprecatedメッセージを単純に消すことも出来るが、新しいバージョンを使用しない理由もないので更新した)
phpMyAdminを3系にするとblowfishの設定を求められるので、/usr/share/phpMyAdmin/config.inc.phpで

$cfg[‘blowfish_secret’] = ‘適当な文字列’;

を設定する。
 なお、現在のMySQLではlog-slow-queriesが非推奨になっている。
現在は

slow_query_log = 1
slow_query_log_file = /var/log/mysql-slow.log

の様に、スロークエリログの有効をslow_query_logに1を与え(0なら無効)、slow_query_log_fileでスロークエリログファイルを指定する。

(325)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP], MySQL | コメントをどうぞ