[mysqld]

# character-set-server = latin1
# collation-server = latin1_general_ci

#character-set-server = utf8
#collation-server = utf8_unicode_ci

character-set-server = ujis
collation-server = ujis_japanese_ci

#character-set-server = sjis
#collation-server = sjis_japanese_ci

skip-character-set-client-handshake

Xoopsの基本システムに関係する項目(日本語環境EUC-JP)のサンプル推奨値の例;
php.ini 抜粋 php バージョン 4.1.2)

[PHP]

register_globals = Off ;;(強く推奨)セキュリテイ上Onにするのは良くないです。

display_errors = On ;;(強く推奨)XOOPSphpデバグ表示のために必要

;;default_charset = "iso-8859-1" 初期値
;default_charset = "EUC-JP" ;;(任意)EUC-JPを指定すると文字化けが防止されるかも

file_uploads = On ;;(推奨)ファイルのアップロード機能を使うとき必要

[mbstring]
mbstring.encoding_translation = On ;;確認要phpバージョン4.3.Xでは必要かどうかは組み合わせしだい
mbstring.language = Japanese
mbstring.internal_encoding = EUC-JP
mbstring.http_input = auto
mbstring.http_output = pass
mbstring.detect_order = auto
mbstring.substitute_character = none ;

ただし、「skip-character-set-client-handshake」は「character_set_server」の値を参照するので注意。

mysql コマンドでは大丈夫なのに、PHP,perl,accessなどで文字が ? に化けるのは?(文字化け) †

良くある勘違いは、
mysqlコマンドが動いているから、自分のアプリも正しくコード変換するだろう」
というものです。
これは間違いです。

次の節の概念図をじっくり見てください。

MySQL サーバーとおしゃべりしている libmysqlclient.so (libmysql.dll) に、キャラクターセットが埋め込まれています。

mysql コマンドには default-character-set のオプションがあり、キャラクターセットの指定ができます。
これは libmysqlclient.so (libmysql.dll) の埋込キャラクターセットを上書きします。

しかし、MySQL AB が提供しているコマンド(mysqldump, mysql, mysqlimport等)や MyODBC 以外の、
別の誰かが作ったアプリやコマンドは、
my.cnf を読んだり、default-character-set オプションがあったりするわけではありません。
my.cnf を読んだり、default-character-set オプションが使えたり、SET NAMES 文が実行されたりするのは、
あくまでも、アプリ側の責任、作り手の責任なのです。
上の図で言えば、PHPMyAdminPHP 自身の部分に、キャラクターセットの指定をする処理や my.cnf を読む処理を、作り手が意図して書かない限り、実現しないのです。

これは perl だろうが Ruby だろうが、access だろうが、PHP と同じです。
(MyODBC(Connector/ODBC)は設定をすることで、my.cnf の [odbc] グループを読みます。
access で MyODBC を使用しているなら、my.cnf を読むオプションを有効にしておきます。)


コードを書くのが嫌なら(変更することが出来ない状況なら)、libmysqlclient (libmysql,dll) の埋込キャラクターセットを変えるのです。
これは libmysqlclient(libmysql.dll)のコンパイルのし直しを意味します。
なお、5.0.13-rc 以上では、mysqld --skip-character-set-client-handshake とすることで、libmysqlclient はサーバーのキャラクターセットに合せるようになります。
1 つのサーバーで 1 つのキャラクターセットしか使用しない(4.0までのように)のであれば、skip-character-set-client-handshake オプションの指定だけで OK です。
このとき、libmysqlclient の re-compile は不要です。

version 4.1 以上の文字コード変換機能とうまくつきあうには?(文字化け) †

MySQL version 4.1 から、utf8 が組み込まれたり、文字コードの自動変換が組み込まれたりと、けっこう文字周りがかわりました。 4.0までの MySQL とは感覚が変わるので、一応、こうした方がトラブルは少ないね、という経験上のものを書いておきます。

