1 Star 0 Fork 4

zkg/PHP class fetch_url

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
fetch_url.c 30.26 KB
一键复制 编辑 原始数据 按行查看 历史
上帝禁区 提交于 2013-06-17 23:30 +08:00 . 乱码修复
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2012 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "main/SAPI.h"
#include "Zend/zend_interfaces.h"
#include "ext/standard/info.h"
#include "ext/standard/php_var.h"
#include "ext/standard/php_string.h"
#include "ext/standard/php_smart_str.h"
#include "ext/standard/url.h"
#include "ext/pcre/php_pcre.h"
#include "php_fetch_url.h"
#include <curl/curl.h>
zend_class_entry *g_fetch_ce;
ZEND_BEGIN_ARG_INFO_EX(void_arginfo, 0, 0, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(fetch_arginfo, 0, 0, 1)
ZEND_ARG_INFO(0, url)
ZEND_ARG_INFO(0, callback)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(responseCookies_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, all)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(responseHeaders_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, parse)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setAllowRedirect_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, allow)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setConnectTimeout_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, ms)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setCookie_arginfo, 0, 0, 2)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setCookies_arginfo, 0, 0, 1)
ZEND_ARG_INFO(0, cookies)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setHeader_arginfo, 0, 0, 2)
ZEND_ARG_INFO(0, name)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setMethod_arginfo, 0, 0, 1)
ZEND_ARG_INFO(0, method)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setPostData, 0, 0, 1)
ZEND_ARG_INFO(0, post_data)
ZEND_ARG_INFO(0, multil)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setReadTimeout_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, ms)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setBinary_arginfo, 0, 0, 3)
ZEND_ARG_INFO(0, post_filed)
ZEND_ARG_INFO(0, uploadfile_name)
ZEND_ARG_INFO(0, url)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(setFile_arginfo, 0, 0, 2)
ZEND_ARG_INFO(0, post_filed)
ZEND_ARG_INFO(0, path)
ZEND_END_ARG_INFO()
ZEND_METHOD(fetch_url, __construct){
}
ZEND_METHOD(fetch_url, setBinary){
zval *input_filed_name, *binary_data, *uploadfile_name;
zval *g_binary_data, *item_data;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &input_filed_name, &uploadfile_name, &binary_data) == FAILURE){
RETURN_FALSE;
}
if(Z_TYPE_P(input_filed_name) != IS_STRING || Z_TYPE_P(uploadfile_name) != IS_STRING || Z_TYPE_P(binary_data) != IS_STRING){
RETURN_FALSE;
}
g_binary_data = zend_read_property(FETCH_THIS, ZEND_STRL("binary_data"), 0 TSRMLS_CC);
if(Z_TYPE_P(g_binary_data) == IS_NULL){
MAKE_STD_ZVAL(g_binary_data);
array_init(g_binary_data);
}
MAKE_STD_ZVAL(item_data);
array_init(item_data);
add_index_stringl(item_data, 0, Z_STRVAL_P(uploadfile_name), Z_STRLEN_P(uploadfile_name), 1);
add_index_stringl(item_data, 1, Z_STRVAL_P(binary_data), Z_STRLEN_P(binary_data), 1);
add_assoc_zval(g_binary_data, Z_STRVAL_P(input_filed_name), item_data);
zend_update_property(FETCH_THIS, ZEND_STRL("binary_data"), g_binary_data TSRMLS_CC);
}
ZEND_METHOD(fetch_url, setFile){
zval *file_path, *input_filed_name;
zval *upload_filepaths;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &input_filed_name, &file_path) == FAILURE){
RETURN_FALSE;
}
if(Z_TYPE_P(file_path) != IS_STRING || Z_TYPE_P(input_filed_name) != IS_STRING){
RETURN_FALSE;
}
upload_filepaths = zend_read_property(FETCH_THIS, ZEND_STRL("upload_filepaths"), 0 TSRMLS_CC);
if(Z_TYPE_P(upload_filepaths) == IS_NULL){
MAKE_STD_ZVAL(upload_filepaths);
array_init(upload_filepaths);
}
add_assoc_stringl(upload_filepaths, Z_STRVAL_P(input_filed_name), Z_STRVAL_P(file_path), Z_STRLEN_P(file_path), 1);
zend_update_property(FETCH_THIS, ZEND_STRL("upload_filepaths"), upload_filepaths TSRMLS_CC);
}
ZEND_METHOD(fetch_url, body){
zval *zval_body;
zval_body = zend_read_property(FETCH_THIS, ZEND_STRL("body"), 0 TSRMLS_CC);
RETURN_STRINGL(Z_STRVAL_P(zval_body), Z_STRLEN_P(zval_body), 1);
}
ZEND_METHOD(fetch_url, clean){
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("body"), ZEND_STRL("") TSRMLS_CC);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("errmsg"), ZEND_STRL("") TSRMLS_CC);
zend_update_property_long(FETCH_THIS, ZEND_STRL("errno"), 0 TSRMLS_CC);
zend_update_property_null(FETCH_THIS, ZEND_STRL("httpCode") TSRMLS_CC);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("cookies"), ZEND_STRL("") TSRMLS_CC);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("headers"), ZEND_STRL("") TSRMLS_CC);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("send_headers"), ZEND_STRL("") TSRMLS_CC);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("data"), ZEND_STRL("") TSRMLS_CC);
zend_update_property_null(FETCH_THIS, ZEND_STRL("binary_data") TSRMLS_CC);
zend_update_property_null(FETCH_THIS, ZEND_STRL("upload_filepaths") TSRMLS_CC);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("method"), ZEND_STRL("get") TSRMLS_CC);
}
ZEND_METHOD(fetch_url, errmsg){
zval *errmsg = zend_read_property(FETCH_THIS, ZEND_STRL("errmsg"), 0 TSRMLS_CC);
RETURN_STRINGL(Z_STRVAL_P(errmsg), Z_STRLEN_P(errmsg), 1);
}
ZEND_METHOD(fetch_url, errcode){
zval *err_no = zend_read_property(FETCH_THIS, ZEND_STRL("errno"), 0 TSRMLS_CC);
RETURN_LONG(Z_LVAL_P(err_no));
}
static size_t read_data(void *buffer, size_t size, size_t nmemb, void *data){
smart_str *content = (smart_str*)data;
smart_str_appendl(content, buffer, size*nmemb);
return size*nmemb;
}
ZEND_METHOD(fetch_url, fetch){
CURLcode return_code;
CURL *curl_handler;
struct curl_slist *http_headers = NULL;
zval *url, *callback, *cookies, *connect_timeout, *allow_redirect, *method, *post_data, *read_timeout,
*send_headers, *err_no, *errmsg, *binary_data, *upload_filepaths;
smart_str body_str = {0}, header_str = {0};
struct curl_httppost *post = NULL;
struct curl_httppost *last = NULL;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &url, &callback) == FAILURE){
RETURN_FALSE;
}
err_no = zend_read_property(FETCH_THIS, ZEND_STRL("errno"), 0 TSRMLS_CC);
errmsg = zend_read_property(FETCH_THIS, ZEND_STRL("errmsg"), 0 TSRMLS_CC);
if(Z_LVAL_P(err_no) > 0){
php_printf("errno:%d, errmsg:%s", Z_LVAL_P(err_no), Z_STRVAL_P(errmsg));
RETURN_FALSE;
}
if(Z_TYPE_P(url) != IS_STRING){
FETCH_ERROR("fetch url must be string.", 500);
RETURN_FALSE;
}
return_code = curl_global_init(FETCH_CURL_MODE);
if(return_code != CURLE_OK){
curl_global_cleanup();
FETCH_ERROR("curl init failed.", 500);
RETURN_FALSE;
}
curl_handler = curl_easy_init();
if(NULL == curl_handler){
curl_easy_cleanup(curl_handler);
curl_global_cleanup();
FETCH_ERROR("get curl handler failed.", 500);
RETURN_FALSE;
}
cookies = zend_read_property(FETCH_THIS, ZEND_STRL("cookies"), 0 TSRMLS_CC);
connect_timeout = zend_read_property(FETCH_THIS, ZEND_STRL("connect_timeout"), 0 TSRMLS_CC);
read_timeout = zend_read_property(FETCH_THIS, ZEND_STRL("read_timeout"), 0 TSRMLS_CC);
allow_redirect = zend_read_property(FETCH_THIS, ZEND_STRL("allow_redirect"), 0 TSRMLS_CC);
method = zend_read_property(FETCH_THIS, ZEND_STRL("method"), 0 TSRMLS_CC);
post_data = zend_read_property(FETCH_THIS, ZEND_STRL("data"), 0 TSRMLS_CC);
send_headers = zend_read_property(FETCH_THIS, ZEND_STRL("send_headers"), 0 TSRMLS_CC);
binary_data = zend_read_property(FETCH_THIS, ZEND_STRL("binary_data"), 0 TSRMLS_CC);
upload_filepaths = zend_read_property(FETCH_THIS, ZEND_STRL("upload_filepaths"), 0 TSRMLS_CC);
curl_easy_setopt(curl_handler, CURLOPT_URL, Z_STRVAL_P(url));
curl_easy_setopt(curl_handler, CURLOPT_COOKIE, Z_STRVAL_P(cookies));
curl_easy_setopt(curl_handler, CURLOPT_WRITEFUNCTION, &read_data);
curl_easy_setopt(curl_handler, CURLOPT_WRITEDATA, &body_str);
curl_easy_setopt(curl_handler, CURLOPT_HEADERDATA, &header_str);
curl_easy_setopt(curl_handler, CURLOPT_HEADERFUNCTION, &read_data);
curl_easy_setopt(curl_handler, CURLOPT_TIMEOUT, Z_LVAL_P(read_timeout));
curl_easy_setopt(curl_handler, CURLOPT_CONNECTTIMEOUT, Z_LVAL_P(connect_timeout));
curl_easy_setopt(curl_handler, CURLOPT_AUTOREFERER, Z_LVAL_P(allow_redirect));
curl_easy_setopt(curl_handler, CURLOPT_MAXREDIRS, 5);
if(strcmp(Z_STRVAL_P(method), "get") == 0){
curl_easy_setopt(curl_handler, CURLOPT_HTTPGET, 1);
}else{
if(Z_TYPE_P(binary_data) != IS_NULL || Z_TYPE_P(upload_filepaths) != IS_NULL){
zval *delim, *post_arr, *delim_equal;
MAKE_STD_ZVAL(delim_equal);
MAKE_STD_ZVAL(delim);
MAKE_STD_ZVAL(post_arr);
ZVAL_STRING(delim, "&", 1);
ZVAL_STRING(delim_equal, "=", 1);
array_init(post_arr);
php_explode(delim, post_data, post_arr, LONG_MAX);
for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(post_arr));
zend_hash_has_more_elements(Z_ARRVAL_P(post_arr)) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(post_arr))){
zval **data_str;
zval *temp_data, **post_data_name, **post_data_value, *temp_zval;
if(zend_hash_get_current_data(Z_ARRVAL_P(post_arr), (void**)&data_str) == FAILURE){
continue;
}
if(Z_STRLEN_PP(data_str) > 0){
MAKE_STD_ZVAL(temp_data);
array_init(temp_data);
temp_zval = *data_str;
php_explode(delim_equal, temp_zval, temp_data, LONG_MAX);
zend_hash_index_find(Z_ARRVAL_P(temp_data), 0, (void**)&post_data_name);
zend_hash_index_find(Z_ARRVAL_P(temp_data), 1, (void**)&post_data_value);
curl_formadd(&post, &last, CURLFORM_COPYNAME, Z_STRVAL_PP(post_data_name), CURLFORM_COPYCONTENTS, Z_STRVAL_PP(post_data_value), CURLFORM_END);
zval_dtor(temp_data);
}
}
zval_dtor(post_arr);
zval_dtor(delim);
zval_dtor(delim_equal);
if(Z_TYPE_P(binary_data) != IS_NULL)
for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(binary_data));
zend_hash_has_more_elements(Z_ARRVAL_P(binary_data)) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(binary_data))){
char *input_file_name;
uint input_file_name_len;
ulong idx;
zval **item_data;
zval **upload_binary_data;
zval **uploadfile_name;
if(zend_hash_get_current_key_ex(Z_ARRVAL_P(binary_data), &input_file_name, &input_file_name_len, &idx, 0, NULL) != HASH_KEY_IS_STRING){
continue;
}
if(zend_hash_get_current_data(Z_ARRVAL_P(binary_data), (void**)&item_data) == FAILURE){
continue;
}
zend_hash_index_find(Z_ARRVAL_PP(item_data), 0, (void**)&uploadfile_name);
zend_hash_index_find(Z_ARRVAL_PP(item_data), 1, (void**)&upload_binary_data);
curl_formadd(&post,
&last,
CURLFORM_COPYNAME,
input_file_name,
CURLFORM_BUFFER,
Z_STRVAL_PP(uploadfile_name), //todo:setBinary需要传递文件名参数
CURLFORM_BUFFERPTR,
Z_STRVAL_PP(upload_binary_data),
CURLFORM_BUFFERLENGTH,
Z_STRLEN_PP(upload_binary_data),
CURLFORM_END
);
}
if(Z_TYPE_P(upload_filepaths) != IS_NULL)
for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(upload_filepaths));
zend_hash_has_more_elements(Z_ARRVAL_P(upload_filepaths)) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(upload_filepaths))){
char *input_filed_name;
uint input_file_name_len;
ulong idx;
zval **file_path;
if(zend_hash_get_current_key_ex(Z_ARRVAL_P(upload_filepaths), &input_filed_name, &input_file_name_len, &idx, 0, NULL) != HASH_KEY_IS_STRING){
continue;
}
if(zend_hash_get_current_data(Z_ARRVAL_P(upload_filepaths), (void**)&file_path) == FAILURE){
continue;
}
curl_formadd(&post, &last, CURLFORM_COPYNAME, input_filed_name, CURLFORM_FILE, Z_STRVAL_PP(file_path), CURLFORM_END);
}
curl_easy_setopt(curl_handler, CURLOPT_HTTPPOST, post);
http_headers = curl_slist_append(http_headers, estrdup("Expect:"));//防止出现HTTP 100跳转
}else{
curl_easy_setopt(curl_handler, CURLOPT_POSTFIELDS, Z_STRVAL_P(post_data));
curl_easy_setopt(curl_handler, CURLOPT_POST, 1);
}
}
if(Z_TYPE_P(send_headers) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(send_headers)) > 0){
for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(send_headers));
zend_hash_has_more_elements(Z_ARRVAL_P(send_headers)) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(send_headers))){
char *header_key;
uint header_keylen;
ulong idx;
zval **header_val;
smart_str impl_headers = {0};
if(zend_hash_get_current_key_ex(Z_ARRVAL_P(send_headers), &header_key, &header_keylen, &idx, 0, NULL) != HASH_KEY_IS_STRING){
continue;
}
if(zend_hash_get_current_data(Z_ARRVAL_P(send_headers), (void**)&header_val) == FAILURE){
continue;
}
smart_str_appendl(&impl_headers, header_key, header_keylen);
smart_str_appendl(&impl_headers, ": ", 2);
smart_str_appendl(&impl_headers, Z_STRVAL_PP(header_val), Z_STRLEN_PP(header_val));
http_headers = curl_slist_append(http_headers, impl_headers.c);
}
}
curl_easy_setopt(curl_handler, CURLOPT_HTTPHEADER, http_headers);
curl_easy_perform(curl_handler);
curl_slist_free_all(http_headers);
curl_formfree(post);
curl_easy_cleanup(curl_handler);
curl_global_cleanup();
smart_str_0(&body_str);
smart_str_0(&header_str);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("headers"), header_str.c, header_str.len TSRMLS_CC);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("body"), body_str.c, body_str.len TSRMLS_CC);
}
ZEND_METHOD(fetch_url, httpCode){
pcre_cache_entry *pce;
zval *headers;
zval *result_match, *match_long, **http_code;
char regex[30] = "/^HTTP\\/1\\.1\\s(.*)\\sOK/";
if((pce = pcre_get_compiled_regex_cache(regex, strlen(regex) TSRMLS_CC)) == NULL){
RETURN_FALSE;
}
MAKE_STD_ZVAL(result_match);
MAKE_STD_ZVAL(match_long);
ZVAL_LONG(match_long, 0);
ZVAL_NULL(result_match);
headers = zend_read_property(FETCH_THIS, ZEND_STRL("headers"), 0 TSRMLS_CC);
php_pcre_match_impl(pce, Z_STRVAL_P(headers), Z_STRLEN_P(headers), match_long, result_match, 0, 0, 0, 0 TSRMLS_CC);
if(Z_LVAL_P(match_long) > 0){
if(zend_hash_index_find(Z_ARRVAL_P(result_match), 1, (void**)&http_code) == FAILURE){
RETURN_FALSE;
}else{
RETURN_STRINGL(Z_STRVAL_PP(http_code), Z_STRLEN_PP(http_code), 0);
}
}else{
RETURN_FALSE;
}
}
ZEND_METHOD(fetch_url, responseCookies){
pcre_cache_entry *pce;
zval *headers, *result_match, *match_long;
char *regex = estrdup("/Set-Cookie:\\s(.*?);/");
headers = zend_read_property(FETCH_THIS, ZEND_STRL("headers"), 0 TSRMLS_CC);
array_init(return_value);
if(Z_STRLEN_P(headers) > 0){
if((pce = pcre_get_compiled_regex_cache(regex, strlen(regex) TSRMLS_CC)) == NULL){
RETURN_NULL();
}
MAKE_STD_ZVAL(result_match);
MAKE_STD_ZVAL(match_long);
//void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value, zval *subpats, int global, int use_flags, long flags, long start_offset TSRMLS_DC)
php_pcre_match_impl(pce, Z_STRVAL_P(headers), Z_STRLEN_P(headers), match_long, result_match, 1, 0, 0, 0 TSRMLS_CC);
if(Z_LVAL_P(match_long) > 0){
zval **result;
HashTable *result_ht;
char *found = NULL;
long found_offset;
char *cookie_name;
char *cookie_value;
if(zend_hash_index_find(Z_ARRVAL_P(result_match), 1, (void**)&result) != FAILURE){
result_ht = Z_ARRVAL_PP(result);
for(zend_hash_internal_pointer_reset(result_ht);
zend_hash_has_more_elements(result_ht) == SUCCESS;
zend_hash_move_forward(result_ht)){
zval **tmpzval;
if(zend_hash_get_current_data(result_ht, (void**)&tmpzval) == FAILURE){
continue;
}
found = php_memnstr(Z_STRVAL_PP(tmpzval), "=", 1, Z_STRVAL_PP(tmpzval) + Z_STRLEN_PP(tmpzval));
found_offset = found - Z_STRVAL_PP(tmpzval);
cookie_name = estrndup(Z_STRVAL_PP(tmpzval), found_offset);
cookie_value= estrndup(found+1, strlen(found)-1);
add_assoc_stringl(return_value, cookie_name, cookie_value, strlen(cookie_value), 1);
efree(cookie_name);
efree(cookie_value);
}
}
}
}else{
RETURN_NULL();
}
}
ZEND_METHOD(fetch_url, responseHeaders){
zval *headers, *delim;
uint idx;
headers = zend_read_property(FETCH_THIS, ZEND_STRL("headers"), 0 TSRMLS_CC);
MAKE_STD_ZVAL(delim);
array_init(return_value);
ZVAL_STRING(delim, "\r\n", 1);
php_explode(delim, headers, return_value, LONG_MAX);
idx = zend_hash_num_elements(Z_ARRVAL_P(return_value));
zend_hash_index_del(Z_ARRVAL_P(return_value), idx-1);
zend_hash_index_del(Z_ARRVAL_P(return_value), idx-2);
zval_dtor(delim);
}
ZEND_METHOD(fetch_url, setAllowRedirect){
zval *allow;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &allow) == FAILURE){
RETURN_FALSE;
}
convert_to_long(allow);
zend_update_property_long(FETCH_THIS, ZEND_STRL("allow_redirect"), Z_LVAL_P(allow) TSRMLS_CC);
}
ZEND_METHOD(fetch_url, setConnectTimeout){
zval *connect_timeout;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &connect_timeout) == FAILURE){
RETURN_FALSE;
}
convert_to_long(connect_timeout);
zend_update_property_long(FETCH_THIS, ZEND_STRL("connect_timeout"), Z_LVAL_P(connect_timeout) TSRMLS_CC);
}
ZEND_METHOD(fetch_url, setCookie){
zval *zval_cookies;
zval *cookie_name, *cookie_value;
smart_str impl_cookies = {0};
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &cookie_name, &cookie_value) == FAILURE){
RETURN_FALSE;
}
if(Z_TYPE_P(cookie_name) != IS_STRING || Z_TYPE_P(cookie_value) != IS_STRING){
RETURN_FALSE;
}
zval_cookies = zend_read_property(FETCH_THIS, ZEND_STRL("cookies"), 0 TSRMLS_CC);
smart_str_appendl(&impl_cookies, Z_STRVAL_P(zval_cookies), Z_STRLEN_P(zval_cookies));
smart_str_appendl(&impl_cookies, Z_STRVAL_P(cookie_name), Z_STRLEN_P(cookie_name));
smart_str_appendc(&impl_cookies, '=');
smart_str_appendl(&impl_cookies, Z_STRVAL_P(cookie_value), Z_STRLEN_P(cookie_value));
smart_str_appendc(&impl_cookies, ';');
smart_str_0(&impl_cookies);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("cookies"), impl_cookies.c, impl_cookies.len TSRMLS_CC);
}
ZEND_METHOD(fetch_url, setCookies){
zval *zval_cookies;
zval *cookie_array;
smart_str impl_cookies = {0};
HashTable *cookies_ht;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &cookie_array) == FAILURE){
RETURN_FALSE;
}
if(Z_TYPE_P(cookie_array) != IS_ARRAY){
RETURN_FALSE;
}
zval_cookies = zend_read_property(FETCH_THIS, ZEND_STRL("cookies"), 0 TSRMLS_CC);
cookies_ht = Z_ARRVAL_P(cookie_array);
smart_str_appendl(&impl_cookies, Z_STRVAL_P(zval_cookies), Z_STRLEN_P(zval_cookies));
for(zend_hash_internal_pointer_reset(cookies_ht);
zend_hash_has_more_elements(cookies_ht) == SUCCESS;
zend_hash_move_forward(cookies_ht))
{
zval **value;
char *key;
uint key_len;
ulong idx;
if(zend_hash_get_current_key_ex(cookies_ht, &key, &key_len, &idx, 0, NULL) != HASH_KEY_IS_STRING){
continue;
}
if(zend_hash_get_current_data(cookies_ht, (void**)&value) == FAILURE){
continue;
}
convert_to_string(*value);
if(Z_TYPE_PP(value) != IS_STRING){
continue;
}
smart_str_appendl(&impl_cookies, key, key_len-1);
smart_str_appendl(&impl_cookies, "=", 1);
smart_str_appendl(&impl_cookies, Z_STRVAL_PP(value), Z_STRLEN_PP(value));
smart_str_appendl(&impl_cookies, ";", 1);
}
php_url_decode(impl_cookies.c, impl_cookies.len);
smart_str_0(&impl_cookies);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("cookies"), impl_cookies.c, impl_cookies.len TSRMLS_CC);
}
ZEND_METHOD(fetch_url, setHeader){
zval *headers, *value=NULL, *send_headers;
HashTable *headers_ht;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &headers) == FAILURE){
RETURN_FALSE;
}
send_headers = zend_read_property(FETCH_THIS, ZEND_STRL("send_headers"), 0 TSRMLS_CC);
if(Z_TYPE_P(send_headers) == IS_NULL){
MAKE_STD_ZVAL(send_headers);
array_init(send_headers);
}
headers_ht = Z_ARRVAL_P(send_headers);
if(Z_TYPE_P(headers) == IS_ARRAY){
for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(headers));
zend_hash_has_more_elements(Z_ARRVAL_P(headers)) == SUCCESS;
zend_hash_move_forward(Z_ARRVAL_P(headers))){
char* key;
uint key_len;
ulong idx;
zval **tmpzval;
if(zend_hash_get_current_key_ex(Z_ARRVAL_P(headers), &key, &key_len, &idx, 0, NULL) != HASH_KEY_IS_STRING){
continue;
}
if(zend_hash_get_current_data(Z_ARRVAL_P(headers), (void**)&tmpzval) == FAILURE){
continue;
}
add_assoc_stringl(send_headers, key, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), 1);
}
}else if(Z_TYPE_P(headers) == IS_STRING && Z_TYPE_P(value) == IS_STRING){
add_assoc_stringl(send_headers, Z_STRVAL_P(headers), Z_STRVAL_P(value), Z_STRLEN_P(value), 1);
}else{
zend_error(E_WARNING, "param error.");
}
zend_update_property(FETCH_THIS, ZEND_STRL("send_headers"), send_headers);
}
ZEND_METHOD(fetch_url, setMethod){
zval *zval_method;
char *method;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zval_method) == FAILURE){
RETURN_FALSE;
}
if(Z_TYPE_P(zval_method) != IS_STRING){
RETURN_FALSE;
}
method = php_strtolower(Z_STRVAL_P(zval_method), Z_STRLEN_P(zval_method));
if(strcmp(method, "get") == 0){
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("method"), ZEND_STRL("get") TSRMLS_CC);
}else if(strcmp(method, "post") == 0){
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("method"), ZEND_STRL("post") TSRMLS_CC);
}else{
FETCH_ERROR("Not support method.", 404);
RETURN_FALSE;
}
RETURN_TRUE;
}
ZEND_METHOD(fetch_url, setPostData){
zval *data, *post_data;
HashTable *post_data_ht;
smart_str temp = {0};
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &post_data) == FAILURE){
RETURN_FALSE;
}
data = zend_read_property(FETCH_THIS, ZEND_STRL("data"), 0 TSRMLS_CC);
if(Z_TYPE_P(post_data) != IS_ARRAY){
zend_error(E_WARNING, "post data must be array.");
RETURN_FALSE;
}
post_data_ht = Z_ARRVAL_P(post_data);
smart_str_appendl(&temp, Z_STRVAL_P(data), Z_STRLEN_P(data));
for(zend_hash_internal_pointer_reset(post_data_ht);
zend_hash_has_more_elements(post_data_ht) == SUCCESS;
zend_hash_move_forward(post_data_ht)){
zval **current_data;
char *key;
uint key_len;
ulong idx;
if(zend_hash_get_current_key_ex(post_data_ht, &key, &key_len, &idx, 0, NULL) != HASH_KEY_IS_STRING){
continue;
}
if(zend_hash_get_current_data(post_data_ht, (void**)&current_data) == FAILURE){
continue;
}
convert_to_string(*current_data);
smart_str_appendl(&temp, key, key_len-1);
smart_str_appendc(&temp, '=');
smart_str_appendl(&temp, Z_STRVAL_PP(current_data), Z_STRLEN_PP(current_data));
smart_str_appendc(&temp, '&');
}
smart_str_0(&temp);
zend_update_property_stringl(FETCH_THIS, ZEND_STRL("data"), temp.c, temp.len TSRMLS_CC);
}
ZEND_METHOD(fetch_url, setReadTimeout){
zval *read_timeout;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &read_timeout) == FAILURE){
RETURN_FALSE;
}
if(Z_TYPE_P(read_timeout) != IS_LONG){
zend_error(E_WARNING, "readtimeout must be integer.");
RETURN_FALSE;
}
zend_update_property_long(FETCH_THIS, ZEND_STRL("read_timeout"), Z_LVAL_P(read_timeout) TSRMLS_CC);
}
ZEND_METHOD(fetch_url, __destruct){}
static zend_function_entry fetch_url_method[] = {
ZEND_ME(fetch_url, __construct, void_arginfo, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setBinary, setBinary_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setFile, setFile_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, body, void_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, clean, void_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, errmsg, void_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, errcode, void_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, fetch, fetch_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, httpCode, void_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, responseCookies, responseCookies_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, responseHeaders, responseHeaders_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setAllowRedirect, setAllowRedirect_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setConnectTimeout, setConnectTimeout_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setCookie, setCookie_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setCookies, setCookies_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setHeader, setHeader_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setMethod, setMethod_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setPostData, setPostData, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, setReadTimeout, setReadTimeout_arginfo, ZEND_ACC_PUBLIC)
ZEND_ME(fetch_url, __destruct, void_arginfo, ZEND_ACC_DTOR|ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
/* If you declare any globals in php_fetch_url.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(fetch_url)
*/
/* True global resources - no need for thread safety here */
static int le_fetch_url;
/* {{{ fetch_url_functions[]
*
* Every user visible function must have an entry in fetch_url_functions[].
*/
const zend_function_entry fetch_url_functions[] = {
PHP_FE_END /* Must be the last line in fetch_url_functions[] */
};
/* }}} */
/* {{{ fetch_url_module_entry
*/
zend_module_entry fetch_url_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"fetch_url",
fetch_url_functions,
PHP_MINIT(fetch_url),
PHP_MSHUTDOWN(fetch_url),
PHP_RINIT(fetch_url), /* Replace with NULL if there's nothing to do at request start */
PHP_RSHUTDOWN(fetch_url), /* Replace with NULL if there's nothing to do at request end */
PHP_MINFO(fetch_url),
#if ZEND_MODULE_API_NO >= 20010901
"0.1", /* Replace with version number for your extension */
#endif
STANDARD_MODULE_PROPERTIES
};
/* }}} */
#ifdef COMPILE_DL_FETCH_URL
ZEND_GET_MODULE(fetch_url)
#endif
/* {{{ PHP_INI
*/
/* Remove comments and fill if you need to have entries in php.ini
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("fetch_url.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_fetch_url_globals, fetch_url_globals)
STD_PHP_INI_ENTRY("fetch_url.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_fetch_url_globals, fetch_url_globals)
PHP_INI_END()
*/
/* }}} */
/* {{{ php_fetch_url_init_globals
*/
/* Uncomment this function if you have INI entries
static void php_fetch_url_init_globals(zend_fetch_url_globals *fetch_url_globals)
{
fetch_url_globals->global_value = 0;
fetch_url_globals->global_string = NULL;
}
*/
/* }}} */
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(fetch_url)
{
/* If you have INI entries, uncomment these lines
REGISTER_INI_ENTRIES();
*/
zend_class_entry fetch_ce;
INIT_CLASS_ENTRY(fetch_ce, FETCH_CLASS_NAME, fetch_url_method);
g_fetch_ce = zend_register_internal_class(&fetch_ce TSRMLS_CC);
zend_declare_property_stringl(g_fetch_ce, ZEND_STRL("body"), ZEND_STRL(""), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(g_fetch_ce, ZEND_STRL("errmsg"), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_long(g_fetch_ce, ZEND_STRL("errno"), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(g_fetch_ce, ZEND_STRL("httpCode"), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_stringl(g_fetch_ce, ZEND_STRL("cookies"), ZEND_STRL(""), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_stringl(g_fetch_ce, ZEND_STRL("headers"), ZEND_STRL(""), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(g_fetch_ce, ZEND_STRL("send_headers"), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_long(g_fetch_ce, ZEND_STRL("allow_redirect"), 1, ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_long(g_fetch_ce, ZEND_STRL("connect_timeout"), 5, ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_stringl(g_fetch_ce, ZEND_STRL("method"), ZEND_STRL("get"), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_long(g_fetch_ce, ZEND_STRL("multilpart"), 0, ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_stringl(g_fetch_ce, ZEND_STRL("data"), ZEND_STRL(""), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_long(g_fetch_ce, ZEND_STRL("read_timeout"), 60, ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(g_fetch_ce, ZEND_STRL("binary_data"), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(g_fetch_ce, ZEND_STRL("upload_filepaths"), ZEND_ACC_PROTECTED TSRMLS_CC);
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(fetch_url)
{
/* uncomment this line if you have INI entries
UNREGISTER_INI_ENTRIES();
*/
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
*/
PHP_RINIT_FUNCTION(fetch_url)
{
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
PHP_RSHUTDOWN_FUNCTION(fetch_url)
{
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(fetch_url)
{
php_info_print_table_start();
php_info_print_table_header(2, "fetch_url support", "enabled");
php_info_print_table_end();
/* Remove comments if you have entries in php.ini
DISPLAY_INI_ENTRIES();
*/
}
/* }}} */
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/Davis/php-class-fetch_url.git
git@gitee.com:Davis/php-class-fetch_url.git
Davis
php-class-fetch_url
PHP class fetch_url
master

搜索帮助