blog
« MySQLのUDF関数を作った - アルファベットの文字列をひらがな順にソートする |  TOPへ  | JettyをPort80で起動する方法 »

カテゴリ PHP の記事

PHP

PHPには、Linux、Mac、Windowsなどの異なるOS環境間で改行コードを内部的に自動で切り替えてくれるPHP_EOLという便利な定数が用意されている。Javaでの実装だとSystem.getProperty("line.separator")にあたると思う。PHP_EOLがPHPの内部ではどのように実装されているのか、いまさらながらPHP_EOLと改行コードについて書いてみた。

PHP_EOLが定義されているソースファイルをリーディングする

リーディングするソースコードのPHPバージョンはphp-5.3.1を使う。PHP_EOLの定義箇所は以下のヘッダファイルにあり、PHP_EOL以外の定義済み定数の大半もこのファイルで定義されている。

php-5.3.1/main/php.h の Line47 ~ 71あたり
#ifdef PHP_WIN32         

  #include "tsrm_win32.h"
    ・
    ・
  #define PHP_EOL "\r\n"
   // (OSがWindowsの場合に改行コードが\r\nになる)

#else
    ・ 
    ・ 
 #if defined(__MacOSX__) 
   // ※__MacOSX__このマクロはMacOS10では使われてない
   //   らしい。なのでここの条件分岐にMacOS10は入らない

   #define PHP_EOL "\r" 
    // (OSがMacOS9以前の場合に改行コードが\rになる) 

 #else

   #define PHP_EOL "\n" 
    // (OSがMacOS10、Linux、Unixなどの場合に\nになる) 

 #endif

#endif

このように、OS環境によって、if文で条件分岐し改行コードの文字表現を\r\n\r\nとdefineしているシンプルなソースコードである。わかりやすいように一覧表にまとめてみると以下の関係になり、ネットでも検索すれば同じような一覧内容は確認できる。

改行コード

各OS環境でPHP_EOLが出力する改行コードをASCIIコードで確認してみる

改行コードを標準出力しても分かりずらいので、PHPのord()関数をつかいASCIIコードに変換して出力してみたいと思う。(※Mac環境がないので、Linux、Windows環境のみで)

以下にASCIIコード一覧の抜粋があるが、そこにある太字のASCIIコードが返ってくることが予想できる。ここで問題なのがWindows環境であるCRLF(\r\n)である。そもそもCRLFというASCII文字は存在していない。いったいどのような値がかえるのか?

ASCIIコード

コマンドラインでスクリプトを実行した結果

下記、改行コードを生成するコマンドをOS環境を変えてコマンドラインから実行していってみる。またOS環境における差異を明確化させるために、strlen()関数で出力される改行コードの長さも測った。下記が結果内容である。
php -r 'echo ord(PHP_EOL);'  (改行コードをASCIIコードで出力)

Linux環境で実行した際の結果値:10
Windows環境で実行した際の結果値:13

php -r 'echo strlen(PHP_EOL);'  (改行コードの長さを出力)
Linux環境で実行した際の結果値:1
Windows環境で実行した際の結果値:2

これらの結果から、疑問であったWindows環境における改行コードのASCIIコードの値は13と出力された。ASCIIコード一覧と照らしてみると、13 = CR = \rになる。このような値が返ってきたのはCRLF自身が、ASCIIコードのCR(\r)とLF(\n)を並べて表現しているからである。現にstrlen()関数で長さを取得するとWindows環境(CRLF)では2という値がかえり、2byteの文字列であることがわかる。そのためord()関数にPHP_EOL定数がPHP内部でOS環境を判定して、\r\nをセットしても、先頭1byteの\r = 13が返ってくるというわけである。これはord()関数の異常というわけでなく、正常動作であった。

 
投稿日:2010/01/04 | カテゴリ:PHP | コメント・TrackBack:(0)



Trackback URL

http://blog.fukaoi.org/2010/01/04/php_eol?tb=y&entry_id=19

コメントはこちらからどうぞ

 
 
              
入力された内容
確認内容として表示されます