* MySQL 5.0.13-rc 以上の場合、mysqld に skip-character-set-client-handshake オプションを指定する。
* mysqldump には必ず --default-character-set= を指定すること。
* MySQL サーバーとクライアントは、必ず同じキャラクターセットにしておくこと。
* 4.1以上対応のアプリケーションには、必ず "SET NAMES キャラクターセット名" という SQL 文を、サーバーに接続した直後に実行すること。
* データベース名、テーブル名、フィールド名には、マルチバイト文字は使用しないこと。
* マルチバイトキャラクターセットと、latin1などのシングルバイトキャラクターセットを混在させないようにすること。
* キャラクターセットはデータベース単位、テーブル単位、フィールド単位で指定できるが、フィールド単位でのキャラクターセットの指定はなるべく避けた方がよいだろう
* 文字の自動変換機能を抑止する、--default-character-set=binary の使用が便利。
* 既にコンパイル済みのバイナリを使うときは、そのバイナリが作成されたときに埋め込まれている、標準のキャラクターセットを知っておいた方がよい。
o !!! MySQL AB のバイナリは latin1 が標準 !!!
* 自分でコンパイルする場合は、binary キャラクターセットを標準に指定してコンパイルすれば、アプリの変更や設定の変更無しに、MySQL 4.0,3.23 対象のアプリが動く。
* --init-connect='SET NAMES キャラクタセット名' は使わない。これはクライアントコマンドオプション --default-character-set= を無効にしてしまうから。
* 4.1 の mysqldump には --hex-blob というオプションが追加されている。これは BLOB のバイナリデータを壊さずに mysqldump 可能になる。

    • init-connect='SET NAMES キャラクタセット名' は使わない。これはクライアントコマンドオプション --default-character-set= を無効にしてしまうから。

尚、XAMPP(v1.5.1時点)を使っている場合、このオプション(init-connect)が効かないので、
C:\Program Files\xampp\mysql_start.batを開きmysqldの起動オプションに、
「--init-connect="SET NAMES ujis"」を書き加えてください。

尚、XAMPP(v1.5.1時点)を使っている場合、このオプション(init-connect)が効かないので、
C:\Program Files\xampp\mysql_start.batを開きmysqldの起動オプションに、
「--init-connect="SET NAMES ujis"」を書き加えてください。

日本人以外のデベロッパーが作ったバイナリは、ujis,sjis を標準のキャラクターセットにしているわけがありません。
事実 MySQL AB 配布のバイナリは、latin1 が標準です。
それらのバイナリを使って PHPMySQL モジュールを動かせば(作成すれば)、クライアント(PHP)は latin1 で動作し、サーバーは ujis,sjis で動くことになるのです。こうして日本語文字は破壊されます。

これらの問題を避けるには、方法は3つ。

* 5.0.13-rc 以上の場合は、mysqld --skip-character-set-client-handshake オプションを必ず指定する
* PHP(Ruby,Perl,C,...)のアプリの変更。サーバーに接続した後にすぐ、"SET NAMES キャラクターセット名" という SQL 文を実行する
* PHP(Ruby,Perl,C,...)の MySQL モジュールの標準キャラクターセットを、自分が使うキャラクターセットにする。これはアプリの変更はない。しかし、libmysql.dll, libmysqlclient のコンパイルし直しが発生する。
ただし、サーバーもクライアントライブラリーも5.0.13-rc 以上の場合、skip-character-set-client-handshake オプションが mysqld に指定されていれば、この作業は不要。

美しいレイアウト

http://www.hirokiazuma.com/blog/

ブログなんだけど、ヘッダーが1ページで表示されその直下にログのタイトルが見える。はっと気づいたレイアウトの美しさ。最近htmlとか勉強していてデザインが綺麗なサイトをよく参考にしているんだけど、ただの偶然だったのかもしれないけどkajyougenronは美しいと思った。

二段組レイアウトを作ってみた


メニューブロックとメインブロックの二つが水平に並んだレイアウトをCSSで設定する。ブラウザの動作モードは標準準拠としCSSも標準に準拠するよう心がける。なおこのレイアウトはWEBアプリケーションで使用する事を主な目的としているので動作モードの仕様上、JavaScriptが必要な場合はそれを可とする。

2段組のhtmlソースは下記の通り

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang="ja">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>二段組レイアウト-右メニュー</title>
<style type="text/css" media="screen">@import "./css/2column-layout.css";</style>
</head>

<body>

<div id="menublock">

/* ここにメニューコンテンツを記述する */

</div>

<div id="mainblock">

/* ここにメニューコンテンツを記述する */

</div>

</body>

