2014-02-24 68 views
0

我正在尝试开发一个可以处理cookie的完整PHP网页浏览器。我创建了以下类:file_get_contents获取Cookies

<?php 

class Browser 
{ 
    private $cookies = ''; 
    private $response_cookies = ''; 
    private $content = ''; 

    /** 
    * Cookie manager 
    * @Description : To set or get cookies as Array or String 
    */ 
    public function set_cookies_json($cookies) 
    { 
    $cookies_json = json_decode($cookies, true); 
    $cookies_array = array(); 
    foreach ($cookies_json as $key => $value) 
    { 
     $cookies_array[] = $key .'='.$value; 
    } 
    $this->cookies = 'Cookie: ' . $cookies_array.join('; ') . "\r\n"; 
    } 

    public function set_cookies_string($cookies) 
    { 
    $this->cookies = 'Cookie: ' . $cookies . "\r\n"; 
    } 

    private function get_cookies() 
    { 
    global $http_response_header; 
    $cookies_array = array(); 
    foreach($http_response_header as $s) 
    { 
     if (preg_match('|^Set-Cookie:\s*([^=]+)=([^;]+);(.+)$|', $s, $parts)) 
     { 
     $cookies_array[] = $parts[1] . '=' . $parts[2]; 
     } 
    } 

    $this->cookies = 'Cookie: ' . $cookies_array.join('; ') . "\r\n"; 
    } 

    /** 
    * GET and POST request 
    * Send a GET or a POST request to a remote URL 
    */ 
    public function get($url) 
    { 
    $opts = array(
     'http' => array(
     'method' => 'GET', 
     'header' => "Accept-language: en\r\n" . 
        $this->cookies 
    ) 
    ); 
    $context = stream_context_create($opts); 
    $this->content = file_get_contents($url, false, $context); 
    $this->get_cookies(); 
    return $this->content; 
    } 

    public function post($url, $post_data) 
    { 
    $post_content = array(); 
    foreach ($post_data as $key => $value) 
    { 
     $post_content[] = $key .'='.$value; 
    } 

    $opts = array(
     'http' => array(
     'method' => 'GET', 
     'header' => "Content-type: application/x-www-form-urlencoded\r\n" . 
        $this->cookies, 
     'content' => $post_content.join('&'), 
    ) 
    ); 
    $context = stream_context_create($opts); 
    $this->content = file_get_contents($url, false, $context); 
    $this->get_cookies(); 
    return $this->content; 
    } 
} 

基本上,它可以发送GET请求并'应'检索cookie。 我做了一个非常简单的测试脚本:

<?php 

require('browser.class.php'); 

$browser = new Browser(); 
$browser->get('http://google.com'); 
print_r($browser->response_cookies); 

但它在线路出现故障时32$http_response_header看起来是空。它是不是应该包含我的回应的标题?我已阅读该页面,但它看起来很适合这个人:get cookie with file_get_contents in PHP

我知道我可以使用cUrl来处理这个,但我真的很喜欢使用粗略的PHP代码。

我做错了什么?

感谢您的宝贵帮助。

编辑:

解决办法是:

<?php 

class Browser 
{ 
    public $request_cookies = ''; 
    public $response_cookies = ''; 
    public $content = ''; 

    /** 
    * Cookie manager 
    * @Description : To set or get cookies as Array or String 
    */ 
    public function set_cookies_json($cookies) 
    { 
    $cookies_json = json_decode($cookies, true); 
    $cookies_array = array(); 
    foreach ($cookies_json as $key => $value) 
    { 
     $cookies_array[] = $key .'='.$value; 
    } 
    $this->request_cookies = 'Cookie: ' . join('; ', $cookies_array) . "\r\n"; 
    } 

    public function set_cookies_string($cookies) 
    { 
    $this->request_cookies = 'Cookie: ' . $cookies . "\r\n"; 
    } 

    private function get_cookies($http_response_header) 
    { 
    $cookies_array = array(); 
    foreach($http_response_header as $s) 
    { 
     if (preg_match('|^Set-Cookie:\s*([^=]+)=([^;]+);(.+)$|', $s, $parts)) 
     { 
     $cookies_array[] = $parts[1] . '=' . $parts[2]; 
     } 
    } 

    $this->response_cookies = 'Cookie: ' . join('; ', $cookies_array) . "\r\n"; 
    } 

    /** 
    * GET and POST request 
    * Send a GET or a POST request to a remote URL 
    */ 
    public function get($url) 
    { 
    $opts = array(
     'http' => array(
     'method' => 'GET', 
     'header' => "Accept-language: en\r\n" . 
        $this->request_cookies 
    ) 
    ); 
    $context = stream_context_create($opts); 
    $this->content = file_get_contents($url, false, $context); 
    $this->get_cookies($http_response_header); 
    return $this->content; 
    } 

    public function post($url, $post_data) 
    { 
    $post_content = array(); 
    foreach ($post_data as $key => $value) 
    { 
     $post_content[] = $key .'='.$value; 
    } 

    $opts = array(
     'http' => array(
     'method' => 'GET', 
     'header' => "Content-type: application/x-www-form-urlencoded\r\n" . 
        $this->request_cookies, 
     'content' => join('&', $post_content), 
    ) 
    ); 
    $context = stream_context_create($opts); 
    $this->content = file_get_contents($url, false, $context); 
    $this->get_cookies($http_response_header); 
    return $this->content; 
    } 
} 

回答

3

据php.net:

$ http_response_header会在局部范围内创建。

因此$http_response_header仅在get()范围内可用。 您可以像$this->get_cookies($http_response_header);那样传递它或创建一个属性来存储它。

+0

感谢它完美的作品。我会用答案更新我的问题。 – Manitoba

+0

太棒了!我很高兴它帮助;) – wesolyromek