1

構築中の CodeIgniter ベースのアプリケーションの一部に問題があります。

私はリモートサーバーに接続しなければならず、VB スクリプトで、ソケットを開き、XML データを送信し、応答を受信する方法について、サードパーティからかなり詳細な一連の指示を得る必要があります。これを以下の PHP コードに変換しました。現在、私のログによると、データはサーバーに書き込まれています (ログ出力は以下に示されています)。ただし、コードの fgets() 部分はタイムアウトしているようで、エラーなどはありません...デバッグがかなり難しくなります。

fsockopen()fgets( )について読んだことから、次のように動作するはずですが、明らかに動作しません。問題は、エラーメッセージなどが表示されないことです。デバッグ方法について少し迷っています。

私が明らかな間違いを犯したかどうかを確認するためだけに (または、私がやっていることはその点で正しいことを確認するために) 時間を割いていただける方がいらっしゃれば幸いです。

これがコードです(申し訳ありませんが、一部を空白にする必要がありました)。

public function makeBooking($orderId) {

    // get entire XML file as a string
    $xmlString = $this->getXmlString();

    // replace non-alphanumeric characters
    $xmlString = $this->replaceChars($xmlString);

    // get length of xml string
    $xmlStrCount = mb_strlen($xmlString) + 7;

    // attempt to open socket
    $fp = fsockopen('xxx.xx.xxx.xx', '81', $errno, $errstr, 10); 

    if (!$fp) {

        // couldn't open socket
        log_message('ERROR', "*** Couldn't open socket: $errno $errstr " . ' | line ' . __LINE__ . ' of ' . __FILE__);

    } else {

        log_message('DEBUG', "*** Socket open, connected to remote server ");

        $lf = chr(13).chr(10);

        // opened socket, prepare output
        $output = '"POST xxxxxxxxxxxx.asp HTTP/1.0"' . $lf;
        $output .= '"Accept: */*"' . $lf;                                            
        $output .= '"User-Agent: xxxxxxxxxxx_socket/1.0";' . $lf;
        $output .= '"Content-type: application/x-www-form-urlencoded";' . $lf;
        $output .= '"Content-length: ' . $xmlStrCount . '";' . $lf;
        $output .= '""' . $lf;
        $output .= '"xml_in='.$xmlString.'"';

        // attempt to write output
        $result = fwrite($fp, $output);
        log_message('DEBUG', "***  Bytes written: $result " . ' | line ' . __LINE__ . ' of ' . __FILE__);
        if($result) {
            log_message('DEBUG', "*** Wrote output:$lf$lf$output$lf");
        } else {
            log_message('ERROR', "*** Failed to write output:$lf$lf$output$lf");
        }


        // read data from server until no more responses are sent            
        // while (!feof($fp)) {
        if(!feof($fp)) {
            log_message('DEBUG',"*** Requesting line 1 from remote server" );
           //$line = fgets($fp);
            $line = fgets($fp);
            if($line) {
                log_message('DEBUG',"*** Retreived line 1: " . print_r($line,TRUE) );
            } else {
                log_message('ERROR',"*** Could not retreive line 1" );
            }
        }
        fclose($fp);
        log_message('DEBUG',"*** Closed connection to remote server" );
    }

}

ログ。明らかに、その多くは、関連する結果をどのように解釈したかです。URL エンコードされた XML データを切り捨てました。

    DEBUG - 2012-09-21 14:50:01 --> *** Socket open, connected to remote server 
DEBUG - 2012-09-21 14:50:01 --> ***  Bytes written: 8801  | line 57
DEBUG - 2012-09-21 14:50:01 --> *** Wrote output:

"POST xxxxxxxxxxxx.asp HTTP/1.0"
"Accept: */*"
"User-Agent: xxxxxxxxxxxxx_socket/1.0";
"Content-type: application/x-www-form-urlencoded";
"Content-length: 8630";
""
"xml_in=%26lt%3B%3Fxml+version%3D%26quot%3B1.0%26quot%3B..."
DEBUG - 2012-09-21 14:50:01 --> *** Requesting line 1 from remote server
ERROR - 2012-09-21 14:51:01 --> *** Could not retreive line 1
DEBUG - 2012-09-21 14:51:01 --> *** Closed connection to remote server

どこを見ればよいかについてのアイデアは大歓迎です。

- - - - - - - 編集 - - - - - - -

同様の問題で誰かがこのスレッドに出くわした場合に備えて、ロビーの提案に基づいて、私が最終的に行ったことは次のとおりです。

public function createBooking($orderId) {

    // http://php.net/manual/en/book.curl.php

    // get entire XML file as a string
    $xmlString = $this->getXmlString();

    // replace non-alphanumeric characters - can't use htmlentities or htmlspecialchars
    // because remote server uses different codes
    $xmlString = $this->replaceChars($xmlString);

    // get length of xml string
    $xmlStrCount = mb_strlen($xmlString) + 7;

    // prepare output
    $lf = chr(13).chr(10);
    $output = '"Accept: */*"' . $lf;                                            
    $output .= '"User-Agent: xxxxx_socket/1.0";' . $lf;
    $output .= '"Content-type: application/x-www-form-urlencoded";' . $lf;
    $output .= '"Content-length: ' . $xmlStrCount . '";' . $lf;
    $output .= '""' . $lf;
    $output .= '"xml_in='.$xmlString.'"';

    // set curl options
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,"http://xxxxx:xx/xxxxx.asp");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $output);
    // Request the header information in the response. 
    curl_setopt($ch,CURLOPT_HEADER,true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Now execute the query
    $response = curl_exec ($ch);
    if(!$response) {
        log_message('ERROR', "*** Curl error: " . curl_error($ch) . ' | line ' . __LINE__ . ' of ' . __FILE__);
        show_error(DEFAULT_ERR_MSG);
    }
    curl_close ($ch);



    // Response is the data. 
    $aLines = explode("\n", $response);  // Splits the resposne into an array so you can process individual lines.
    // etc

    print_r($aLines);

}
4

1 に答える 1

1

エラーは確かではありませんが、「if」ではなく必要です。while はwhile (!$feof($fp))、すべての応答を取得するまでループします。それでも問題は解決しないので...

curl を使用して実装すると、これがより簡単になる場合があります。はるかに短く、きれいで、デバッグも簡単です。http://php.net/manual/en/book.curl.php

<?php

$ch = curl_init();

// Set the various options. replace the xxxx's 
curl_setopt($ch, CURLOPT_URL,"xxxxxxxxxxxx.asp");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'xml_in=' . $xmlString);
curl_setopt($ch,CURLOPT_USERAGENT,'xxxxxxxxxxx_socket/1.0');

// Request the header information in the response. You're example gets the header, but you may not need it, so change to false if not
curl_setopt($ch,CURLOPT_HEADER,true);

// Now execute the query
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec ($ch);
curl_close ($ch);

// Response is the data. 
$aLines = explode("\n", $response);  // Splits the resposne into an array so you can process individual lines.
// etc

?>
于 2012-09-21T03:56:31.773 に答える