PHPでOracleDBにアクセスする方法

PHPでOracleDBにアクセスする場合、OracleのOracle Database Instant Clientをインストールする必要がある。

ダウンロード先は以下のURLです
http://www.oracle.com/technetwork/jp/database/features/instant-client/index-352321-ja.html

そこからinstantclient-basic-nt-12.*.*.*.*.zipのファイルをダウンロードする。(Windowsの場合)
解凍して適当なところに格納する。

その後、環境変数のPATHを変更する。格納したフォルダ名を追加する。

PHPのphp.iniを変更する。
;extension=php_oci8.dll
extension=php_oci8.dll

完了後再起動を行うこと。再起動しないと反映されない。

Oracleはライセンスが非常に高いので、業務に利用するには難しいが、勉強程度に触ってみることにする。

chrome バージョン 37.0.2062.103 PDF印刷不具合が発生

chrome バージョン 37.0.2062.103にアップデートを行い、一部のPDF出力時(Chromeから)に少し大きく印刷され、一部はみ出る不具合があった。
最近話題のDirectWrite機能の不具合であると思われます。

DirectWriteを無効にする事のより、症状はなくなりました。

しかし腑に落ちないのは、すべてのPDFに発生するのではなく、一部のPDFのみ発生する事です。
canary版も確認したが、そちらでは発生しなかった。

中国でGoogle Apps完全にアクセスできず・・・

多くの企業が中国へ工場を出していると思います。連絡を取る為にはメールなどインターネットを使ったツールが必需品です。
日本ではGoogle Appsを使っていて便利ですが、中国工場へ出張する際は注意が必要です。
先月まではGMailぐらいは使えたのに、今では完全にアクセスができません。

どうしたらいいのだろうか・・・。
今のところ対応は難しいです。

インターネットを検索すると有料のVPNでは接続できるという情報があります。
しかしわざわざお金を出して、賭けに出るのも嫌なので、確実につながる方法を探しました。

一番簡単な方法はマイクロソフトのLiveメール(Outlook.com)を使用する方法です。
「メール アカウントのインポート」を行い、Gmailのインポートを行います。
いくつかの設定をこなった後にインポートが開始され、すべてのデータがインポートされるまで待ちます。
すべてのインポートが終わらないと新しいメールなどはインポートされないようです。

IMAP機能というより、インポート機能ですね。
使い方が間違っている可能性がありますが、とりあえずメールは送れます。

FATAL: erealloc(): Unable to allocate XXXXXX bytes エラー対策

FATAL: erealloc(): Unable to allocate XXXXXX bytes

いろいろなサイトで対策が記載されていますが、実施してみてもなくなることはありません。

なぜ起きるの検証してみました。httpd.confのThreadsPerChildを1000程度にしてみて、いつメッセージが出るのかタスクマネージャを見ながら確認してみました。
ThreadsPerChildを大きくすると発生する期間が短くなることはわかってきました。しかしThreadsPerChildを小さくしても必ず発生するようです。

ThreadsPerChildを1000にして5分後にエラー発生し、その時のメモリ使用量を確認しました。メモリは600MByteほどした。
すごい勢いでメモリーが食っていくようです。(私の環境ではWindows+Apache+phpです)

メモリが増えすぎて発生するわけではないと思いますが、何らかのメモリの異常であることは判るので、Apacheの再起動を定期的に行う事でメモリをクリアするとどうなのだろうか?
Windowsの再起動はHELPで確認、”-k restart : tell running Apache to do a graceful restart”となっているので、graceful restartであることを確認。
(強制終了ではないので、データベース接続にのも安心です)

ThreadsPerChildを100程度にして、”httpd.exe -k restart”を1時間ごとに実行するようにした。
バッチファイル ApacheRestart.bat

"C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin\httpd.exe" -k restart

1日経過してみて、エラーは1度も発生しなかった。
同じ現象がある方々には、この方法をおすすめします。
但し、今回のケースはWindowsなのでLinuxの場合は、”graceful”で再起動する事をおすすめします。

DebinaでPDFを直接印刷する常駐PHPの作成

ローカルポート1025待ち受けして、サーバからの指示したPDFファイルを印刷するプログラムを作成した。
これはインターネット環境での動作確認はされていないので、ご注意ください。

ファイル名:/usr/local/bin/KaneyanPdf2Prn.php

#!/usr/bin/php -q
<?php
echo "PROGRAM START.....\r\n";

