A. php使用CURL請求https的微信統一下單介面時報錯,同樣的代碼我在另一台機器上運行是正常的
我也遇到了同樣的問題,只要是走微信,偶爾都會請求不到,原來是正常的。今天排查了一天,終於找到了原因所在。
centos原生用的NSS,而不是OpenSSL,curl調用NSS庫請求https時偶爾會出現請求不到的情況。
解決方案:
參考網址:網頁鏈接
按步驟完成後記得重啟 php-fpm和nginx
B. php如何上傳圖片到遠程伺服器
可以使用curl這個擴展來實現。
PHP 支持的由Daniel Stenberg創建的libcurl庫允許你與各種的伺服器使用各種類型的協議進行連接和通訊。
libcurl支持http、https、ftp、gopher、telnet、dict、file和ldap協議。libcurl同時也支持HTTPS認證、HTTP POST、HTTP PUT、 FTP 上傳(這個也能通過PHP的FTP擴展完成)、HTTP 基於表單的上傳、代理、cookies和用戶名+密碼的認證。
curl_close() 關閉一個cURL會話。
curl__handle()復制一個cURL句柄和它的所有選項。
curl_errno()返回最後一次的錯誤號。
curl_error()返回一個保護當前會話最近一次錯誤的字元串。
curl_escape()返回轉義字元串,對給定的字元串進行URL編碼。
curl_exec()執行一個cURL會話。
curl_file_create()創建一個CURLFile對象。
curl_getinfo()獲取一個cURL連接資源句柄的信息。
curl_init()初始化一個cURL會話。
curl_multi_add_handle()向curl批處理會話中添加單獨的curl句柄。
curl_multi_close()關閉一組cURL句柄。
curl_multi_exec()運行當前cURL句柄的子連接
curl_multi_getcontent()如果設置了CURLOPT_RETURNTRANSFER,則返回獲取的輸出的文本流。
curl_multi_info_read()獲取當前解析的cURL的相關傳輸信息。
curl_multi_init()返回一個新cURL批處理句柄。
curl_multi_remove_handle()移除curl批處理句柄資源中的某個句柄資源。
curl_multi_select()等待所有cURL批處理中的活動連接。
curl_multi_setopt()設置一個批處理cURL傳輸選項。
curl_multi_strerror()返回描述錯誤碼的字元串文本。
curl_pause()暫停及恢復連接。
curl_reset()重置libcurl的會話句柄的所有選項。
curl_setopt_array()為cURL傳輸會話批量設置選項。
curl_setopt()設置一個cURL傳輸選項。
curl_share_close()關閉cURL共享句柄。
curl_share_init()初始化cURL共享句柄。
curl_share_setopt()設置一個共享句柄的cURL傳輸選項。
curl_strerror()返回錯誤代碼的字元串描述。
curl_unescape()解碼URL編碼後的字元串。
curl_version()獲取cURL版本信息。
C. PHP curl 模擬表單數據流multipart/form-data上傳文件
在調用公眾號介面https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=".$token."&type=".$type;
上傳永久素材文件總是返回 "{\"errcode\":41005,\"errmsg\":\"media data missing\"}"
經過多次測試使用下面的方式,可以正常上傳
//調用測試
protected static $url;
protected static $delimiter;
protected static $instance;
public function index()
{
static::$delimiter = uniqid();
$basename = Request::instance()->root();
if (pathinfo($basename, PATHINFO_EXTENSION) == 'php') {
$basename = dirname($basename);
}
$result=$this->wxAddMaterial($token,$basename.'/upload/images/gnlog.jpg','image');
}
// 新增其他類型永久素材
public function wxAddMaterial($token,$filename='',$type='') {
// 設置請求參數
static::$url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=".$token."&type=".$type;
$filePath = str_replace('\\', '/', $filename);
// 發送請求
$imginfo=pathinfo($filePath);
$fields = array(
'media'=>扒槐file_get_contents(".".$filePath),
'filename'=>$imginfo["basename"茄此嫌],
);
$res = $this->putPart( $fields);
// 發送請求
return $res;
}
//推送文件流
public function putPart($param) {
$post_data = static::buildData($param);
$curl = curl_init(static::$url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
"Content-Type: multipart/form-data; boundary=" . static::$delimiter,
"Content-Length: " . strlen($post_data)
]);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
//編譯請求頭格式和數據流
private static function buildData($param){
$data = '';
$eol = "\r\n";
$upload = $param['media'];
unset($param['media']);
foreach ($param as $name => $content) {
$data .= "--" . static::$delimiter . "\r\顫手n"
. 'Content-Disposition: form-data; name="' . $name . "\"\r\n\r\n"
. $content . "\r\n";
}
$data .= "--" . static::$delimiter . $eol
. 'Content-Disposition: form-data; name="media"; filename="' . $param['filename'] . '"' . "\r\n"
. 'Content-Type:application/octet-stream'."\r\n\r\n";
$data .= $upload . "\r\n";
$data .= "--" . static::$delimiter . "--\r\n";
return $data;
}
根據自己的實際情況稍作修改
D. 如何通過php的curl模擬ajax請求,獲取其返回值
這個需要配合js,打開一個html頁面,首先js用ajax請求頁面,返回第一個頁面信息確定處理完畢(ajax有強制同步功能),ajax再訪問第二個頁面。(或者根據伺服器狀況,你可以同時提交幾個URL,跑幾個相同的頁面)
參數可以由js產生並傳遞url,php後台頁面根據URL抓頁面。然後ajax通過php,在資料庫或者是哪裡設一個標量,標明檢測到哪裡。由於前台的html頁面執行多少時候都沒問題,這樣php的內存限制和執行時間限制就解決了。
因為不會浪費大量的資源用一個頁面來跑一個瞬間500次的for循環了。(你的500次for循環死了原因可能是獲取的數據太多,大過了php限制的內存)
不過印象中curl好像也有強制同步的選項,就是等待一個抓取後再執行下一步。但是這個500次都是用一個頁面線程處理,也就是說肯定會遠遠大於30秒的默認執行時間。
E. 對於https協議的網站,可以用php 的curl來模擬get請求和post請求嗎,能得到返回值嗎
可以。
CURLOPT_PROTOCOLS
CURLPROTO_* 的位域指。如果被啟用,位域值會限定libcurl在傳輸過程中有哪些可使用的協議。這將允許你在編譯libcurl時支持眾多協議,但是限制只是用它們中被允許使用的一個子集。默認libcurl將會使用全部它支持的協議。參見 CURLOPT_REDIR_PROTOCOLS .
可用的協議選項為:CURLPROTO_HTTP、CURLPROTO_HTTPS、CURLPROTO_FTP、CURLPROTO_FTPS、CURLPROTO_SCP、CURLPROTO_SFTP、CURLPROTO_TELNET、CURLPROTO_LDAP、CURLPROTO_LDAPS、CURLPROTO_DICT、CURLPROTO_FILE、CURLPROTO_TFTP、CURLPROTO_ALL
對了,可定能得到返回值