Hi, this works for me with curl-7.9.8 and php-4.2.3 under Linux.
Problems are: * curl_easy_cleanup segfaults after curl_multi_cleanup * I have to introduce Version checking in these m4 Files Please give me suggestions howto make it clean and stable. thx Boris Here an example what this patch enables: <? // creates a multi session $multi = curl_multi_init(); // start of a normal easy session $ch1 = curl_init("http://192.168.4.2/"); $ch2 = curl_init("http://192.168.4.2/"); curl_setopt($ch1,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch2,CURLOPT_RETURNTRANSFER,1); // adding the easy handles to the multi hndle curl_multi_add ($multi,$ch1); curl_multi_add ($multi,$ch2); // executing all curl_multi_exec($multi); // getting content $c1=curl_get_content($ch1); $c2=curl_get_content($ch2); curl_close($ch1); curl_close($ch2); echo "<br>ch1=".strlen($c1); echo "<br>ch2=".strlen($c2); ?> Regards Boris Bukowski
diff -ur php-4.2.3_orig/ext/curl/curl.c php-4.2.3/ext/curl/curl.c --- php-4.2.3_orig/ext/curl/curl.c 2002-04-04 02:04:25.000000000 +0200 +++ php-4.2.3/ext/curl/curl.c 2002-10-13 20:54:37.000000000 +0200 @@ -28,6 +28,10 @@ #include <stdio.h> #include <string.h> +#include <unistd.h> +#include <time.h> +#include<sys/timeb.h> + #ifdef PHP_WIN32 #include <winsock.h> @@ -45,9 +49,11 @@ #include "php_curl.h" static int le_curl; +static int le_multi_curl; #define le_curl_name "cURL handle" static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC); +static void _php_multi_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC); #define SAVE_CURL_ERROR(__handle, __err) (__handle)->err.no = (int) __err; @@ -55,9 +61,13 @@ */ function_entry curl_functions[] = { PHP_FE(curl_init, NULL) + PHP_FE(curl_multi_init, NULL) PHP_FE(curl_version, NULL) PHP_FE(curl_setopt, NULL) PHP_FE(curl_exec, NULL) + PHP_FE(curl_get_content, NULL) + PHP_FE(curl_multi_exec, NULL) + PHP_FE(curl_multi_add, NULL) PHP_FE(curl_getinfo, NULL) PHP_FE(curl_error, NULL) PHP_FE(curl_errno, NULL) @@ -93,6 +103,7 @@ php_info_print_table_start(); php_info_print_table_row(2, "CURL support", "enabled"); php_info_print_table_row(2, "CURL Information", curl_version()); + php_info_print_table_row(2, "CURL Multi Interface", "enabled"); php_info_print_table_end(); } /* }}} */ @@ -104,7 +115,8 @@ PHP_MINIT_FUNCTION(curl) { le_curl = zend_register_list_destructors_ex(_php_curl_close, NULL, "curl", module_number); - + le_multi_curl = zend_register_list_destructors_ex(_php_multi_curl_close, NULL, "curl", module_number); + /* Constants for curl_setopt() */ REGISTER_CURL_CONSTANT(CURLOPT_PORT); REGISTER_CURL_CONSTANT(CURLOPT_FILE); @@ -151,6 +163,7 @@ REGISTER_CURL_CONSTANT(CURLOPT_STDERR); REGISTER_CURL_CONSTANT(CURLOPT_TRANSFERTEXT); REGISTER_CURL_CONSTANT(CURLOPT_RETURNTRANSFER); + REGISTER_CURL_CONSTANT(CURLOPT_INMEMORY); REGISTER_CURL_CONSTANT(CURLOPT_QUOTE); REGISTER_CURL_CONSTANT(CURLOPT_POSTQUOTE); REGISTER_CURL_CONSTANT(CURLOPT_INTERFACE); @@ -542,6 +555,8 @@ (*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write)); (*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write)); (*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read)); + (*ch)->multi = 0; + memset(&(*ch)->err, 0, sizeof((*ch)->err)); zend_llist_init(&(*ch)->to_free.str, sizeof(char *), @@ -602,6 +617,128 @@ } /* }}} */ + +/* {{{ proto int curl_init([string url]) + Initialize a CURL session */ +PHP_FUNCTION(curl_multi_init) +{ + php_multi_curl *multi_handle; + multi_handle=emalloc(sizeof(php_multi_curl)); + multi_handle->cp = curl_multi_init(); + ZEND_REGISTER_RESOURCE(return_value, multi_handle, le_multi_curl); + multi_handle->id = Z_LVAL_P(return_value); + + +} + +PHP_FUNCTION(curl_multi_exec) +{ + zval **zidm; + php_multi_curl *multi_handle; + CURLcode error; + int still_running; + struct timeb start; + struct timeb now; + long nmili; + + ftime(&start); + + if ( ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &zidm) == FAILURE) { + WRONG_PARAM_COUNT; + } + ZEND_FETCH_RESOURCE(multi_handle, php_multi_curl *, zidm, -1, le_curl_name, le_multi_curl); + + +/* while(still_running) { */ +/* struct timespec t,tl; */ +/* t.tv_sec=0; */ +/* t.tv_nsec=50000000; */ +/* curl_multi_perform(multi_handle->cp, &still_running); */ + +/* ftime(&now); */ +/* nmili=(now.time-start.time)*1000 - start.millitm + now.millitm; */ +/* zend_printf("%d<br>", nmili); */ + +/* nanosleep(&t,&tl); */ +/* } */ + + + + while(still_running) { + + struct timeval timeout; + int rc; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + int maxfd; + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + + curl_multi_fdset(multi_handle->cp, &fdread, &fdwrite, &fdexcep, &maxfd); + rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); + + /* + ftime(&now); + nmili=(now.time-start.time)*1000 - start.millitm + now.millitm; + zend_printf("%d:%d<br>", nmili, rc); + */ + + switch(rc) { + case -1: + break; + case 0: + default: + curl_multi_perform(multi_handle->cp, &still_running); + } + + } + + +} + +PHP_FUNCTION(curl_multi_add) +{ + zval **zidm; + zval **zidc; + php_curl *ch; + php_multi_curl *multi_handle; + CURLcode error; + + if (ZEND_NUM_ARGS() != 2 || + zend_get_parameters_ex(2, &zidm, &zidc) == FAILURE +) { + WRONG_PARAM_COUNT; + } + + ZEND_FETCH_RESOURCE(multi_handle, php_multi_curl *, zidm, -1, le_curl_name, le_multi_curl); + ZEND_FETCH_RESOURCE(ch, php_curl *, zidc, -1, le_curl_name, le_curl); + if(ch->multi == 1) { + RETURN_FALSE; + + } else { + ch->multi=1; + } + + error = curl_multi_add_handle(multi_handle->cp, ch->cp); + SAVE_CURL_ERROR(ch, error); + if (error != CURLE_OK) { + RETURN_FALSE; + } + + RETURN_TRUE; +} + + + + + + /* {{{ proto bool curl_setopt(int ch, string option, mixed value) Set an option for a CURL transfer */ PHP_FUNCTION(curl_setopt) @@ -726,6 +863,13 @@ ch->handlers->write->method = PHP_CURL_RETURN; } break; + case CURLOPT_INMEMORY: + convert_to_long_ex(zvalue); + + if (Z_LVAL_PP(zvalue)) { + ch->handlers->write->method = PHP_CURL_RETURN; + } + break; case CURLOPT_BINARYTRANSFER: convert_to_long_ex(zvalue); ch->handlers->write->type = PHP_CURL_BINARY; @@ -889,8 +1033,33 @@ RETURN_TRUE; } + + /* }}} */ +PHP_FUNCTION(curl_get_content) +{ + zval **zid; + php_curl *ch; + CURLcode error; + + if (ZEND_NUM_ARGS() != 1 || + zend_get_parameters_ex(1, &zid) == FAILURE) { + WRONG_PARAM_COUNT; + } + ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl); + + + if (ch->handlers->write->method == PHP_CURL_RETURN && ch->handlers->write->buf.len > 0) { + if (ch->handlers->write->type != PHP_CURL_BINARY) + smart_str_0(&ch->handlers->write->buf); + RETURN_STRINGL(ch->handlers->write->buf.c, ch->handlers->write->buf.len, 0); + } + + RETURN_FALSE; +} + + #define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s), v); #define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s), v); #define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s), v, 1); @@ -1052,8 +1221,11 @@ static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC) { php_curl *ch = (php_curl *) rsrc->ptr; - + if (ch->multi != 1){ + curl_easy_cleanup(ch->cp); + } + zend_llist_clean(&ch->to_free.str); zend_llist_clean(&ch->to_free.slist); zend_llist_clean(&ch->to_free.post); @@ -1071,6 +1243,17 @@ } /* }}} */ +static void _php_multi_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + php_multi_curl *multi_handle = (php_multi_curl *) rsrc->ptr; + + curl_multi_cleanup(multi_handle->cp); + + efree(multi_handle); +} + + + #endif /* diff -ur php-4.2.3_orig/ext/curl/php_curl.h php-4.2.3/ext/curl/php_curl.h --- php-4.2.3_orig/ext/curl/php_curl.h 2001-12-11 16:28:58.000000000 +0100 +++ php-4.2.3/ext/curl/php_curl.h 2002-10-13 20:54:37.000000000 +0200 @@ -39,14 +39,19 @@ #define CURLOPT_RETURNTRANSFER 19913 #define CURLOPT_BINARYTRANSFER 19914 +#define CURLOPT_INMEMORY 19915 PHP_MINIT_FUNCTION(curl); PHP_MSHUTDOWN_FUNCTION(curl); PHP_MINFO_FUNCTION(curl); PHP_FUNCTION(curl_version); PHP_FUNCTION(curl_init); +PHP_FUNCTION(curl_multi_init); PHP_FUNCTION(curl_setopt); PHP_FUNCTION(curl_exec); +PHP_FUNCTION(curl_get_content); +PHP_FUNCTION(curl_multi_exec); +PHP_FUNCTION(curl_multi_add); PHP_FUNCTION(curl_getinfo); PHP_FUNCTION(curl_error); PHP_FUNCTION(curl_errno); @@ -91,8 +96,15 @@ struct _php_curl_error err; struct _php_curl_free to_free; long id; + long multi; } php_curl; +typedef struct { + CURLM *cp; + struct _php_curl_error err; + long id; +} php_multi_curl; + #else #define curl_module_ptr NULL
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php