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