我尝试了两种不同的实现来模拟 POST 表单。一种用途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);
}
}
}