1、 fsockopen
/** * 異步 執行程序 * @param string $path 異步url 地址 * @param array $postData 傳遞的參數 * @param string $method 請求方式 * @param string $url 請求地址 * @return bool */ function request_asynchronous($path, $method = "POST", $postData = array(), $url = ''){ if(empty($path)){ return false; } if($url) { $matches = parse_url($url); $host = $matches['host']; //$path = $matches['path'] ? $matches['path'] . ($matches['query'] ? '?' . $matches['query'] : '') : '/'; if ($matches['scheme'] == 'https') { //判斷是否使用HTTPS $transports = 'ssl://'; //如使用HTTPS則使用SSL協議 $port = !empty($matches['port']) ? $matches['port'] : 443; //如使用HTTPS端口使用443 } else { $transports = 'tcp://'; //如沒有使用HTTPS則使用tcp協議 $port = !empty($matches['port']) ? $matches['port'] : 80;//如沒有使用HTTPS則使用80端口 } }else{ $port = 443; $transports = 'ssl://'; $host = $_SERVER['HTTP_HOST']; } $errNo = 0; $errStr = ''; $timeout = 60; $fp = ''; if(function_exists('fsockopen')) { $fp = @fsockopen(($transports . $host), $port, $errno, $errStr, $timeout); } elseif(function_exists('pfsockopen')) { $fp = @pfsockopen($transports.$host, $port, $errNo, $errStr, $timeout); } elseif(function_exists('stream_socket_client')) { $fp = @stream_socket_client($transports.$host.':'.$port, $errNo, $errStr, $timeout); } if (!$fp) { return false; } stream_set_blocking($fp, 0); //開啟非阻塞模式 stream_set_timeout($fp, 3); //設置超時時間(s) $date = []; if($postData) { //處理文件 foreach ($postData as $key => $value) { if(is_array($value)){ $date[$key] = serialize($value); }else{ $date[$key] = $value; } } } if ($method == "GET") { $query = $date ? http_build_query($date) : ''; $path .= "?".$query; }else{ $query = json_encode($date); } $cookie = "token={$_COOKIE['token']}; session={$_COOKIE['session']}"; //http消息頭 $out = $method." ".$path." HTTP/1.1\r\n"; $out .= "HOST: ".$host."\r\n"; if ($method == "POST") { $out .= "Content-Length:".strlen($query)."\r\n"; } $out .= "Accept: application/json, text/plain, */*\r\n"; $out .= "Access-Control-Allow-Credentials: true\r\n"; $out .= "Content-Type: application/x-www-form-urlencoded\r\n"; $out .= "Cookie: ".$cookie."\r\n"; $out .= "Connection: Close\r\n\r\n"; if ($method == "POST") { $out .= $query; } fputs($fp, $out); usleep(500); //忽略執行結果 /*while (!feof($fp)) { echo fgets($fp, 128); }*/ fclose($fp); return true; }
2、CURL
/** * 發送https/http請求 正常/異步 * @param string $url 請求地址 * @param array $params http請求數據, 數據類型必須是Array * @param string $method http方法(GET POST PUT DELETE) * @param array $header http請求頭 * @param int $type 請求類型 0正常,1異步 * @return string|bool */ function request_curl($url, $params = [], $method = "POST", $header = [], $type = 0) { //檢查地址是否為空 if (empty($url)) { return false; } //控制請求方法范圍 $httpMethod = array('GET', 'POST', 'PUT', 'DELETE'); $method = strtoupper($method); if (!in_array($method, $httpMethod)) { return false; } //請求頭初始化 $request_headers = array(); $User_Agent = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31'; $request_headers[] = 'User-Agent: '. $User_Agent; if($header){ foreach ($header as $v) { $request_headers[] = $v; } } $request_headers[] = 'Accept: text/html,application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; switch ($method) { case "POST": $request_headers[] = "X-HTTP-Method-Override: POST"; break; case "PUT": $request_headers[] = "X-HTTP-Method-Override: PUT"; break; case "DELETE": $request_headers[] = "X-HTTP-Method-Override: DELETE"; break; default: } //格式化發送數據 if($params) { if($method == 'GET'){ //GET請求 $url = $url . '?' . http_build_query($params); }else{ if (!$type){ $params = json_encode($params,JSON_UNESCAPED_UNICODE); } } } //發送http請求 $ch = curl_init(); if($type) { curl_setopt($ch, CURLOPT_TIMEOUT, 1);//設置超時時間為1秒,超過1秒則關閉連接 #curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //注意,毫秒超時一定要設置這個 #curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); //超時毫秒,cURL 7.16.2中被加入。從PHP 5.2.3起可使用 }else{ curl_setopt($ch, CURLOPT_TIMEOUT, 1500); // 最大執行時間 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1500); // 在嘗試連接時等待的秒數 } curl_setopt($ch, CURLOPT_URL, $url); // 要訪問的地址 curl_setopt($ch, CURLOPT_HEADER, 0);// 設置是否顯示返回頭信息 1返回 0不返回 curl_setopt($ch, CURLOPT_NOBODY, 0); //不想在輸出中包含body部分,設置這個選項為一個非零值 curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自動設置Referer curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//獲取的信息以文件流的形式返回 curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//https 不進行ssl驗證 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);//設置頭信息 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); //設置請求方式 if($method != 'GET'){ if($method != 'POST'){ curl_setopt($ch, CURLOPT_POSTFIELDS, $params); } curl_setopt($ch, CURLOPT_POSTFIELDS, $params); } //發送請求獲取返回響應 $result['data'] = curl_exec($ch); $result['httpCode'] = curl_getinfo($ch,CURLINFO_HTTP_CODE); if(strlen(curl_error($ch))>1){ $result = false; } curl_close($ch); //var_dump($result); return $result; }
原文鏈接:https://blog.csdn.net/u011477914/article/details/105989536/
注:測試發現 fsockopen 請求執行https時,有兩個亂碼總是:
1,返回頭中 Content-Encoding: gzip 表示body是gzip壓縮格式的,body需要gzdecode(body)解壓
2,返回頭中 Transfer-Encoding: chunked 分塊傳輸編碼