لماذا يواجه fsockopen مشاكل في الأداء ولا يتم فتحه عند إرسال طلب POST في PHP؟

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() لا يعود صحيحًا حتى تنتهي مهلة الطلب.للالتفاف على هذا إرسال Connection: close head أو استخدم HTTP 1.0 الذي لا يدعم الاتصالات المستمرة.

نصائح أخرى

هل يعرف أي شخص لماذا سيكون لدى Fsockopen مشاكل الأداء هذه؟هل لها علاقة بإعداد المهلة؟

لقد واجهت مشاكل في الماضي مع fsockopen عبر SSL - ولكن هذا ليس ما تطلبه.

هل حاولت استخدام مجموعة وظائف curl_* بدلاً من ذلك، فقد يساعدك ذلك؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top