参考: http://techzinger.blogspot.com/2007/07/writing-reverse-proxy-in-php5.html
例如我想执行的是B url,但是显示的是A url,这样就需要进行反向代理
以下是根据上文参考改良而成,传入pdf参数
<?php
namespace App\Helper\ReverseProxy;
class ProxyHandler
{
private $url;
private $curl_handler;
private $proxy_url;
public function begin($url, $proxy_url, $pdf)
{
logger('start ProxyHandler');
$this->url = $url;
$this->proxy_url = $proxy_url;
// Parse all the parameters for the URL
if (isset($_SERVER['PATH_INFO'])) {
$proxy_url .= $_SERVER['PATH_INFO'];
} else {
$proxy_url .= '/';
}
if ($_SERVER['QUERY_STRING'] !== '') {
$proxy_url .= "?{$_SERVER['QUERY_STRING']}";
}
$translated_url = $proxy_url. $pdf;
$this->curl_handler = curl_init($translated_url);
logger('translated_url: '. $translated_url);
logger('curl_handler: '. $this->curl_handler);
// Set various options
$this->setCurlOption(CURLOPT_RETURNTRANSFER, true);
$this->setCurlOption(CURLOPT_BINARYTRANSFER, true); // For images, etc.
$this->setCurlOption(CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
$this->setCurlOption(CURLOPT_WRITEFUNCTION, array($this,'readResponse'));
$this->setCurlOption(CURLOPT_HEADERFUNCTION, array($this,'readHeaders'));
// Process post data.
if (count($_POST)) {
logger('in post method');
// Empty the post data
$post=array();
// Set the post data
$this->setCurlOption(CURLOPT_POST, true);
// Encode and form the post data
foreach ($_POST as $key => $value) {
$post[] = urlencode($key)."=".urlencode($value);
}
$this->setCurlOption(CURLOPT_POSTFIELDS, implode('&', $post));
unset($post);
} elseif ($_SERVER['REQUEST_METHOD'] !== 'GET') { // Default request method is 'get'
logger('in get method');
// Set the request method
$this->setCurlOption(CURLOPT_CUSTOMREQUEST, $_SERVER['REQUEST_METHOD']);
}
}
// Executes the proxy.
public function execute()
{
logger('start to execute');
curl_exec($this->curl_handler);
}
// Get the information about the request.
// Should not be called before exec.
public function getCurlInfo()
{
return curl_getinfo($this->curl_handler);
}
// Sets a curl option.
public function setCurlOption($option, $value)
{
curl_setopt($this->curl_handler, $option, $value);
}
protected function readHeaders(&$cu, $string): int
{
$length = strlen($string);
if (preg_match(',^Location:,', $string)) {
$string = str_replace($this->proxy_url, $this->url, $string);
}
header($string);
return $length;
}
protected function readResponse(&$cu, $string): int
{
$length = strlen($string);
echo $string;
return $length;
}
}
把以上代码复制进去项目,然后通过以下执行
class ReverseProxyController extends Controller
{
/**
* @var ProxyHandler
*/
private $proxy;
/**
* ReverseProxyController constructor.
* @param ProxyHandler $proxy
*/
public function __construct(ProxyHandler $proxy)
{
$this->proxy = $proxy;
}
public function uploadPdf(Request $request, $pdf)
{
$uploadUrl = config('app.reverse_proxy');
$nativeUrl = config('app.url').'/upload/public/doc/' . $pdf;
$this->proxy->begin($nativeUrl, $uploadUrl, $pdf);
$this->proxy->execute();
}