ここ最近PHP+PostgreSQLでの開発をしていなかったので、調査に時間がかかってしまった。。。
PHP5.2.6でPostgreSQLに接続で下記のエラーが表示される。
Fatal error: Call to undefined function pg_connect()
PHPINFOでは、PostgreSQL設定関連が表示されていなかった。
php.iniのextension=php_pdo_pgsql.dllのコメントアウトを外していないという凡ミスではなく、Windows版PHP5.2.6自体のバグらしい。
日本PHPユーザ会のメーリングリストで報告されていた。
http://bugs.php.net/にも報告されていた。
Bug #44905 PHP 5.2.6 fails to load PostgreSQL related libraries
LAMPセキュリティを強化する4つの方法:CodeZine
CodeZineさん、こんな誤った記事は速やかに削除してください。
「PHP = トラブル」とか「Perl、Python、Rubyのどれかを使う方が良いでしょう」やら、あいた口がふさがりません。
なんというかとトンデモ科学の域に達しています。
PHPのセキュリティ情報配信などで有名なYasuo Ohgaki (大垣 靖男)さんは以下のようにBLOGでおっしゃっています。
言語を替える事はセキュリティ問題の解決策にはなりません。
via 誤解を招く記事 – LAMPセキュリティを強化する4つの方法
そのとおりだと思います。
「Perl、Python、Rubyなら大丈夫」、それは思考停止にほかなりません。
どんな言語でも、セキュリティについて学習し細心の注意を払って対策しない限り、セキュリティホールはなくなりません。
LAMPのPをPHPからPerl/Python/Rubyに替えるだけではセキュリティは向上しない証拠
通常設定で下記のようにPDOStatement->fetch()を2回使用すると、エラーとなります。
コード:
dsn = 'mysql:host=接続先;dbname=データベース名'
$user = 'ユーザ名'
$pass = 'パスワード'
$dbh = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => 1));
// エラーが発生した場合、PDOException を投げるように設定
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
// QUERY
$stmt = $dbh->prepare("SELECT * FROM customer ORDER BY id");
$result = $stmt->execute();
while ($rows = $stmt->fetch(PDO::FETCH_ASSOC)) {
// var_dump($rows);
// プリペアドステートメント
$sub_stmt = $dbh->prepare("SELECT * FROM order_summary WHERE id = :id");
// 値をパラメータにバインドする
$sub_stmt->bindParam(":id", $rows["id"]);
// 実行
$result = $sub_stmt->execute();
while ($sub_rows = $sub_stmt->fetch(PDO::FETCH_ASSOC)) {
var_dump($sub_rows);
}
// カーソルを閉じてステートメントを再実行できるようにする
$sub_stmt->closeCursor();
$sub_stmt = null;
}
// カーソルを閉じてステートメントを再実行できるようにする
$stmt->closeCursor();
$stmt = null;
} catch (PDOException $e) {
var_dump($e->getMessage());
}
エラー内容:
General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
回避策は、PDOStatement::fetchAll()を使用するか、PDO::MYSQL_ATTR_USE_BUFFERED_QUERYをtrueの設定にすればよいのですが、
PHPのマニュアル::MySQL 関数 (PDO_MYSQL)では、PDOStatement::fetchAll()を推奨しています。
MySQLでしか利用できない、また他データベースと互換性のない設定だからでしょう。
抜粋:
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (integer)
PDOStatement でこの属性を TRUE に設定すると、 MySQL ドライバはバッファ版の MySQL API を使用します。 移植性の高いコードを書くには、代わりに PDOStatement::fetchAll() を使用すべきです。
Example#1 mysql でクエリのバッファリングを強制する
< ?php
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
$stmt = $db->prepare('select * from foo',
array(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true));
} else {
die("このアプリケーションは mysql でしか動作しません。代わりに \$stmt->fetchAll() を使用すべきです");
}
?>
しかし万件単位のデータを扱い場合PDOStatement::fetchAll()ではメモリオーバーフローしてしまう可能性があります。
そう考えると、PDO->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);の方がよいのか……
SQLのLIMIT句で上手く制御すれば良いだけかもしれませんが……