////////////////////////////////////////////////////////////////////////////////
//初期設定
$address = '0.0.0.0';  //全アドレスを対象とする
$port = 1025;
////////////////////////////////////////////////////////////////////////////////
set_time_limit(0);
ob_implicit_flush();
//ソケット作成
if (($master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
    echo "socket_create() failed: reason: " . socket_strerror($master) . "\n";
}
//ソケットの種類を設定する
socket_set_option($master, SOL_SOCKET,SO_REUSEADDR, 1);
//ソケットのバインド
if (($ret = socket_bind($master, $address, $port)) < 0) {
    echo "socket_bind() failed: reason: " . socket_strerror($ret) . "\n";
}
//ソケット待ち受け
if (($ret = socket_listen($master, 5)) < 0) {
    echo "socket_listen() failed: reason: " . socket_strerror($ret) . "\n";
}

////////////////////////////////////////////////////////////////////////////////
//受信データが来た場合
function handle_client($allclient, $socket, $buf, $bytes,$txtCount) {
        echo "受信データ:".$buf."\r\n";
        //受信データ例:"http://xxx.xxx.xxx.xxx/test.pdf" "test.pdf" "HL2270DW" "" ""

        $aryDat = str_getcsv($buf,' ','"');
        print_r($aryDat);
        $url=$aryDat[0];
        $Download = $aryDat[1];
        $Printer = $aryDat[2];
        $data = file_get_contents($url);
        file_put_contents($Download,$data);
        exec("lpr -P".$Printer." ./".$Download);
}
////////////////////////////////////////////////////////////////////////////////
//受信待ち受けルーチン
$read_sockets = array($master);
$txtCount=0;
while (true) {
        $ret= 0;
        $changed_sockets = $read_sockets;
        $num_changed_sockets = socket_select($changed_sockets, $write = NULL, $except = NULL, NULL);
        foreach($changed_sockets as $socket) {
                if ($socket == $master) {
                        if (($client = socket_accept($master)) < 0) {
                                echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
                                continue;
                        }else{
                                array_push($read_sockets, $client);
                        }
                }else{
                        $bytes = socket_recv($socket, $buffer, 2048, 0);
                        if($bytes == 0) {
                                $index = array_search($socket, $read_sockets);
                                unset($read_sockets[$index]);
                                socket_close($socket);
                        }else{
                                $allclients = $read_sockets;
                                array_shift($allclients);    // remove master
                                $txtCount++;
                                $ret = handle_client($allclients, $socket, $buffer, $bytes,$txtCount);
                        }
                }
        }
}
socket_close($master);
exit(-1);
?>

属性の変更を行う。

# chmod 755 /usr/local/bin/KaneyanPdf2Prn.php

パソコン自動起動時する場合のスクリプト作成

起動用スクリプトを作成

vi /etc/init.d/KaneyanPdf2Prn

ファイル名:/etc/init.d/KaneyanPdf2Prn

#!/bin/sh
### BEGIN INIT INFO
# Provides:          KaneyanPdf2Prn
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# X-Start-Before:
# X-Stop-After:
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description:
# Description:
### END INIT INFO

case "$1" in
  start)
        /usr/local/bin/KaneyanPdf2Prn.php &
    ;;
  stop)
    ;;
  restart)
    ;;
  reload|force-reload)
    ;;
  status)
    ;;
  *)
esac

属性の変更を行う。

# chmod 755 /etc/init.d/KaneyanPdf2Prn

起動時の自動起動設定(Debian 7の場合)

# update-rc.d KaneyanPdf2Prn defaults

apache 2.2 再起動連発する現象について その2

ログを確認していると何らかのエラーで再起動しているようである。
このメッセージは昔からよく見ていたが、原因が分からなかった。

FATAL:  erealloc():  Unable to allocate 1441792 bytes
[notice] Parent: child process exited with status 1 -- Restarting.

連休という事で実験に適しているので、再度インターネットで確認してみた。
どうもWin32DisableAcceptExが原因らしい。Winsocket2で問題があるからと昔調べてこの記述をしたのだが…

Win32DisableAcceptEx

環境が変わりWindows Server 2012では違うのかもしれない。
とりあえずコメントにして稼働させておくことにした。

# Win32DisableAcceptEx

頻繁に再起動していたのがうそのようになくなった。しかし0ではないのが残念です。
とりあえず様子を見ておくことにする。

apache 2.2 再起動連発する現象について その1

apacheのログを検証するとたびたび再起動しているのが判る。

[notice] Child 2768: Process exiting because it reached MaxRequestsPerChild. Signaling the parent to restart a new child process.

MaxRequestsPerChildが何らかの原因らしいことはわかった。
httpd.conf内を確認

MaxRequestsPerChild 100

根拠はないが100ぐらいでいいだろうというのが間違いだったみたいです。
インターネットで検索してみると上限を無くす為に0にする。

MaxRequestsPerChild 0

これで再起動されていない事を確認した。

Apache 2.2.25 アクセスが遅い現象

ある時突然サーバのアクセスが遅くなる現象が発生した。
込み合っているのであろうと思い、しばらく様子を見ていたが改善されず。

タスクマネージャを眺めていると、2つあるApacheのタスクの1つがCPU3%以上になることに気付いた。
そのタスクはそれほどCPUを上げないになぜか3~5分間隔(?)でCPUが上がってしまうのです。
その時にサーバにアクセスするとなぜかつながりにくい現象が出ました。
20140426_apache2.2.25_Error1

これはサービス起動のタスクっぽいので、サービス起動をストップして、直接コマンドラインで起動しました。

20140426_apache2.2.25_Error2

その後同様に減少が現れず、サーバが遅くなる現象もなくなりました。

バージョンは2.2.25なので、2.2.27へのバージョンアップを検討しています。

追記
error_logを確認してみると再起動が頻繁に起きていた。

[notice] Child 10976: Process exiting because it reached MaxRequestsPerChild. Signaling the parent to restart a new child process.

MaxRequestsPerChildのパラメータを最近触っていたのですが、このあたりが原因の可能性があります。

MaxRequestsPerChild 0 へ変更

しかしそのあともログを確認すると再起動しているようである。でも上のメッセージではなく、メッセージが変わってきました。

FATAL:  erealloc():  Unable to allocate 11028481 bytes
[Sat Apr 26 14:34:28 2014] [notice] Parent: child process exited with status 1 -- Restarting.

このメッセージはPHPに関係しているようです。