0

データをフェッチするために、dll フォームのウィンドウ用に記述されたアプリケーション ライブラリを使用して PI データソースにアクセスする必要がある php Web アプリケーションがあります。PHP は非ポリモーフィズムであるため、ポリモーフィズム ライブラリを使用するために C#-Dotnet で記述されたラッパーを使用しています。

PHP->Wrapper->Lib->PI-System

問題: PHP は、ログを残さずに、com オブジェクトの作成時にクラッシュします (ほとんどの場合、2 回目のリクエストごとに)。私の考えでは、おそらく既存のphpコードの何かが間違っていて、この致命的なエラーが発生する可能性があり、多くのデバッグと試行の後、コードを次のように単純化しました。

$connection = new Com('Something.SomethingClass');

変数 $connection は決して使用されません! それでも2回ごとにphp-crashが発生します(Windowsエラーログに1000-Errorと1001-Informationが記録されています)

>Faulting application name: php-cgi.exe, version: 5.4.11.0, time stamp: 0x511a30ec
>Faulting module name: KERNELBASE.dll, version: 6.1.7601.17932, time stamp: 0x503275ba
>Exception code: 0xc0000005
>Fault offset: 0x0000d3cf
>Faulting process id: 0x14d0
>Faulting application start time: 0x01ce89dd0ae23748
>Faulting application path: C:\Program Files\Zend\ZendServer\bin\php-cgi.exe
>Faulting module path: C:\Windows\system32\KERNELBASE.dll

だから私はさらに多くのcomオブジェクトを生成しようとしました..

$connArray = array();
for($i = 0; $i < 50 ; $i++){
  Core_System_Log::getInstance()->logWithoutMessageId('Before: ' . $i ,Core_System_Log::DEBUG);
  $connArray[i] = new Com('Something.SomethingClass');
  Core_System_Log::getInstance()->logWithoutMessageId('After: ' . $i, Core_System_Log::DEBUG);
}   

50 個すべてが問題なく生成され、2 回目の試行ごとに php の致命的なエラーが発生しました。50 個すべてを使用しようとしましたが、すべて問題なく PI システムから値を読み取りました。

変数の設定を解除してgcも呼び出し、C#からデストラクタを呼び出し、C#からコンストラクタをチェックしようとしました(ライブラリのオブジェクトを作成するだけで例外はありませんでした。オブジェクトは正常に作成され、それでもphpがクラッシュしました)が、問題消えませんでした。

それで、何か考えはありますか?私は何か間違ったことをしていますか(2回ごとに値を適切に読み取っているのに、どうして間違っているのでしょうか)?

テストされた環境:

  • OS:Windows Server 2008 R2 64Bit / Windows 7 Prof SP1 32/64Bit
  • PHP: 5.3.9/5.3.14/5.3.21/5.4.11
  • WS: Apache と IIS (いくつかの異なるバージョン)

更新: 問題は最終的に C# コードにありました。COM オブジェクトを正しく閉じたり削除したりできない GC への呼び出しがあり、その結果、C# がハングし (これも例外なく)、PHP の致命的なエラーが「トリガー」されました。

回答ありがとうございます。

4

2 に答える 2

0

ファイルにログインせずにリターンがクラッシュした場合、コードに sign が含まれているように見えます@

例:

@some_function()

これにより関数が呼び出されますが、エラーがある場合は表示されず、スキップされます。いくつかのエラーにより、PHP が停止する可能性があります。

しかし、Windows サーバーで PHP を 5.5 にアップグレードしてみてはいかがでしょうか?

コードのどの行でエラーがスローされるかがわかっていて、スキップしたい場合は、isset()

isset($somevar)orが true を返す場合isset(function())、それはエラーではないことを意味しますが、エラーで関数を停止したくない場合はisset()、エラーが発生したコード行に配置します。

コード内でクラスと関数がどのように見えるかがわからないので、PHP->Wrapper->Lib->PI-System完全に修正された答えを伝えることができます。

于 2013-07-26T12:27:57.647 に答える