PHPでファイルのtar圧縮・解凍を行う場合、PEARライブラリのArchive_Tarを利用すると良いでしょう。
gz, bz2形式も扱えます。
注意:PHPにzlibのエクステンションが必要です。
圧縮例)
$archiveFile = "archive.tar.gz";
// インスタンス
$Tar = new Archive_Tar($archiveFile, "gz");
$fileList[0] = "file1.txt"; // ファイル
$fileList[1] = "/tmp/work/"; // ディレクトリ
// tar.gzファイル作成
$Tar->create($fileList);
// 追加
$fileList[0] = "/tmp/work1/file2.txt"; // ファイル
$fileList[1] = "/tmp/work2/"; // ディレクトリ
$Tar->add($fileList);

内部文字コードをUTF-8に設定し、CSV処理のプログラムを開発していたのですが、fgetcsv()関数で半角カタカナが取得できない現象ではまってしまいました。
対応策を備忘録として残しておきます。
PHPマニュアルには以下の記載があります。
via PHP Manual
getcsv — ファイルポインタから行を取得し、CSVフィールドを処理する
注意: この関数はロケール設定を考慮します。もし LANG が例えば en_US.UTF-8 の場合、 ファイル中の 1 バイトエンコーディングは間違って読み込まれます。
なので、プログラム内でロケールの設定をします。
ロケールの設定はsetlocale()関数で行うことができます。
via PHP Manual
setlocale — ロケール情報を設定する
CSV処理の前に下記のようにロケールを日本語の設定にすると、fgetcsv()関数が正常動作できます。
//setlocale -- ロケール情報をセットする
setlocale(LC_ALL, 'ja_JP.UTF-8');
// CSV処理
$handle = fopen("test.csv", "r");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
……
追記[2008.02.06]:
最初の公開時
setlocale(LC_ALL, 'ja_JP.');
としていましたが
setlocale(LC_ALL, 'ja_JP.UTF-8');
の方がより正しいと判明しましたので訂正します。
2008/01/03にPHP4.4.8リリースされました。
via PHP公式サイト
PHP 4.4.8 Released
[03-Jan-2008]The PHP development team would like to announce the immediate availability of PHP 4.4.8. It continues to improve the security and the stability of the 4.4 branch and all users are strongly encouraged to upgrade to it as soon as possible. This release wraps up all the outstanding patches for the PHP 4.4 series, and is therefore the last normal PHP 4.4 release. If necessary, releases to address security issues could be made until 2008-08-08.
Security Enhancements and Fixes in PHP 4.4.8:
* Improved fix for MOPB-02-2007.
* Fixed an integer overflow inside chunk_split(). Identified by Gerhard Wagner.
* Fixed integer overlow in strspn().
* Fixed regression in glob when open_basedir is on introduced by #41655 fix.
* Fixed money_format() not to accept multiple %i or %n tokens.
* Addded “max_input_nesting_level” php.ini option to limit nesting level of input variables. Fix for MOPB-03-2007.
* Fixed INFILE LOCAL option handling with MySQL – now not allowed when open_basedir or safe_mode is active.
* Fixed session.save_path and error_log values to be checked against open_basedir and safe_mode (CVE-2007-3378).For a full list of changes in PHP 4.4.8, see the ChangeLog.
Historical PHP 4 Stable: 4.4.8
ChangeLog
さくらインターネットのレンタルサーバーを利用しています。
今までPHP4系しか利用できなかったのですが、コントロールパネルからPHPのバージョンの選択(4.4.7と5.2.5)ができるようになっていました(2007年12月23日現在試用版)。
近いうちにPHP4系最後?のPHP4.4.8のリリースが予定されているようですが、PHP開発チームによるPHP4系のサポートは2007年12月まで、セキュリティフィックスも2008年8月までとなっています。
PHP 4 から PHP 5 への移行に記載されているように下位互換がない変更点がかなりあります。
十分なテスト及び修正期間を設けて移行しましょう。