[PHP-DEV] [PATCH] New function file_put_contents()
Ok, I try again to submit the patch and a test script for it :-) Prototype: int file_put_contents(string filename, mixed data [, string mode]) It takes a filename (URL wrappers supported), the data to be written and a mode for the file. The data can be either a string or an array (which is like using join(, $data) first and can be used to write data read by the file() function). The mode can be a or ab to append to a file and defaults to wb. The function returns the number of bytes written to the stream. - Chris Index: ext/standard/basic_functions.c === RCS file: /repository/php4/ext/standard/basic_functions.c,v retrieving revision 1.528 diff -u -r1.528 basic_functions.c --- ext/standard/basic_functions.c 6 Oct 2002 17:04:10 - 1.528 +++ ext/standard/basic_functions.c 16 Oct 2002 01:48:48 - @@ -625,6 +625,7 @@ PHP_STATIC_FE(tmpfile,php_if_tmpfile, NULL) PHP_FE(file, NULL) PHP_FE(file_get_contents, NULL) + PHP_FE(file_put_contents, + NULL) PHP_FE(stream_select, first_through_third_args_force_ref) PHP_FE(stream_context_create, NULL) PHP_FE(stream_context_set_params, NULL) Index: ext/standard/file.c === RCS file: /repository/php4/ext/standard/file.c,v retrieving revision 1.270 diff -u -r1.270 file.c --- ext/standard/file.c 15 Oct 2002 16:45:26 - 1.270 +++ ext/standard/file.c 16 Oct 2002 01:48:49 - @@ -452,6 +452,79 @@ } /* }}} */ +/* {{{ proto int file_put_contents(string filename, mixed data [, string mode]) + Write an entire string or array to a file and return length written */ +PHP_FUNCTION(file_put_contents) +{ + size_t ret = 0; + char *filename; + int filename_len; + char *data = NULL; + int data_len; + zval *arr = NULL; + char *mode = wb; + int mode_len; + HashPosition pos; + zval **tmp = NULL; + php_stream *stream; + + /* Parse arguments */ + if ((zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() +TSRMLS_CC, ss|s, + filename, +filename_len, data, data_len, mode, mode_len) == FAILURE) + (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, sa|s, + filename, filename_len, arr, mode, mode_len) == +FAILURE)) { + return; + } + + stream = php_stream_open_wrapper(filename, mode, + ENFORCE_SAFE_MODE | REPORT_ERRORS, + NULL); + if (!stream) { + RETURN_FALSE; + } + + if (arr) { + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), pos); + + if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)tmp, +pos) == SUCCESS) { + convert_to_string_ex(tmp); + data = Z_STRVAL_PP(tmp); + data_len = Z_STRLEN_PP(tmp); + } + } + + while (data) { + char *buffer = NULL; + + if (PG(magic_quotes_runtime)) { + buffer = estrndup(data, data_len); + php_stripslashes(buffer, data_len TSRMLS_CC); + } + + ret += php_stream_write(stream, buffer ? buffer : data, data_len); + if (buffer) { + efree(buffer); + } + + data = NULL; + + if (arr) { + zend_hash_move_forward_ex(Z_ARRVAL_P(arr), pos); + + if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void +**)tmp, pos) == SUCCESS) { + convert_to_string_ex(tmp); + data = Z_STRVAL_PP(tmp); + data_len = Z_STRLEN_PP(tmp); + } + } + } + + php_stream_close(stream); + + RETURN_LONG(ret); +} +/* }}} */ + /* {{{ proto array file(string filename [, bool use_include_path]) Read entire file into an array */ Index: ext/standard/file.h === RCS file: /repository/php4/ext/standard/file.h,v retrieving revision 1.70 diff -u -r1.70 file.h --- ext/standard/file.h 28 Sep 2002
[PHP-DEV] [PATCH] New function file_put_contents()
Wez Furlong wrote: It's just that there was a thread about this recently on php-dev, and it's something to get right for new functions - we can fix the old ones as we go :-) The README, the Zend API doc on zend.com and the implementation in zend_API.c all assume an int * for string length in zend_parse_parameters. So I guess that's the right thing to do for now. Please re-submit the fixed version, and I'll probably commit it :-) Ok, I attached the new patch: a) renamed to file_put_contents (can I file minority report? :-)) b) now returns total length written if data is an array c) return value was changed to size_t to match php_stream_write() - Chris ? ext/standard/file_put.c Index: ext/standard/basic_functions.c === RCS file: /repository/php4/ext/standard/basic_functions.c,v retrieving revision 1.528 diff -u -r1.528 basic_functions.c --- ext/standard/basic_functions.c 6 Oct 2002 17:04:10 - 1.528 +++ ext/standard/basic_functions.c 16 Oct 2002 01:48:48 - -625,6 +625,7 PHP_STATIC_FE(tmpfile,php_if_tmpfile, NULL) PHP_FE(file, NULL) PHP_FE(file_get_contents, NULL) + PHP_FE(file_put_contents, + NULL) PHP_FE(stream_select, first_through_third_args_force_ref) PHP_FE(stream_context_create, NULL) PHP_FE(stream_context_set_params, NULL) Index: ext/standard/file.c === RCS file: /repository/php4/ext/standard/file.c,v retrieving revision 1.270 diff -u -r1.270 file.c --- ext/standard/file.c 15 Oct 2002 16:45:26 - 1.270 +++ ext/standard/file.c 16 Oct 2002 01:48:49 - -452,6 +452,79 } /* }}} */ +/* {{{ proto int file_put_contents(string filename, mixed data [, string mode]) + Write an entire string or array to a file and return length written */ +PHP_FUNCTION(file_put_contents) +{ + size_t ret = 0; + char *filename; + int filename_len; + char *data = NULL; + int data_len; + zval *arr = NULL; + char *mode = wb; + int mode_len; + HashPosition pos; + zval **tmp = NULL; + php_stream *stream; + + /* Parse arguments */ + if ((zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() +TSRMLS_CC, ss|s, + filename, +filename_len, data, data_len, mode, mode_len) == FAILURE) + (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, sa|s, + filename, filename_len, arr, mode, mode_len) == +FAILURE)) { + return; + } + + stream = php_stream_open_wrapper(filename, mode, + ENFORCE_SAFE_MODE | REPORT_ERRORS, + NULL); + if (!stream) { + RETURN_FALSE; + } + + if (arr) { + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), pos); + + if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)tmp, +pos) == SUCCESS) { + convert_to_string_ex(tmp); + data = Z_STRVAL_PP(tmp); + data_len = Z_STRLEN_PP(tmp); + } + } + + while (data) { + char *buffer = NULL; + + if (PG(magic_quotes_runtime)) { + buffer = estrndup(data, data_len); + php_stripslashes(buffer, data_len TSRMLS_CC); + } + + ret += php_stream_write(stream, buffer ? buffer : data, data_len); + if (buffer) { + efree(buffer); + } + + data = NULL; + + if (arr) { + zend_hash_move_forward_ex(Z_ARRVAL_P(arr), pos); + + if (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void +**)tmp, pos) == SUCCESS) { + convert_to_string_ex(tmp); + data = Z_STRVAL_PP(tmp); + data_len = Z_STRLEN_PP(tmp); + } + } + } + + php_stream_close(stream); + + RETURN_LONG(ret); +} +/* }}} */ + /* {{{ proto array file(string filename [, bool use_include_path]) Read entire file into an array */ Index: ext/standard/file.h