Re: fputcsv()

From: Date: Sun, 11 Apr 2004 17:07:12 +0000
Subject: Re: fputcsv()
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-9042@lists.php.net to get a copy of this message
How about using PHP_EOL? At 12:33 PM 4/11/2004 -0400, David Sklar wrote:
Attached is a patch that implements fputcsv() as a complement to fgetcsv(). There are two things that still need improvement: - It adds "\n" as a newline onto the end of each line. I think it would be better to add a platform-specific line ending. - It is not mbstring-aware. Any suggestions for fixing these things (or other issues) would be appreciated. Thanks, David Index: ext/standard/basic_functions.c =================================================================== RCS file: /repository/php-src/ext/standard/basic_functions.c,v retrieving revision 1.662 diff -u -B -b -r1.662 basic_functions.c
--- ext/standard/basic_functions.c      3 Apr 2004 09:51:57 -0000       1.662
+++ ext/standard/basic_functions.c      11 Apr 2004 16:31:33 -0000
@@ -596,6 +596,7 @@
        PHP_FE(stream_copy_to_stream,                                                NULL)
        PHP_FE(stream_get_contents,                                                        NULL)
        PHP_FE(fgetcsv,                                                                NULL)
+       PHP_FE(fputcsv,                                                              NULL)
        PHP_FE(flock,                                third_arg_force_ref)
        PHP_FE(get_meta_tags,                                                        NULL)
        PHP_FE(stream_set_write_buffer,                                                NULL)
Index: ext/standard/file.h =================================================================== RCS file: /repository/php-src/ext/standard/file.h,v retrieving revision 1.88 diff -u -B -b -r1.88 file.h
--- ext/standard/file.h 8 Jan 2004 17:32:51 -0000       1.88
+++ ext/standard/file.h 11 Apr 2004 16:31:33 -0000 @@ -39,6 +39,7 @@ PHP_FUNCTION(fscanf); PHPAPI PHP_FUNCTION(fgetss); PHP_FUNCTION(fgetcsv); +PHP_FUNCTION(fputcsv); PHPAPI PHP_FUNCTION(fwrite); PHPAPI PHP_FUNCTION(fflush); PHPAPI PHP_FUNCTION(rewind); Index: ext/standard/file.c =================================================================== RCS file: /repository/php-src/ext/standard/file.c,v retrieving revision 1.380 diff -u -B -b -r1.380 file.c
--- ext/standard/file.c 25 Feb 2004 20:16:26 -0000      1.380
+++ ext/standard/file.c 11 Apr 2004 16:31:35 -0000 @@ -35,6 +35,7 @@ #include "php_open_temporary_file.h" #include "ext/standard/basic_functions.h" #include "php_ini.h" +#include "php_smart_str.h" #include <stdio.h> #include <stdlib.h> @@ -1704,6 +1705,112 @@
        return ptr;
} +/* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]]) + Format line as CSV and write to file pointer */ +PHP_FUNCTION(fputcsv) +{
+       char *delimiter = ",";  /* allow this to be set as parameter */
+       char *enclosure = "\""; /* allow this to be set as parameter */
+    php_stream *stream;
+    int ret;
+    zval *fp = NULL, *fields = NULL, **field = NULL;
+    char *delimiter_str = NULL;
+    int delimiter_str_len = 0;
+    char *enclosure_str = NULL;
+    int enclosure_str_len = 0;
+    char *buffer = NULL;
+    int csvline_len = 0;
+    HashPosition pos;
+    int count = 0, i = 0;
+    char enc_double[3];
+    smart_str csvline = {0};
+
+    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ass",
+                              &fp, &fields, &delimiter_str, &delimiter_str_len,
+                              &enclosure_str, &enclosure_str_len) == FAILURE) {
+        return;
+    }
+
+    if (delimiter_str != NULL) {
+        /* Make sure that there is at least one character in string */
+        if (delimiter_str_len < 1) {
+            php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
+            RETURN_FALSE;
+        }
+
+        /* use first character from string */
+        delimiter[0] = delimiter_str[0];
+    }
+
+    if (enclosure_str != NULL) {
+        if (enclosure_str_len < 1) {
+            php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
+            RETURN_FALSE;
+        }
+        /* use first character from string */
+        enclosure[0] = enclosure_str[0];
+    }
+
+    PHP_STREAM_TO_ZVAL(stream, &fp);
+
+    enc_double[0] = enc_double[1] = enclosure[0];
+    enc_double[2] = '\0';
+    count = zend_hash_num_elements(Z_ARRVAL_P(fields));
+    zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos);
+    while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field, &pos) == SUCCESS) {
+               if ((*field)->type != IS_STRING) {
+                       SEPARATE_ZVAL(field);
+                       convert_to_string(*field);
+               }
+        /* enclose a field that contains a delimiter, an enclosure
+           character, or a newline */
+        if (php_memnstr(Z_STRVAL_PP(field), delimiter, 1, Z_STRVAL_PP(field) + Z_STRLEN_PP(field)) ||
+            php_memnstr(Z_STRVAL_PP(field), enclosure, 1, Z_STRVAL_PP(field) + Z_STRLEN_PP(field)) ||
+            php_memnstr(Z_STRVAL_PP(field), "\n", 1, Z_STRVAL_PP(field) + Z_STRLEN_PP(field)) ||
+            php_memnstr(Z_STRVAL_PP(field), "\r", 1, Z_STRVAL_PP(field) + Z_STRLEN_PP(field))) {
+
+            smart_str_appendl(&csvline, enclosure, 1);
+
+            {
+                zval enclosed_field;
+                php_char_to_str_ex(Z_STRVAL_PP(field), Z_STRLEN_PP(field), enclosure[0],
+                                   enc_double, 2, &enclosed_field, 0, NULL);
+                smart_str_appendl(&csvline, Z_STRVAL(enclosed_field), Z_STRLEN(enclosed_field));
+                zval_dtor(&enclosed_field);
+            }
+            smart_str_appendl(&csvline, enclosure, 1);
+        } else {
+            smart_str_appendl(&csvline, Z_STRVAL_PP(field), Z_STRLEN_PP(field));
+        }
+        if (++i != count) {
+            smart_str_appendl(&csvline, delimiter, 1);
+        }
+        zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos);
+    }
+
+    /* XXX: this should be platform-specific */
+    smart_str_appendc(&csvline, '\n');
+
+    smart_str_0(&csvline);
+
+       if (PG(magic_quotes_runtime)) {
+               buffer = estrndup(csvline.c, csvline.len);
+               php_stripslashes(buffer, &csvline_len TSRMLS_CC);
+       } else {
+        csvline_len = csvline.len;
+    }
+
+       ret = php_stream_write(stream, buffer ? buffer : csvline.c, csvline_len);
+
+       if (buffer) {
+               efree(buffer);
+       }
+
+    smart_str_free(&csvline);
+
+       RETURN_LONG(ret);
+} + /* {{{ proto array fgetcsv(resource fp [,int length [, string delimiter [, string enclosure]]])
    Get line from file pointer and parse for CSV fields */
PHP_FUNCTION(fgetcsv) -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php


« previous php.internals (#9042) next »