</html>
  • 出来るだけ直感的、メンテナンスの容易なソースを書く。
  • メニューブロック、メインブロックの高さはブラウザ表示領域全体と等しいものとする。
  • メニューブロックの幅は固定幅とする。
  • メインブロックの幅はウィンドウサイズにより変化する。
  • 各ブロックはコンテンツ内容に応じてスクロールバーを表示する。

CSSの手順を下記の通りとする。

  • ブラウザ標準のスクロールバー表示を消す
  • ブロックの表示位置を設定する
  • ブロックの大きさを設定する
  • ブロックの属性を設定する

ブラウザ標準のスクロールバー表示を消す

/* ブラウザ標準のスクロールバー表示を消す */
html
{
 overflow : hidden;
}

コンテンツが表示領域よりはみ出る場合、見栄えをどうするかを設定するのがoverflowである。ブラウザ標準のスクロールバー表示を消すにはタグhtmloverflowをhiddenに設定すればよい。つまり通常表示されるスクロールバーはタグhtmlのスクロールバーである。

ブロックの表示位置を設定する

/* メニューブロックの表示位置 */
#menublock
{
 position : absolute;

 top      : 0px;
 left     : 0px;
}
/* メインブロックの表示位置 */
#mainblock
{
 position : absolute;

 top      : 0px;
 left     : 320px;
}

ブロックの大きさを設定する

/* メニューブロックの大きさ */
#menublock
{
 width    : 320px;
 height   : 100%;
}
/* メインブロックの大きさ */
#mainblock
{
 right    : 0px;
 height   : 100%;
}

一般的なブラウザのCSS標準準拠動作モードではブロックレベル要素の100%指定の高さを表示する場合は注意が必要である。詳しくは「height: n%;の正しい仕様」を参照の事。

前提条件
/* メニューブロック、メインブロック高さの前提条件 */
body
{
 height : 100%;
}
IE6におけるrightの仕様

IE6のCSS標準準拠動作モードではright0pxと指定したにも関わらず僅かな余白が出現する。これは隠したスクロールバーの表示領域である。この余白をなくす為には

  • body幅を100%とする
  • expressionを使ってブロックレベル要素の表示領域幅を計算する

またIE6だけに有効な属性の指定はcssハックを利用し_widthとすれば良い。

/* IE6用のブロックレベル要素表示領域の幅計算 前提条件 */
body
{
 width : 100%;
}
/* IE6用のブロックレベル要素表示領域の幅計算 */
#mainblock
{
 _width : expression((document.body.clientWidth-320)+'px')
}

ブロックのスクロールバー動作

コンテンツがブロックの表示領域をはみ出した場合はブロックレベル要素にスクロールバーを表示するように指定する。

/* コンテンツが表示領域をはみ出した場合の処理 */
#menublock,
#mainblock
{
 overflow : auto;
}

まとめ

以上をまとめると下記のようなソースとなる。

/* ======= ベース ==================================================*/

/* ブラウザ標準のスクロールバー表示を消す */
html
{
 overflow : hidden;
}

/* ======= 表示位置 ================================================*/

/* メニューブロックの表示位置 */
#menublock
{
 position : absolute;
 top      : 0px;
 left     : 0px;
}

/* メインブロックの表示位置 */
#mainblock
{
 position : absolute;
 top      : 0px;
 left     : 320px;
}

/* ======= 大きさ ==================================================*/

/* メニューブロック、メインブロック高さの前提条件 */
body
{
 height : 100%;
}

/* メニューブロックの大きさ */
#menublock
{
 width    : 320px;
 height   : 100%;
}

/* メインブロックの大きさ */
#mainblock
{
 right    : 0px;
 height   : 100%;
}

/* IE6用のブロックレベル要素表示領域の幅計算 前提条件 */
body
{
 width : 100%;
}

/* IE6用のブロックレベル要素表示領域の幅計算 */
#mainblock
{
 _width : expression((document.body.clientWidth-320)+'px')
}

/* ======= ブロックの属性 ==========================================*/

/* コンテンツが表示領域をはみ出した場合の処理 */
#menublock,
#mainblock
{
 overflow : auto;
}

Web標準化Tips」いい感じ。ブロックレベル要素をセンタリングする方法とか知らなかったなー。

height: n%;の正しい仕様 なんて言うのも知らなかった。