Monthly Archives: 11月 2011

HTTP_Request2でhttps接続できない場合の対策

このエントリーをはてなブックマークに追加
はてなブックマーク - HTTP_Request2でhttps接続できない場合の対策
Share on Facebook

HTTP_Request2::send()でhttpsサイトに接続しようとしたら、下記のようなエラーが返ってきました。

Malformed response:
Unable to connect to ssl://www.google.com:443.
stream_socket_client(): unable to connect to ssl://www.google.com:443 (Unknown error)

Unknown errorというのが一番タチが悪い。エラーが追えません。

検証のためcurlコマンドで同じURLに接続を試みると、ちゃんとレスポンスが返ってきます。何か設定をし忘れているに違いない。

原因

どうやらHTTP_Request::setConfig()で正しい接続設定を行えていない場合、”Malformed response”というエラーが出るようです。 私の場合、オレオレ証明書の許可と社内プロキシの設定を行っていなかったためにはまってしまったようです。

対応

オレオレ証明書を持ったサイトを許可するために、setConfig()でssl_verify_peerssl_verify_hostをfalseに設定してやります。 また、プロキシの設定も行います。

<?php
require_once('HTTP/Request2.php');
$req = new HTTP_Request2();

$req->setConfig(array(
    'ssl_verify_host' => false,
    'ssl_verify_peer' => false,
    'proxy_host' => 'uso.proxy.jp',
    'proxy_port' => '8080',
));

$response = $req->setUrl("https://www.google.com/")->send();
print_r($response);     // HTTPレスポンスが出力される

ほかにも設定項目はあるので、マニュアルを参考に設定を疑ってみてはどうでしょうか。

参考

pear installできないのがpear clear-cacheで解決

このエントリーをはてなブックマークに追加
はてなブックマーク - pear installできないのがpear clear-cacheで解決
Share on Facebook

pear installでパッケージをインストールしようと思いましたが、身に覚えのないエラーが出て困りました。

$ pear install HTTP_Request2
PHP_PEAR_PHP_BIN is not set correctly.
Please fix it using your environment variable or modify
the default value in pear.bat
The current value is:
.\php.exe

$ pear install Net_URL2-2.0.0
SECURITY ERROR: Will not write to C:\DOCUME~1\keijiro\LOCALS~1\Temp\pear\cache\ee3f372dc6f69cdae3c6b0c2a0d1098erest.cacheid as it is symlinked to C:\DOCUME~1\keijiro\LOCALS~1\Temp\pear\cache\ee3f372dc6f69cdae3c6b0c2a0d1098erest.cacheid - Possible symlink attack
install failed

「PHP_PEAR_PHP_BINが間違ってる」「一時ファイルが書き込めない」など言われていますが、どちらも正常に設定できています。

はてどうしたことか。 と思いましたが、pear clear-cacheを実行したらコマンドが通るようになりました。

$ pear clear-cache
reading directory C:\DOCUME~1\keijiro\LOCALS~1\Temp\pear\cache
1024 cache entries cleared

$ pear install Net_URL2-2.0.0

Notice: fwrite(): send of 189 bytes failed with errno=10054 既存の接続はリモート ホストに強制的に切断されました。
 in PEAR\Downloader.php on line 1664
downloading Net_URL2-2.0.0.tgz ...
Starting to download Net_URL2-2.0.0.tgz (11,325 bytes)
.....done: 11,325 bytes
install ok: channel://pear.php.net/Net_URL2-2.0.0

$ pear install HTTP_Request2-2.0.0

Notice: fwrite(): send of 189 bytes failed with errno=10054 既存の接続はリモート ホストに強制的に切断されました。
 in PEAR\Downloader.php on line 1664
pear/HTTP_Request2 can optionally use PHP extension "curl"
pear/HTTP_Request2 can optionally use PHP extension "fileinfo"
downloading HTTP_Request2-2.0.0.tgz ...
Starting to download HTTP_Request2-2.0.0.tgz (97,476 bytes)
......................done: 97,476 bytes
install ok: channel://pear.php.net/HTTP_Request2-2.0.0

Noticeが出ていますが、問題無く使えました。

参考

SQLiteのインメモリDBを異なるPDOオブジェクトから参照するには

このエントリーをはてなブックマークに追加
はてなブックマーク - SQLiteのインメモリDBを異なるPDOオブジェクトから参照するには
Share on Facebook

どうにもSQLiteのインメモリDBの値が取得できなかったので、実験してみました。 いきなり結論を書くと、「あるPDOオブジェクトからは、別のPDOオブジェクトが作成したインメモリDBには接続できない」ようです。

テストコード

<?php
/**
 * SQLiteのオンメモリDBにテストデータを作成し、PDOからアクセスできることを確かめる
 */
try {
    $pdo1 = new PDO('sqlite::memory:', null, null);
    $pdo1->exec('CREATE TABLE uso(id INTEGER PRIMARY KEY, name STRING)');
    $pdo1->exec('INSERT INTO uso VALUES (1, "uhouho");');
    $pdo1->exec('INSERT INTO uso VALUES (2, "mojamoja");');

    // 接続済みのPDOオブジェクトからデータを取得できるか試してみる
    $stmt = $pdo1->query('SELECT * FROM uso');
    if (!$stmt) {
        echo 'Cannot fetch data via $pdo1.';
    } else {
        print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
    }

    // 新たにPDOオブジェクトを作成し、データを取得できるか試してみる
    $pdo2 = new PDO('sqlite::memory:');
    $stmt = $pdo2->query('SELECT * FROM uso');
    if (!$stmt) {
        echo 'Cannot fetch data via $pdo2.';
    } else {
        print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
    }
} catch (Exception $e) {
    exit($e->getMessage());
}

結果

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => uhouho
        )

    [1] => Array
        (
            [id] => 2
            [name] => mojamoja
        )

)
Cannot fetch data via $pdo2.

$pdo1で作成したインメモリDBに、$pdo2からは接続できていません。 どちらも同じ「sqlite::memory:」ですが、見ている領域は異なるようです。

考察

インメモリDB内に作ったテーブルに、複数のPDOオブジェクトからアクセスすることはできませんでした。 アクセスしたければ、テーブルを作ったPDOオブジェクトを使い回すしかなさそうです。

var_dump()の結果をファイルに出力する

このエントリーをはてなブックマークに追加
はてなブックマーク - var_dump()の結果をファイルに出力する
Share on Facebook

file_put_contents()とvar_export()を組み合わせれば、1行で実現できます。

コード

/**
 * 変数のvar_dump()結果をログファイルに出力する。
 *
 * @param mixed $var ダンプしたい変数
 * @param string $path ログファイルのパス
 * @return int ファイルに書き込まれたバイト数。失敗した場合falseを返す。
 */
public function varExportToLog($var, $path) {
    return file_put_contents($path, $var_export($var, true), FILE_APPEND);
}

参考