1
0
mirror of https://github.com/deuill/go-php.git synced 2024-09-21 08:50:45 +00:00

Added support for script evaluation from string

This commit is contained in:
Alex Palaistras 2015-10-04 19:55:45 +01:00
parent 6da50279b2
commit 9e046ba882
4 changed files with 64 additions and 4 deletions

View File

@ -43,7 +43,7 @@ engine_context *context_new(void *parent) {
void context_exec(engine_context *context, char *filename) { void context_exec(engine_context *context, char *filename) {
#ifdef ZTS #ifdef ZTS
void ***tsrm_ls = *context->ptsrm_ls; void ***tsrm_ls = *(context->ptsrm_ls);
#endif #endif
// Attempt to execute script file. // Attempt to execute script file.
@ -62,6 +62,20 @@ void context_exec(engine_context *context, char *filename) {
return NULL; return NULL;
} }
void context_eval(engine_context *context, char *script) {
#ifdef ZTS
void ***tsrm_ls = *(context->ptsrm_ls);
#endif
// Attempt to evaluate inline script.
zend_first_try {
zend_eval_string(script, NULL, "" TSRMLS_CC);
} zend_end_try();
errno = 0;
return NULL;
}
void context_bind(engine_context *context, char *name, void *zvalptr) { void context_bind(engine_context *context, char *name, void *zvalptr) {
zval *value = (zval *) zvalptr; zval *value = (zval *) zvalptr;

View File

@ -56,10 +56,10 @@ func (c *Context) Bind(name string, val interface{}) error {
// context, and returns an error, if any. Output produced by the script is // context, and returns an error, if any. Output produced by the script is
// written to the context's pre-defined io.Writer instance. // written to the context's pre-defined io.Writer instance.
func (c *Context) Exec(filename string) error { func (c *Context) Exec(filename string) error {
name := C.CString(filename) f := C.CString(filename)
defer C.free(unsafe.Pointer(name)) defer C.free(unsafe.Pointer(f))
_, err := C.context_exec(c.context, name) _, err := C.context_exec(c.context, f)
if err != nil { if err != nil {
return fmt.Errorf("Error executing script '%s' in context", filename) return fmt.Errorf("Error executing script '%s' in context", filename)
} }
@ -67,6 +67,20 @@ func (c *Context) Exec(filename string) error {
return nil return nil
} }
// Eval executes the PHP script contained in script, and follows the same
// semantics as the Exec function.
func (c *Context) Eval(script string) error {
s := C.CString(script)
defer C.free(unsafe.Pointer(s))
_, err := C.context_eval(c.context, s)
if err != nil {
return fmt.Errorf("Error executing script '%s' in context", script)
}
return nil
}
// Write copies data in the context's pre-defined io.Writer instance. It is // Write copies data in the context's pre-defined io.Writer instance. It is
// largely used internally, but is part of the context's public API due to // largely used internally, but is part of the context's public API due to
// architectural contstraints. // architectural contstraints.

View File

@ -15,6 +15,7 @@ typedef struct _engine_context {
engine_context *context_new(void *parent); engine_context *context_new(void *parent);
void context_exec(engine_context *context, char *filename); void context_exec(engine_context *context, char *filename);
void context_eval(engine_context *context, char *script);
void context_bind(engine_context *context, char *name, void *zvalptr); void context_bind(engine_context *context, char *name, void *zvalptr);
void context_destroy(engine_context *context); void context_destroy(engine_context *context);

View File

@ -88,6 +88,37 @@ func TestContextExec(t *testing.T) {
} }
} }
var evalTests = []struct {
script string // Script to run
expected string // Expected output
}{
{"echo 'Hello World';", "Hello World"},
{"$i = 10; $d = 20; echo $i + $d;", "30"},
}
func TestContextEval(t *testing.T) {
var w MockWriter
e, _ := New()
ctx, _ := NewContext(&w)
defer e.Destroy()
defer ctx.Destroy()
for _, tt := range evalTests {
if err := ctx.Eval(tt.script); err != nil {
t.Errorf("Context.Eval(%s): %s", tt.script, err)
}
actual := w.String()
w.Reset()
if actual != tt.expected {
t.Errorf("Context.Eval(%s): expected '%s', actual '%s'", tt.script, tt.expected, actual)
}
}
}
var bindTests = []struct { var bindTests = []struct {
value interface{} // Value to bind value interface{} // Value to bind
expected string // Serialized form of value expected string // Serialized form of value