mirror of
https://github.com/deuill/go-php.git
synced 2024-09-21 00:40:45 +00:00
Move NewContext
function to engine
package
Call order is now enforced when using the root `php` package by moving the `NewContext` function in the `engine` package, as a method of the `Engine` method receiver. Further clean-ups have been made to the code as a result of this change.
This commit is contained in:
parent
0523266e32
commit
7ed2c81ec6
@ -92,6 +92,10 @@ void context_bind(engine_context *context, char *name, void *zvalptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int context_write(engine_context *context, const char *str, unsigned int len) {
|
||||
return contextWrite(context->parent, (void *) str, len);
|
||||
}
|
||||
|
||||
void context_destroy(engine_context *context) {
|
||||
php_request_shutdown((void *) 0);
|
||||
|
||||
|
@ -81,15 +81,17 @@ func (c *Context) Eval(script string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Destroy tears down the current execution context along with any values binded
|
||||
// in.
|
||||
// Destroy tears down the current execution context along with any active value
|
||||
// bindings for that context.
|
||||
func (c *Context) Destroy() {
|
||||
for _, v := range c.values {
|
||||
v.Destroy()
|
||||
}
|
||||
|
||||
if c.context != nil {
|
||||
C.context_destroy(c.context)
|
||||
c = nil
|
||||
c.context = nil
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new execution context, passing all script output into w. It
|
||||
@ -107,8 +109,8 @@ func New(w io.Writer) (*Context, error) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
//export context_write
|
||||
func context_write(ctxptr unsafe.Pointer, buffer unsafe.Pointer, length C.uint) C.int {
|
||||
//export contextWrite
|
||||
func contextWrite(ctxptr unsafe.Pointer, buffer unsafe.Pointer, length C.uint) C.int {
|
||||
c := (*Context)(ctxptr)
|
||||
|
||||
written, err := c.writer.Write(C.GoBytes(buffer, C.int(length)))
|
||||
|
@ -11,13 +11,14 @@ typedef struct _engine_context {
|
||||
#endif
|
||||
|
||||
void *parent; // Pointer to parent Go context, used for passing to callbacks.
|
||||
int (*write)(void *parent, void *msg, unsigned int len);
|
||||
int (*write)(struct _engine_context *context, const char *msg, unsigned int len);
|
||||
} engine_context;
|
||||
|
||||
engine_context *context_new(void *parent);
|
||||
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);
|
||||
int context_write(engine_context *context, const char *str, unsigned int len);
|
||||
void context_destroy(engine_context *context);
|
||||
|
||||
#endif
|
@ -26,7 +26,7 @@ const char engine_ini_defaults[] =
|
||||
static int engine_ub_write(const char *str, uint str_length TSRMLS_DC) {
|
||||
engine_context *context = (engine_context *) SG(server_context);
|
||||
|
||||
int written = context->write(context->parent, (void *) str, str_length);
|
||||
int written = context->write(context, str, str_length);
|
||||
if (written != str_length) {
|
||||
php_handle_aborted_connection();
|
||||
}
|
||||
|
@ -16,18 +16,41 @@ import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/deuill/go-php/context"
|
||||
)
|
||||
|
||||
// Engine represents the core PHP engine bindings.
|
||||
type Engine struct {
|
||||
engine *C.struct__php_engine
|
||||
contexts []*context.Context
|
||||
}
|
||||
|
||||
// Destroy shuts down and frees any resources related to the PHP engine
|
||||
// bindings.
|
||||
// NewContext creates a new execution context on which scripts can be executed
|
||||
// and variables can be binded. It corresponds to PHP's RINIT (request init)
|
||||
// phase.
|
||||
func (e *Engine) NewContext(w io.Writer) (*context.Context, error) {
|
||||
c, err := context.New(w)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e.contexts = append(e.contexts, c)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Destroy shuts down and frees any resources related to the PHP engine bindings.
|
||||
func (e *Engine) Destroy() {
|
||||
for _, c := range e.contexts {
|
||||
c.Destroy()
|
||||
}
|
||||
|
||||
if e.engine != nil {
|
||||
C.engine_shutdown(e.engine)
|
||||
e = nil
|
||||
e.engine = nil
|
||||
}
|
||||
}
|
||||
|
||||
// New initializes a PHP engine instance on which contexts can be executed. It
|
||||
@ -38,5 +61,5 @@ func New() (*Engine, error) {
|
||||
return nil, fmt.Errorf("PHP engine failed to initialize")
|
||||
}
|
||||
|
||||
return &Engine{engine: ptr}, nil
|
||||
return &Engine{engine: ptr, contexts: make([]*context.Context, 0)}, nil
|
||||
}
|
||||
|
10
php.go
10
php.go
@ -8,9 +8,6 @@
|
||||
package php
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/deuill/go-php/context"
|
||||
"github.com/deuill/go-php/engine"
|
||||
)
|
||||
|
||||
@ -19,10 +16,3 @@ import (
|
||||
func New() (*engine.Engine, error) {
|
||||
return engine.New()
|
||||
}
|
||||
|
||||
// NewContext creates a new execution context on which scripts can be executed
|
||||
// and variables can be binded. It corresponds to PHP's RINIT (request init
|
||||
// phase and *must* be preceeded by a call to `php.New()`.
|
||||
func NewContext(w io.Writer) (*context.Context, error) {
|
||||
return context.New(w)
|
||||
}
|
||||
|
14
php_test.go
14
php_test.go
@ -49,12 +49,10 @@ func TestNewEngineContext(t *testing.T) {
|
||||
|
||||
defer e.Destroy()
|
||||
|
||||
ctx, err := NewContext(os.Stdout)
|
||||
_, err = e.NewContext(os.Stdout)
|
||||
if err != nil {
|
||||
t.Errorf("NewContext(): %s", err)
|
||||
}
|
||||
|
||||
defer ctx.Destroy()
|
||||
}
|
||||
|
||||
var execTests = []struct {
|
||||
@ -68,10 +66,9 @@ func TestContextExec(t *testing.T) {
|
||||
var w MockWriter
|
||||
|
||||
e, _ := New()
|
||||
ctx, _ := NewContext(&w)
|
||||
ctx, _ := e.NewContext(&w)
|
||||
|
||||
defer e.Destroy()
|
||||
defer ctx.Destroy()
|
||||
|
||||
for _, tt := range execTests {
|
||||
file := path.Join(testDir, tt.file)
|
||||
@ -94,16 +91,16 @@ var evalTests = []struct {
|
||||
}{
|
||||
{"echo 'Hello World';", "Hello World"},
|
||||
{"$i = 10; $d = 20; echo $i + $d;", "30"},
|
||||
{"notascript{}!!*", ""},
|
||||
}
|
||||
|
||||
func TestContextEval(t *testing.T) {
|
||||
var w MockWriter
|
||||
|
||||
e, _ := New()
|
||||
ctx, _ := NewContext(&w)
|
||||
ctx, _ := e.NewContext(&w)
|
||||
|
||||
defer e.Destroy()
|
||||
defer ctx.Destroy()
|
||||
|
||||
for _, tt := range evalTests {
|
||||
if err := ctx.Eval(tt.script); err != nil {
|
||||
@ -135,10 +132,9 @@ func TestContextBind(t *testing.T) {
|
||||
var w MockWriter
|
||||
|
||||
e, _ := New()
|
||||
ctx, _ := NewContext(&w)
|
||||
ctx, _ := e.NewContext(&w)
|
||||
|
||||
defer e.Destroy()
|
||||
defer ctx.Destroy()
|
||||
|
||||
for i, tt := range bindTests {
|
||||
if err := ctx.Bind(strconv.FormatInt(int64(i), 10), tt.value); err != nil {
|
||||
|
@ -36,8 +36,10 @@ func (v *Value) Ptr() unsafe.Pointer {
|
||||
// Destroy removes all active references to the internal PHP value and frees
|
||||
// any resources used.
|
||||
func (v *Value) Destroy() {
|
||||
if v.value != nil {
|
||||
C.value_destroy(v.value)
|
||||
v = nil
|
||||
v.value = nil
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a PHP value representtion of a Go value val. Available bindings
|
||||
|
Loading…
Reference in New Issue
Block a user