#include #include #include #include #include #include "_cgo_export.h" #include "zend_execute.h" static int custom_output_handler(void **handler_context, php_output_context *output_context) { if (output_context->op & PHP_OUTPUT_HANDLER_START || output_context->op == PHP_OUTPUT_HANDLER_WRITE) { // Append the written data to the output buffer writeOut(output_context->in.data, output_context->in.used); } return SUCCESS; } // Capture exceptions into a zend_string static void handle_exception() { zval tmp, rv; zend_object *ex = EG(exception); ZVAL_OBJ(&tmp, ex); // Get the exception getMessage method zend_call_method_with_0_params(ex, ex->ce, NULL, "getmessage", &rv); printf("%d", Z_TYPE(rv)); if (Z_TYPE(rv) == IS_STRING) { zend_string *s = Z_STR(rv); writeErr(ZSTR_VAL(s), ZSTR_LEN(s)); zval_ptr_dtor(&rv); } else { writeErr(ZEND_STRL("unknown exception")); } } void exec(zend_op_array *code, zval* retval) { php_output_handler *handler; handler = php_output_handler_create_internal( ZEND_STRL("gophp-output-handler"), custom_output_handler, 512, PHP_OUTPUT_HANDLER_STDFLAGS); if (!handler || php_output_handler_start(handler) != SUCCESS) { php_error_docref(NULL, E_WARNING, "Failed to start output buffering"); return; } ZVAL_UNDEF(retval); zend_execute(code, retval); if (EG(exception)) { handle_exception(); EG(exception) = NULL; // Clear the exception } // End output buffering php_output_end(); }