[PATCH] #29416 - ob_include

php.internals

Stuart Dallas

22 years ago
Hi All, This is my first attempt at submitting a patch so please be gentle :). The feature requested in #29416 is something I've wanted to see for a while, so I decided to have a go at adding it. I decided name ob_include described the method by which the function did it's job rather than what it was for. I have implemented it as eval_file_get_output which I feel is a better description of its purpose. The requester suggests require and _once variations but those make little sense to me so I haven't implemented those.
-- Stuart

Jason Garber

22 years ago
Hello Stuart, Patch didn't come through...
-- Best regards, Jason mailto:jason@ionzoft.com Wednesday, September 1, 2004, 3:50:30 PM, you wrote: SD> Hi All, SD> This is my first attempt at submitting a patch so please be gentle :). SD> The feature requested in #29416 is something I've wanted to see for a SD> while, so I decided to have a go at adding it. SD> I decided name ob_include described the method by which the function SD> did it's job rather than what it was for. I have implemented it as SD> eval_file_get_output which I feel is a better description of its SD> purpose. The requester suggests require and _once variations but those SD> make little sense to me so I haven't implemented those.

Stuart Dallas

22 years ago
On Wed, 1 Sep 2004 17:24:33 -0400, Jason Garber <jason@ionzoft.com> wrote:
> Patch didn't come through...
Odd. I BCC'd it to my archive account and that got the attachment. Oh well, something had to go wrong. Hi All, This is my first attempt at submitting a patch so please be gentle :). The feature requested in #29416 is something I've wanted to see for a while, so I decided to have a go at adding it. I decided name ob_include described the method by which the function did it's job rather than what it was for. I have implemented it as eval_file_get_output which I feel is a better description of its purpose. The requester suggests require and _once variations but those make little sense to me so I haven't implemented those. Index: ext/standard/basic_functions.c =================================================================== RCS file: /repository/php-src/ext/standard/basic_functions.c,v retrieving revision 1.543.2.41 diff -u -r1.543.2.41 basic_functions.c --- ext/standard/basic_functions.c 30 Jul 2004 16:52:35 -0000 1.543.2.41 +++ ext/standard/basic_functions.c 1 Sep 2004 19:31:36 -0000 @@ -792,6 +792,7 @@ PHP_FE(ob_get_contents, NULL) PHP_FE(ob_implicit_flush, NULL) PHP_FE(ob_list_handlers, NULL) + PHP_FE(eval_file_get_output, NULL) /* functions from array.c */ PHP_FE(ksort, first_arg_force_ref) Index: main/output.c =================================================================== RCS file: /repository/php-src/main/output.c,v retrieving revision 1.142.2.15 diff -u -r1.142.2.15 output.c --- main/output.c 8 Aug 2003 23:44:04 -0000 1.142.2.15 +++ main/output.c 1 Sep 2004 19:31:36 -0000 @@ -927,6 +927,59 @@ } /* }}} */ +/* {{{ proto bool eval_file_get_output(STRING filename) + Execute a file and return the output. */ +PHP_FUNCTION(eval_file_get_output) +{ + zval *retval=NULL; + zval *inc_filename=NULL; + int argc = ZEND_NUM_ARGS(); + + if (argc != 1) { + ZEND_WRONG_PARAM_COUNT(); + } + + if (zend_parse_parameters(argc TSRMLS_CC, "z", &inc_filename) == FAILURE) { + RETURN_FALSE; + } + + /* create a buffer */ + if (php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC)==FAILURE) { + RETURN_FALSE; + } + + /* compile the file */ + zend_op_array * new_op_array = compile_filename(ZEND_INCLUDE, inc_filename); + + if (new_op_array) { + /* execute the compiled file */ + zend_execute(new_op_array); + + efree(new_op_array); + + /* get the output */ + if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) + RETURN_FALSE; + + /* error checks */ + if (!OG(ob_nesting_level)) { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete."); + RETURN_FALSE; + } + if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) { + php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s.", OG(active_ob_buffer).handler_name); + RETURN_FALSE; + } + /* delete buffer */ + php_end_ob_buffer(0, 0 TSRMLS_CC); + } + else + { + RETURN_FALSE; + } +} +/* }}} */ + /* {{{ int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result) */ static int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result) { Index: main/php_output.h =================================================================== RCS file: /repository/php-src/main/php_output.h,v retrieving revision 1.47.2.1 diff -u -r1.47.2.1 php_output.h --- main/php_output.h 31 Dec 2002 16:26:19 -0000 1.47.2.1 +++ main/php_output.h 1 Sep 2004 19:31:36 -0000 @@ -58,6 +58,7 @@ PHP_FUNCTION(ob_get_status); PHP_FUNCTION(ob_implicit_flush); PHP_FUNCTION(ob_list_handlers); +PHP_FUNCTION(eval_file_get_output); typedef struct _php_ob_buffer { char *buffer;
-- Stuart

Sara Golemon

22 years ago
> This is my first attempt at submitting a patch so please be gentle :). >
*sharpens fangs*
> The feature requested in #29416 is something I've wanted to see for a > while, so I decided to have a go at adding it. >
Considering the triviality of doing it in user space (the bug report shows the four lines it'd take) and the potential for changes in how ZE compiles and executes a new function, I'll throw a -1 vote at it.
> I decided name ob_include described the method by which the function > did it's job rather than what it was for. I have implemented it as > eval_file_get_output which I feel is a better description of its > purpose. The requester suggests require and _once variations but those > make little sense to me so I haven't implemented those. > > Index: ext/standard/basic_functions.c >
There's a considerable amount of work you're not doing here in terms of managing variable scope and dealing with the return value (you'll notice some particular weirdness if you use this from within a function). Take a look at (PHP5)Zend/zend_execute.c::zend_include_or_eval_handler() or (PHP4)Zend/zend_execute.c::execute() (the potion involving `case ZEND_INCLUDE_OR_EVAL:`) -Sara

Stuart Dallas

22 years ago
On Wed, 1 Sep 2004 16:15:59 -0700, Sara Golemon <pollita@php.net> wrote:
> > This is my first attempt at submitting a patch so please be gentle :). > > > *sharpens fangs*
Oops, asked for that!
> > The feature requested in #29416 is something I've wanted to see for a > > while, so I decided to have a go at adding it. > > > Considering the triviality of doing it in user space (the bug report shows > the four lines it'd take) and the potential for changes in how ZE compiles > and executes a new function, I'll throw a -1 vote at it. > > > I decided name ob_include described the method by which the function > > did it's job rather than what it was for. I have implemented it as > > eval_file_get_output which I feel is a better description of its > > purpose. The requester suggests require and _once variations but those > > make little sense to me so I haven't implemented those. > > > > Index: ext/standard/basic_functions.c > > > There's a considerable amount of work you're not doing here in terms of > managing variable scope and dealing with the return value (you'll notice > some particular weirdness if you use this from within a function). > > Take a look at (PHP5)Zend/zend_execute.c::zend_include_or_eval_handler() or > (PHP4)Zend/zend_execute.c::execute() (the potion involving `case > ZEND_INCLUDE_OR_EVAL:`)
To be honest I wasn't really expecting much more. I made a patch that did what I wanted (I don't need it in a function... yet) and thought I'l throw it out there. In case anyone cares I've put it up here: http://dev.stut.net/php/eval_file_get_output.patch I appreciate your comments and those from Derick.
-- Stuart

Derick Rethans

22 years ago
On Wed, 1 Sep 2004, Stuart Dallas wrote:
> On Wed, 1 Sep 2004 17:24:33 -0400, Jason Garber <jason@ionzoft.com> wrote: > > Patch didn't come through... > > Odd. I BCC'd it to my archive account and that got the attachment. Oh > well, something had to go wrong.
The mailinglist strips all attachements != text/plain. And addind patches inline doesn't work as lines will be wrapped. So please put it on a website and provide a link to it. I also think that this patch should not become part of PHP itself as it's something that you can very easily do with 3 function calls. Derick
-- Derick Rethans http://derickrethans.nl | http://ez.no | http://xdebug.org