使用curl封装一个实现后端get和post请求的函数
实现post请求
在《https网页请求http的接口》这篇文章中,我总结了一个curl封装get请求的方法,因为使用的频率比较高,今天再特意单独整理一份。
/**
* 发起http post请求(REST API), 并获取REST请求的结果
* @param string $url
* @param string $param
* @return - http response body if succeeds, else false.
*/
function request_post($url = '', $param = '')
{
if (empty($url) || empty($param)) {
return false;
}
$postUrl = $url;
$curlPost = $param;
// 初始化curl
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $postUrl);
curl_setopt($curl, CURLOPT_HEADER, 0);
// 要求结果为字符串且输出到屏幕上
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
// post提交方式
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
// 运行curl
$data = curl_exec($curl);
curl_close($curl);
return $data;
}
以下是一个使用的例子:
$url = 'https://aip.baidubce.com/oauth/2.0/token';
$post_data['grant_type'] = 'client_credentials';
$post_data['client_id'] = 'apikey123455';
$post_data['client_secret'] = 'secretkey54321';
$o = "";
foreach ( $post_data as $k => $v ) {
$o.= "$k=" . urlencode( $v ). "&" ;
}
// 返回字符串的子串
$post_data = substr($o, 0, -1);
/*
最后返回的字符串是:
grant_type=client_credentials&client_id=apikey123455&client_secret=secretkey54321
*/
$res = request_post($url, $post_data);
// 如果请求成功 那么返回的可能是一个json格式,则将其转为php数组
$res = json_decode($res, JSON_UNESCAPED_UNICODE);
substr,返回字符串string
由offset
和length
参数指定的子字符串。具体语法看文档吧。substr
同样实现方法,做个备份:
<?php
class Curl
{
public function post($url = '', $param = '')
{
if (empty($url) || empty($param)) {
return false;
}
$postUrl = $url;
$curlPost = $param;
$curl = curl_init();//初始化curl
curl_setopt($curl, CURLOPT_URL,$postUrl);//抓取指定网页
curl_setopt($curl, CURLOPT_HEADER, 0);//设置header
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
curl_setopt($curl, CURLOPT_POST, 1);//post提交方式
curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec($curl);//运行curl
if ($error = curl_error($curl)) {
die($error);
}
curl_close($curl);
return $data;
}
}
实现get请求
第一个为非项目应用版,如果应用在项目中,请参考第二段代码。
function request_get($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
curl_setopt($curl, CURLOPT_URL, $url);
// 请求的是https需要加上下面2句 不验证ssl证书
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$res = curl_exec($curl);
if (!$res) {
echo 'Curl error: ' . curl_error($curl);
exit();
}
curl_close($curl);
return $res;
}
相比较而言,get请求就简单多了。下面是一个应用:
$apiKey = '12345';
$url = "https://app.verify-email.org/api/v1/{$apiKey}/verify/wubin-work@qq.com";
$res = request_get($url);
实际应用的时候,应该修改如果get失败的情况,只是简单的返回false即可:
function _request_get($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
curl_setopt($curl, CURLOPT_URL, $url);
// 请求的是https需要加上下面2句 不验证ssl证书
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$res = curl_exec($curl);
// 如果请求失败
if (!$res) {
return false;
}
curl_close($curl);
return $res;
}
针对get实现一个可以通过外部传参的get函数
function request_get($url, $options = []) {
$curl = curl_init();
// 基础设置
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, isset($options['timeout']) ? $options['timeout'] : 500); // 默认超时500秒
curl_setopt($curl, CURLOPT_URL, $url);
// 如果请求的是HTTPS并且需要忽略SSL验证
if (parse_url($url, PHP_URL_SCHEME) === 'https') {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, isset($options['ssl_verifypeer']) ? $options['ssl_verifypeer'] : false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, isset($options['ssl_verifyhost']) ? $options['ssl_verifyhost'] : false);
}
// 支持自定义HTTP头信息
if (isset($options['headers'])) {
curl_setopt($curl, CURLOPT_HTTPHEADER, $options['headers']);
}
// 支持GET参数(如果未在URL中直接包含)
if (isset($options['query'])) {
$parsedUrl = parse_url($url);
$parsedUrl['query'] = http_build_query(array_merge(
isset($parsedUrl['query']) ? parse_str($parsedUrl['query'], $query) : [],
$options['query']
));
$url = http_build_url($parsedUrl); // 注意:http_build_url() 不是一个PHP内置函数,需要自定义或使用第三方库
}
// 注意:如果需要处理POST数据,则应该使用 CURLOPT_POST 和 CURLOPT_POSTFIELDS,这里只处理GET请求
$res = curl_exec($curl);
// 错误处理
if (!$res) {
$error_msg = curl_error($curl);
curl_close($curl);
// 可以选择抛出异常或返回错误信息
throw new Exception("cURL Error: " . $error_msg);
// return false; // 或者返回false
}
curl_close($curl);
return $res;
}
// 注意:http_build_url() 函数不是PHP内置的,这里提供一个简单的实现
function http_build_url(array $parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = $parsed_url['host'] ?? '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$user = $parsed_url['user'] ?? '';
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : '';
$path = $parsed_url['path'] ?? '';
$query = isset($parsed_url['query']) ? '?'.$parsed_url['query'] : '';
$fragment = isset($parsed_url['fragment']) ? '#'.$parsed_url['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment";
}
使用示例:
$url = "https://example.com/api";
$options = [
'timeout' => 30, // 设置超时时间为30秒
'ssl_verifypeer' => true, // 启用SSL证书验证(生产环境中推荐启用)
'ssl_verifyhost' => 2, // 验证主机名(2表示检查存在且匹配)
'headers' => [
'Accept: application/json',
'Authorization: Bearer YOUR_ACCESS_TOKEN'
],
'query' => [
'param1' => 'value1',
'param2' => 'value2'
]
];
try {
$response = request_get($url, $options);
echo $response;
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
注意事项
SSL验证:在生产环境中,不建议禁用SSL验证(
CURLOPT_SSL_VERIFYPEER
和CURLOPT_SSL_VERIFYHOST
)。如果确实需要忽略SSL证书错误,请确保你了解可能的安全风险。