使用file_get_contents()发出的HTTP请求共享相同的会话数据


HTTP Requests made with file_get_contents() share the same session data?

我有一个问题…

我有一个类似mvc的框架,重定向机制允许我在远程主机上获得PHP生成的HTML代码片段。

我通过使用file_get_contents()函数获得这些片段,并打开allow_url_fopen。

问题是我在这些代码片段中使用会话数据,并且每次会话数据都会丢失。我假设这个新请求不共享相同的会话数据,因此我需要一种方法来获得这些片段而不丢失我的会话数据。

有什么建议吗?

如果您访问的文件与调用文件在同一服务器上,那么您不妨使用include();,如@user574632的答案

但是如果没有,为了保持会话,你需要处理服务器发送的cookie;

会话是基于cookie的,服务器设置会话cookie,浏览器拾取它并将其用于所有后续请求。

默认情况下,file_get_contents不会处理cookie,所以你需要通过访问$http_response_header数组从服务器抓取头,然后与regex匹配Set-Cookie:头,然后存储,并在以下请求中使用cookie并创建一个流上下文,将cookie添加到头中,并将其传递给fgc:

<?php 
function get_cookies() {
    //check cookies folder - or make it
    if(!file_exists('./cookies/')){
        mkdir('./cookies/', 0755, true);
    }
    $return = null;
    foreach(glob("./cookies/*.txt") as $file) {
        $return .= file_get_contents($file).';';
    }
    return $return;
}
function save_cookies($http_response_header) {
    print_r($http_response_header);
    foreach($http_response_header as $header) {
        if(substr($header, 0, 10) == 'Set-Cookie'){
            if(preg_match('@Set-Cookie: (([^=]+)=[^;]+)@i', $header, $matches)) {
                $fp = fopen('./cookies/'.$matches[2].'.txt', 'w');
                fwrite($fp, $matches[1]);
                fclose($fp);
            }
        }
    }
}
$opts = array('http' =>
    array('header'=>'Cookie: '.get_cookies()."'r'n")
);
$context  = stream_context_create($opts);
$contents = file_get_contents('http://mywebsite.com/snippets/', false, $context);
save_cookies($http_response_header);
echo $contents;
?> 

或者你应该使用curl,它更快,处理cookie也很好。

就像下面这样,使用curl,如果curl不存在,则返回到fgc,所有这些都用cookie支持包装在一个类中,因此包含了3个函数:

<?php
//example usage
echo new curl_get_contents('http://example.com/page_that_needs_sessions');
class curl_get_contents{
    public $result;
    function __construct($url){
        $this->curl_rev_fgc($url);
    }
    function __toString(){
        return $this->result;
    }
    private function get_cookies() {
        $return = null;
        foreach(glob("./cookies/*.txt") as $file) {
            $return .= file_get_contents($file).';';
        }
        return $return;
    }
    private function save_cookies($http_response_header) {
        foreach($http_response_header as $header) {
            if(substr($header, 0, 10) == 'Set-Cookie'){
                if(preg_match('@Set-Cookie: (([^=]+)=[^;]+)@i', $header, $matches)) {
                    $fp = fopen('./'.$matches[2].'.txt', 'w');
                    fwrite($fp, $matches[1]);
                    fclose($fp);
                }
            }
        }
    }
    private function curl_rev_fgc($url){
        //check cookies folder - or make it
        if(!file_exists('./cookies')){
            mkdir('./cookies/', 0755, true);
        }
        $usragent = 'Mozilla/5.0 (compatible; Yourbot/0.1; +https://yoursite/bot.html)';
        //Check curl is installed or revert to file_get_contents()
        $curl = function_exists('curl_init') ? true : false;
        if($curl){
            $opts = array(
            'http' => array(
            'method' => "GET",
            'header' => 'Cookie: '.$this->get_cookies().''r'n', // cookie in fgc support
            'user_agent' => $usragent)
            );
            $context = stream_context_create($opts);
            $result  = @file_get_contents($url, false, $context);
            $this->save_cookies($http_response_header);
            if(empty($result)){
                $this->result = 'Error fetching: '.htmlentities($url);
            }else{
                $this->result = $result;
            }
            return;
        }
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
        curl_setopt($curl, CURLOPT_USERAGENT, $usragent);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        if(!file_exists('./cookies/curl.txt')){
            file_put_contents('./cookies/curl.txt',null);
        }
        curl_setopt($curl, CURLOPT_COOKIEFILE, './cookies/curl.txt');
        curl_setopt($curl, CURLOPT_COOKIEJAR,  './cookies/curl.txt');
        $result = curl_exec($curl);
        if(empty($result)){
            $this->result = 'Error fetching: '.htmlentities($url);
        }else{
            $this->result = $result;
        }
        curl_close($curl);
        return;
    }
}
?>

使用include代替。如果您需要将输出读入一个变量以便稍后/在代码的其他地方显示,如注释中建议的那样,请使用输出缓冲区:

ob_start();
include('path/to/file.php');
$included = ob_get_clean();
//nothing has been output to the browser yet
//later on
echo $included;