Fsockopen이 PHP에서 게시물 요청을 보낼 때 성능 문제가 있고 Fopen이없는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1930074

문제

양식 게시를 시뮬레이션하기 위해 두 가지 다른 구현을 시도했습니다. 하나의 용도 fsockopen (예 : 여기 : http://www.faqts.com/knowledge_base/view.phtml/aid/7962)) 그리고 다른 용도 fopen (예 : 여기 : http://netevil.org/blog/2006/nov/http-post-from-php-without-curl).

나는 심각한 성능 문제에 부딪쳤다 fsockopen - 디버거를 사용하면 모든 것이 잘 작동하는 것처럼 보이지만 디버거를 첨부하지 않으면 페이지가로드하는 데 시간이 걸립니다 (아마도 10 초 이상). fopen 완벽하게 작동합니다 (또한 응답 헤더를 구문 분석 할 필요가 없습니다). 그 이유를 아는 사람이 있습니까? fsockopen 이러한 성능 문제가 있습니까? 시간 초과 설정과 관련이 있습니까?

아래에 코드를 포함 시켰습니다.


//fsockopen implementation
/**
 * The class that posts form data to a specified URL.
 * @package Core
 * @subpackage Classes
 */
class SU_form_poster_class
{
    /**
     * The file handle which is created when a form is posted.
     * @var resource
     */
    protected $file_handle;

    protected $port;

    protected $timeout;


    /**
     * Creates a new instance of this class.
     * @param int $timeout the timeout (in seconds) to wait for the request
     * @param int $port the port to make the request on
     */
    public function __construct($timeout = 30, $port = 80)
    {
        $this->timeout = $timeout;
        $this->port = $port;
    }

    /**
     * Sends a POST request to a specified page on a specified host with the
     * specified data.
     * @param string $path the part of the URL that specifies the page (including
     * the query string)
     * @param string $host the host part of the URL to post to
     * @param string $request_data the data to be posted in "query string" format,
     * e.g. name1=value1&name2=value2&name3=value3
     */
    public function do_post($path, $host, $request_data)
    {
        $err_num = 0;
        $err_str = '';
        $this->file_handle = fsockopen($host, $this->port, $err_num, $err_str, $this->timeout);
        if (!$this->file_handle)
        {
            throw new RuntimeException($err_str, $err_num);
        }
        else
        {
            $request = 'POST '.$path." HTTP/1.1\r\n".
                'Host: '.$host."\r\n".
                "Content-type: application/x-www-form-urlencoded\r\n".
                'Content-length: '.strlen($request_data)."\r\n\r\n".
                $request_data;

            fputs($this->file_handle, $request);
        }
    }

    /**
     * Retrieves data from the most recent request.
     * @return string the response
     */
    public function get_last_response()
    {
        if (!$this->file_handle)
        {
            throw new RuntimeException('A valid request must be made first.');
        }
        else
        {
            $response = '';
            $linenum = 0;
            while (!feof($this->file_handle))
            {
                $line = fgets($this->file_handle, 1024);
                if ($linenum > 6)
                {
                    $response .= $line;
                }
                ++$linenum;
            }
            fclose($this->file_handle);
            return $response;
        }
    }
}


/**
 * The class that posts form data to a specified URL.
 * @package Core
 * @subpackage Classes
 */
class SU_form_poster_class
{
    /**
     * The file handle which is created when a form is posted.
     * @var resource
     */
    protected $stream;

    /**
     * Sends a POST request to a specified page on a specified host with the
     * specified data.
     * @param string $url
     * @param string $request_data the data to be posted in "query string" format,
     * e.g. name1=value1&name2=value2&name3=value3
     */
    public function do_post($url, $request_data)
    {
        $params = array(
            'http' => array(
                'method' => 'POST', 'content' => $request_data
            )
        );

        $context = stream_context_create($params);
        $this->stream = fopen($url, 'rb', false, $context);
        if (!$this->stream)
        {
            throw new RuntimeException('Stream was not created correctly');
        }
    }

    /**
     * Retrieves data from the most recent request.
     * @return string the response
     */
    public function get_last_response()
    {
        if (!$this->stream)
        {
            throw new RuntimeException('A valid request must be made first.');
        }
        else
        {
            return stream_get_contents($this->stream);
        }
    }
}

도움이 되었습니까?

해결책

HTTP 1.1 연결 기본값은 영구적입니다. 이것은 연결이 자동으로 닫히지 않고 feof() 요청 시간이 끝날 때까지 TRUE를 반환하지 않습니다. 이 주위를 돌려주기 위해 Connection: close 영구 연결을 지원하지 않는 헤더 또는 HTTP 1.0을 사용하십시오.

다른 팁

Fsockopen이 왜 이러한 성능 문제가 발생했는지 아는 사람이 있습니까? 시간 초과 설정과 관련이 있습니까?

나는 과거에 SSL에 대한 fsockopen에 문제가 있었지만 그것은 당신의 묻는 것이 아닙니다.

Curl_* 기능 제품군을 대신 사용해 보셨습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top