Please see attached a new patch that fixes the problem with delimiters
bigger than one char (that's what happens when you code after
midnight). Also, as suggested by Hannes, skip_empty is now being
parsed as zend boolean (b) instead of zval (Z).

Regards,
Igor Feghali.
Index: ext/standard/php_string.h
===================================================================
RCS file: /repository/php-src/ext/standard/php_string.h,v
retrieving revision 1.87.2.2.2.3.2.3
diff -u -r1.87.2.2.2.3.2.3 php_string.h
--- ext/standard/php_string.h	2 Nov 2008 18:24:34 -0000	1.87.2.2.2.3.2.3
+++ ext/standard/php_string.h	6 Dec 2008 13:46:19 -0000
@@ -137,7 +137,7 @@
 PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, int *stateptr, char *allow, int allow_len, zend_bool allow_tag_spaces);
 PHPAPI int php_char_to_str_ex(char *str, uint len, char from, char *to, int to_len, zval *result, int case_sensitivity, int *replace_count);
 PHPAPI int php_char_to_str(char *str, uint len, char from, char *to, int to_len, zval *result);
-PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC);
+PHPAPI void php_implode(zval *delim, zval *arr, zval *skip_empty, zval *return_value TSRMLS_DC);
 PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit);
 
 PHPAPI size_t php_strspn(char *s1, char *s2, char *s1_end, char *s2_end); 
Index: ext/standard/string.c
===================================================================
RCS file: /repository/php-src/ext/standard/string.c,v
retrieving revision 1.445.2.14.2.69.2.38
diff -u -r1.445.2.14.2.69.2.38 string.c
--- ext/standard/string.c	21 Nov 2008 19:16:50 -0000	1.445.2.14.2.69.2.38
+++ ext/standard/string.c	6 Dec 2008 13:46:21 -0000
@@ -1033,30 +1033,28 @@
 }
 /* }}} */
 
-/* {{{ proto string join(array src, string glue)
+/* {{{ proto string join(array src, string glue[, boolean skip_empty])
    An alias for implode */
 /* }}} */
 
 /* {{{ php_implode
  */
-PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC) 
+PHPAPI void php_implode(zval *delim, zval *arr, zval *skip_empty, zval *return_value TSRMLS_DC) 
 {
 	zval         **tmp;
 	HashPosition   pos;
 	smart_str      implstr = {0};
-	int            numelems, i = 0;
-	zval tmp_val;
-	int str_len;
-
-	numelems = zend_hash_num_elements(Z_ARRVAL_P(arr));
+	zval           tmp_val;
+	int            str_len, len;
 
-	if (numelems == 0) {
+	if (zend_hash_num_elements(Z_ARRVAL_P(arr)) == 0) {
 		RETURN_EMPTY_STRING();
 	}
 
 	zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos);
 
 	while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **) &tmp, &pos) == SUCCESS) {
+		len = implstr.len;
 		switch ((*tmp)->type) {
 			case IS_STRING:
 				smart_str_appendl(&implstr, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
@@ -1107,10 +1105,14 @@
 				
 		}
 
-		if (++i != numelems) {
-			smart_str_appendl(&implstr, Z_STRVAL_P(delim), Z_STRLEN_P(delim));
-		}
 		zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos);
+		if (Z_BVAL_P(skip_empty) && (implstr.len == len)) {
+			continue;
+		}
+		smart_str_appendl(&implstr, Z_STRVAL_P(delim), Z_STRLEN_P(delim));
+	}
+	if (implstr.len) {
+		implstr.len -= Z_STRLEN_P(delim);
 	}
 	smart_str_0(&implstr);
 
@@ -1123,14 +1125,15 @@
 }
 /* }}} */
 
-/* {{{ proto string implode([string glue,] array pieces)
+/* {{{ proto string implode([string glue,] array pieces[, boolean skip_empty])
    Joins array elements placing glue string between items and return one string */
 PHP_FUNCTION(implode)
 {
-	zval **arg1 = NULL, **arg2 = NULL, *delim, *arr;
+	zval **arg1 = NULL, **arg2 = NULL, *delim, *arr, *skip_empty;
+	zend_bool arg3;
 	HashPosition pos;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z", &arg1, &arg2) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Zb", &arg1, &arg2, &arg3) == FAILURE) {
 		return;
 	}
 	
@@ -1161,9 +1164,16 @@
 		}
 	}
 
+		MAKE_STD_ZVAL(skip_empty);
+	if (arg3) {
+		ZVAL_BOOL(skip_empty, 1);
+	} else {
+		ZVAL_BOOL(skip_empty, 0);
+	}
+
 	pos = Z_ARRVAL_P(arr)->pInternalPointer;
 	
-	php_implode(delim, arr, return_value TSRMLS_CC);
+	php_implode(delim, arr, skip_empty, return_value TSRMLS_CC);
 
 	Z_ARRVAL_P(arr)->pInternalPointer = pos;
 
Index: tests/strings/001.phpt
===================================================================
RCS file: /repository/php-src/tests/strings/001.phpt,v
retrieving revision 1.3.4.1.4.1
diff -u -r1.3.4.1.4.1 001.phpt
--- tests/strings/001.phpt	5 Jun 2008 08:29:29 -0000	1.3.4.1.4.1
+++ tests/strings/001.phpt	6 Dec 2008 13:46:27 -0000
@@ -190,6 +190,18 @@
 	echo("failed!\n");
 }
 
+echo 'Testing implode: ';
+$foo = 'bar';
+$arr = array(1,'',2,null,3,0,4,true,5,false,false);
+
+$str1 = implode(',|', $arr);
+$str2 = implode(',|', $arr, $foo);
+
+if ($str1 == '1,|,|2,|,|3,|0,|4,|1,|5,|,|' && $str2 == '1,|2,|3,|0,|4,|1,|5' && $foo == 'bar') {
+	echo("passed\n");
+} else {
+	echo("failed!\n");
+}
 ?>
 --EXPECT--
 Testing strtok: passed
@@ -208,3 +220,5 @@
 Testing addslashes: passed
 Testing stripslashes: passed
 Testing uniqid: passed
+Testing implode: passed
+
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to