タグ

ブックマーク / hnw.hatenablog.com (71)

  • PHPのY10K問題 - hnwの日記

    PHPは他の言語と同様に、時刻を扱う際にunix epochからの経過秒数(いわゆるunix time)を利用しています。PHP5.2.6以降では、64bit環境であればunix timeも64bitに拡張されています。これで2038年問題も過去のものになるというわけです。 一方、unix timeが64bitに拡張されたことでカオスな結果になることがあるようです。64bit環境のPHP5.2.11で気づいた点を紹介します。 strtotimeが西暦10K年以降に対応していない <?php var_dump(strtotime("9999-12-31 23:59:59")); // int(253402268399) var_dump(strtotime("+10000-01-01 00:00:00")); //int(946648800) ISO8601的に+10000という書き方は正し

    PHPのY10K問題 - hnwの日記
  • ファイル末尾の連続する改行を取り除く - hnwの日記

    テキストファイルの末尾に改行がたくさんついてたり、逆に1個もついていなかったりすることってありますよね。たくさんあるファイルについて、末尾改行1個だけの形に統一したいなー、と思ったら意外と苦労したので紹介します。 当はもっとシンプルに書けそうな気もするんですが…。 perl -i.bak -pe 'BEGIN{undef $/}s/([^\n])\n*$/$1\n/;' hoge.txt ポイントは「undef $/」です。$/は入力の区切り文字を意味し、デフォルトでは改行文字となっています。これを未定義値にすると、1行を取得しようとしてファイル全体を取得するので、改行を跨いだ置換が可能になります(ファイルが巨大なときには死にかねませんが、手元で作業する分にはいいでしょう)。 ただ、改行を含む文字列の置換ははまりどころが多いので注意が必要です。僕だけかもしれませんが、毎度のことなのにsフ

    ファイル末尾の連続する改行を取り除く - hnwの日記
    shimooka
    shimooka 2009/12/28
    覚えとく
  • SplFixedArrayはPHP標準の配列よりメモリを消費しない - hnwの日記

    PHP5.3.0から実装されたSplFixedArrayというSPLクラスがあります。これはマニュアルによれば下記のようなクラスです。 SplFixedArray クラスは配列の主要な機能を提供します。 SplFixedArray と通常の PHPの配列との主な違いは、 SplFixedArray は固定長であって、整数値で指定した範囲内の添字しか使用できないところです。これにより、より高速な配列の実装が可能となりました。 http://docs.php.net/manual/ja/class.splfixedarray.php 制限はあるけれども高速な配列もどきのクラスだと紹介してありますね。このクラスについて少し調べてみました。 SplFixedArrayの速度 まずはSplFixedArrayが当に速いのかどうか、下記のようなプログラムで実験してみました。実験はPHP5.3.0で行

    SplFixedArrayはPHP標準の配列よりメモリを消費しない - hnwの日記
  • PHPカンファレンス2009でLTしてきました - hnwの日記

    9月5日に、PHPカンファレンス2009のライトニングトーク枠でphpallについて喋ってきました。資料は下記です。 発表資料:「phpall:PHPの全バージョンの挙動を試す」(PDF) Ustream録画:http://www.ustream.tv/recorded/2107844 (他の方のLTも含んでいる動画ですが、僕のLTは7分くらいからです) 過去にPHP勉強会で発表したネタ(参考:「第38回PHP勉強会に参加してきました」)を再度やったようなものです。大勢の前でしゃべるチャンスということで、持ちネタの中で一番ウケのよかったネタを選びましたが、会場の皆様の反応が良くてホッとしました。 ところで、このphpallコマンドはウケ狙いのネタってわけじゃなく、実用的だと思うんですよね。実際、symfony作者のFabienさんも僕のプレゼンを会場で見ていたみたいですが、なんと次のような

    PHPカンファレンス2009でLTしてきました - hnwの日記
  • Symfony Event Dispatcherで遊んでみた - hnwの日記

    Symfony Event Dispatcher とは Symfony Event DispatcherというのはPHPフレームワークであるsymfonyに含まれるライブラリで、GoF*1のObserverパターンの変種です。 このクラスは現在Symfony Event Dispatcherという名前で単体公開されていますので、symfony以外のプロジェクトでも気軽に利用できると思います。全部で300行程度の小さいライブラリで、テストコードが29件書かれています。 また、ガイドとAPIリファレンスが書かれています。レシピ集を見ればsymfonyでどう利用されているかを垣間見ることが出来ます。テストカバレッジ率100%なんてことも書いてありますね。 稿では、PHP5に対応したObserverパターンの実装としてのSymfony Event Dispatcherについて紹介します。 Obs

    Symfony Event Dispatcherで遊んでみた - hnwの日記
    shimooka
    shimooka 2009/07/09
    GoFってマニアの言い方だったのか。。。
  • PCREはUnicode文字プロパティをサポートするとは限らない - hnwの日記

    (2011/05/19追記)CentOS5のpcreパッケージについて言えば、2010年7月以降Unicode文字プロパティが有効になっているそうです。安心ですね!(via「 CentOS5.5でCakePHP1.3系のInflector::slugを正常動作させる方法 - Lism.in * blog - nekoya (id:studio-m)」) PCREというのは、Perl互換の正規表現ライブラリです。PCREは例えばPHPのpreg系関数で利用されていますし、他の処理系でも多く利用されているかと思います。ところで、PCREの挙動は環境ごとに異なる可能性があることをご存知でしょうか。具体的には、Unicode文字プロパティをサポートする環境としない環境とがあり、同じ正規表現でも挙動が変わることがあります。僕はそんなことを考えた事もなかったので、ビックリしました。 同じ原因で、以前の

    PCREはUnicode文字プロパティをサポートするとは限らない - hnwの日記
  • 見直されるべきPHP5の組み込みイテレータ - hnwの日記

    PHPには5.0.0以降SPL (Standard PHP Libray)という枠組みが導入されています。これにより、Iteratorインターフェースを実装したクラスのインスタンスであれば、foreach文で配列と同じように取り扱えます。自分でクラスを作るときもIteratorを実装すれば使うのが楽ですし、コードも読みやすくなると思います。 また、PHPに標準で組み込まれているクラスにはIteratorを実装しているものが多数あります。たとえば僕の手元のPHP5.2.9には24個のイテレータがあり、そのうちいくつかは十分に実用的なクラスです。ただ、日語の資料が少ないせいか、かなり知名度は低いように思います。記事では4つの便利な組み込みイテレータを紹介します。 SPLのクラスにはデザインパターンの考えが多く含まれています。特に、イテレータを元にイテレータを作るような使い方は、保守性の高い

    見直されるべきPHP5の組み込みイテレータ - hnwの日記
    shimooka
    shimooka 2009/05/25
    良いまとめ。でも、配列をオブジェクトにして欲しいのが先
  • array_unique関数がPHP5.2.10から後方互換性を取り戻します - hnwの日記

    「array_unique関数がPHP5.2.9から後方互換性を失いました」の内容について、PHPの中の人も認識を改めたようです。次のようなタレコミがありました。 【速報】「sort()関数は相当おかしい」と PHP 開発者を訴えていた問題で、原告の hnw さんが最高裁で勝訴の模様 http://news.php.net/php.internals/43980 http://wassr.jp/user/moriyoshi/statuses/e04jq6Xu3o id:moriyoshiさんの地道な働きかけのおかげだと思います。ありがとうございます。 そんなわけで、array_uniqueの第2引数のデフォルト値をSORT_STRINGにする(=5.2.8以前の挙動に合わせる)ことで落ち着いたようです。先ほどsnapshotを取って来たところ、5.2系も5.3系も直っていました。 また、P

    array_unique関数がPHP5.2.10から後方互換性を取り戻します - hnwの日記
  • UTF-8→SJIS/EUC-JPの重複文字をまとめてみた - hnwの日記

    文字エンコーディングの変換を行うと、異なる2文字が同じ文字に変換されることがあります。このような文字を重複文字と呼ぶことにします。UTF-8→Shift_JISおよびUTF-8→EUC-JPについて、重複文字を自分用の資料としてまとめてみました。 MacOSX上のPHP5.2.9での実験結果ですが、プログラミング言語や環境によらず気をつけるべき文字一覧ということになると思います。 色のついている部分が重複している部分です。「-」となっているのは変換できなかった文字です。また、ヘッダのカッコ数字ごとに文字エンコーディング変換に利用した関数が異なります。詳細は下記の通りです。 (1) mb_convert_encoding($char, "Shift_JIS", "UTF-8") (2) mb_convert_encoding($char, "SJIS-win", "UTF-8") (3) i

    UTF-8→SJIS/EUC-JPの重複文字をまとめてみた - hnwの日記
  • PHPの==演算子をわかりやすくするパッチ - hnwの日記

    PHPの==がキモい件」でも書きましたが、PHPの==は数値っぽいものに対してアバウトな比較を行う演算子です。 一方で、他の言語の==演算子は正確な比較を行うものばかりだと思います。他の言語の経験者がPHPのソースコードを読み書きする場合に、PHPの==演算子の挙動を想像することは困難です。 つまり、PHPの==演算子の問題点は、他の言語と異なる意味にも関わらず同じ表記を採用していることにあります。見ただけで「アバウトな比較を行う」と想像できれば混乱は避けられるはずです。 そこで、PHPにパッチを当て、新たな演算子を導入してみました。 <?php if ("01" ≒ "0x1") { echo '"01" ≒ "0x1" is true',"\n"; } if ("01" ≈ "0x1") { echo '"01" ≈"0x1" is true',"\n"; } if ("01" ≉

    PHPの==演算子をわかりやすくするパッチ - hnwの日記
    shimooka
    shimooka 2009/04/01
    意外と直感的
  • 巨大なSJISのCSVファイルをfgetcsv関数で処理する - hnwの日記

    さて、前回記事「PHPでメモリ上に一時ファイルを作る」では、file_get_contents関数でCSVファイル全体を取得して文字エンコーディングの変換を行い、変換結果に対してfgetcsv関数を利用しました。しかし、CSVファイルが巨大な場合にはfile_get_contentsを使うとメモリ上限に引っかかってPHPが停止してしまいます。 もちろん、UTF-8CSVファイルに対してfgetcsvを利用するのであれば、どんな大きなCSVファイルだろうと処理することが可能です。なぜなら、fgetcsvはファイルを1行単位で読み込む関数ですから、1行分のメモリ消費だけでファイル全体を読み込み続けられるからです(正確にはストリーム上のデータはバッファリングされるので、バッファサイズ分のメモリは消費しますが)。 それでは、巨大なSJISのCSVファイルをfgetcsvで処理したい場合はどうすれ

    巨大なSJISのCSVファイルをfgetcsv関数で処理する - hnwの日記
    shimooka
    shimooka 2009/03/18
    stream_filter
  • PHPでメモリ上に一時ファイルを作る - hnwの日記

    blog.plastik.jp » PHP5 の fgetcsv() で読み込み内容が腐る現象」という記事を読みました。fgetcsv()だとSJISのCSVファイルがうまく読めないので、UTF-8に直してテンポラリファイルに保存してfgetcsvで読み込む、という筋書きのようです。 ちゃんとtmpfile()を使っていたりしてナイスなコードだと思います。でも、すぐ不要になるデータをディスクに書き込むのはイマイチじゃないでしょうか。ここはメモリに書いた方がカッコいいと思うんです。僕なら下記のようにします。 <?php $data = file_get_contents("example.csv"); $data = mb_convert_encoding($data, "UTF-8", "Shift_JIS"); $fp = fopen('php://memory', 'r+'); fw

    PHPでメモリ上に一時ファイルを作る - hnwの日記
    shimooka
    shimooka 2009/03/17
    ストリームを使ってメモリ上に一時ファイルを作る
  • PHPでマルチバイト対応のtrim関数を作る - hnwの日記

    (2009/06/29)追記4:記事のmb_trim関数が動かない環境があったので、詳細を「PCREはUnicode文字プロパティをサポートするとは限らない」にまとめました。よりポータブルなmb_trim関数も紹介していますので、併せてご覧ください。 追記:「mb_ereg_match('^[\0[:space:]]+$', $str);」で、今回pregで作った正規表現'/^[\s\0\x0b\p{Zs}\p{Zl}\p{Zp}]+$/u'と同一になりました。mb_regex_encoding関数が使える分だけmb_ereg版の方が使い勝手も上です。ちょっとショック。 (2009/02/24 17:00)追記2:もっと簡潔に、「mb_ereg_match('^[\0\s]+$', $str);」でいいことがわかりました。POSIX正規表現風の表記がキモいな、と思っていたので、これは素晴

    PHPでマルチバイト対応のtrim関数を作る - hnwの日記
    shimooka
    shimooka 2009/03/15
    mb_ereg_match('^[\0\s]+$', $str)
  • array_unique関数がPHP5.2.9から後方互換性を失いました - hnwの日記

    追記(2009/06/26):PHP 5.2.10以降、この問題は修正されています。「array_unique関数がPHP5.2.10から後方互換性を取り戻します」も併せてご覧ください。 2/26にPHP5.2.9がリリースされましたが、このバージョンからarray_unique関数が後方互換性を失いました。この関数を利用しているアプリケーションは、PHP5.2.9以降のバージョンでは新たなバグに悩まされるかもしれません。 5.2.9RC1の頃にこの仕様変更に気づいて「PHP Bugs: #47370: array_unique has backward compatibility problem, and SORT_REGULAR is confusing」で指摘してみたんですが、相手にされませんでした。 その後もid:moriyoshiさんが元の動作をデフォルト動作にするよう、中の人と

    array_unique関数がPHP5.2.9から後方互換性を失いました - hnwの日記
    shimooka
    shimooka 2009/03/02
    symfony1.0.19に対してgrep -r array_unique /usr/local/lib/php/symfony/ | wc -lで11かぁ。
  • PHPのsort関数は相当おかしい - hnwの日記

    追記(2009/02/28 15:35):ソートする配列の要素が数値または数値形式の文字列のみの場合は、<、==、>が推移律を満たすので、この記事のような矛盾は起こりません。念のため。 オヤジギャグがこらえられなくなったら立派なオヤジだと思います。それはさておき、今日はPHPのsort関数が不思議な挙動をする例を紹介します。 sort関数の紹介 sort ― 配列をソートする 説明 bool sort ( array &$array [, int $sort_flags= SORT_REGULAR ] ) この関数は配列をソートします。この関数が正常に終了すると、 各要素は低位から高位へ並べ替えられます。 PHP: sort - Manual マニュアルをみる限り普通のソート関数です。省略可能な2番目の引数の意味は次の通りです。 sort_flags オプションの 2 番目のパラメータ s

    PHPのsort関数は相当おかしい - hnwの日記
    shimooka
    shimooka 2009/02/27
    sort関数を使うなら必ずSORT_NUMERICかSORT_STRINGを指定する
  • mb_check_encodingは何をチェックするのか(その1 SJIS編) - hnwの日記

    (2009/02/15 17:20)「個人的な感想」を追記しました。また、下記はPHP5.2.1以降の挙動です。PHP5.2.0以前のmb_check_encodingは更にカオスなので、あまり使い物にならないと思います。 (2009/02/16 12:30)追記2:バグっぽいと思った件は当にバグで、修正がhttp://news.php.net/php.cvs/56276の通り取り込まれました。PHP5.2.9から修正される予定です。 (2009/02/22 16:20)追記3:他のエンコーディングについても調査しました。「(その2 EUC-JP編)」と「(その3 UTF-8編)」も合わせてご覧下さい。 PHPのmb_check_encoding関数が一体何のチェックをしているのか、エンコーディングごとに一通り調べてみます。 まずはSJISとSJIS-win(CP932)について調べてみ

    mb_check_encodingは何をチェックするのか(その1 SJIS編) - hnwの日記
  • PHPとRubyとPythonのparserをいじめてみた - hnwの日記

    下記のようなプログラムを与えると、PHPのparserが「無理っす」と言って死にます。 <?php !!!…(10000個くらい)…!!!true; $ php ./hoge.php PHP Parse error: memory exhausted in /Users/hanawa/hoge.php on line 2yaccによるparserはシフトと還元を繰り返しながら構文解析していきます。単項演算子について言えば、後置された表現が確定するまで還元できませんから、!が連続している間はシフトし続け、トークンをスタックに積み続ける必要があります。 このようにトークンを記録するためのスタックのサイズがPHPでは10000個しかありません。ですから、単項演算子を10000個ほど書くだけで簡単に死にます。他にも、「(」を10000個ほど連続して置くなどの嫌がらせでもPHPを死なせることができま

    PHPとRubyとPythonのparserをいじめてみた - hnwの日記
  • array_unique関数の重複の意味に注意 - hnwの日記

    僕は滅多に使わないのですが、PHPにはarray_uniqueという関数があります。 array_unique ― 配列から重複した値を削除する 説明 array array_unique ( array $array [, int $sort_flags ] ) array を入力とし、値に重複のない新規配列を返します。 PHP: array_unique - Manual ここまでは良いのですが、続いてこんな注意書きも見つかります。 注意: (string) $elem1 === (string) $elem2 の場合のみ二つの要素は等しいとみなされます。 言い換えると、文字列表現が同じ場合となります。 最初の要素が使用されます。 PHP: array_unique - Manual つまり、array_unique関数の「重複」というのは、文字列型にキャストした値同士が等しいという意

    array_unique関数の重複の意味に注意 - hnwの日記
    shimooka
    shimooka 2009/01/26
    これは嫌らしいな。。。
  • phpallコマンドでPHPの全バージョンの挙動を試す - hnwの日記

    追記:1/13頃まで、install-all-php.shにバグがありました。ごめんなさい。今は全バージョンを一気にコンパイルできるはずです。 第38回PHP勉強会でも紹介しましたが、私はPHP5.0.0〜PHP5.2.8までの全バージョンのPHPバイナリを持っています。これはPHPのバージョン間の差異やバグを確認したいときなどに便利です。(参考:「第38回PHP勉強会に参加してきました」) このような環境を作る方法について紹介します。基的には各バージョンのPHPをコンパイルするだけですが、コンパイルが通らない場合があるのでその回避方法と、かんたんインストールスクリプトを用意したのでそれを紹介します。また、全てのバージョンのPHPを順に実行するコマンドphpallについても紹介します。 PHP5をgcc4環境でコンパイルする 実は、PHP 5.0.0-5.0.3はgcc4 でコンパイルで

    phpallコマンドでPHPの全バージョンの挙動を試す - hnwの日記
    shimooka
    shimooka 2009/01/12
    CF-R4+VMwarePlayerだとbuildに2日ぐらいかかりそうだ
  • シェルスクリプトでシンボリックリンク先が同一かチェックする方法 - hnwの日記

    「シェルスクリプト中でシンボリックリンクのリンク先を比較したい -OKWave」というページを見つけたんですが、もっとスマートに出来る気がしたので紹介します。どうやら-ef演算子が利用できるようです。(確証は無いのですが、私の手近では反例を見つけられませんでした) $ touch a b; ln -s a c ; ln -s c d $ ls -lai [abcd] 188974 -rw-r--r-- 1 hanawa hanawa 0 2009-01-05 03:52 a 188976 -rw-r--r-- 1 hanawa hanawa 0 2009-01-05 03:52 b 188977 lrwxrwxrwx 1 hanawa hanawa 1 2009-01-05 03:52 c -> a 188978 lrwxrwxrwx 1 hanawa hanawa 1 2009-01-0

    シェルスクリプトでシンボリックリンク先が同一かチェックする方法 - hnwの日記