mirror of
https://github.com/deuill/go-php.git
synced 2024-09-21 08:50: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;
|
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) {
|
void context_destroy(engine_context *context) {
|
||||||
php_request_shutdown((void *) 0);
|
php_request_shutdown((void *) 0);
|
||||||
|
|
||||||
|
@ -81,15 +81,17 @@ func (c *Context) Eval(script string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy tears down the current execution context along with any values binded
|
// Destroy tears down the current execution context along with any active value
|
||||||
// in.
|
// bindings for that context.
|
||||||
func (c *Context) Destroy() {
|
func (c *Context) Destroy() {
|
||||||
for _, v := range c.values {
|
for _, v := range c.values {
|
||||||
v.Destroy()
|
v.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
C.context_destroy(c.context)
|
if c.context != nil {
|
||||||
c = nil
|
C.context_destroy(c.context)
|
||||||
|
c.context = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new execution context, passing all script output into w. It
|
// 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
|
return ctx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//export context_write
|
//export contextWrite
|
||||||
func context_write(ctxptr unsafe.Pointer, buffer unsafe.Pointer, length C.uint) C.int {
|
func contextWrite(ctxptr unsafe.Pointer, buffer unsafe.Pointer, length C.uint) C.int {
|
||||||
c := (*Context)(ctxptr)
|
c := (*Context)(ctxptr)
|
||||||
|
|
||||||
written, err := c.writer.Write(C.GoBytes(buffer, C.int(length)))
|
written, err := c.writer.Write(C.GoBytes(buffer, C.int(length)))
|
||||||
|
@ -11,13 +11,14 @@ typedef struct _engine_context {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *parent; // Pointer to parent Go context, used for passing to callbacks.
|
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;
|
||||||
|
|
||||||
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_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);
|
||||||
|
int context_write(engine_context *context, const char *str, unsigned int len);
|
||||||
void context_destroy(engine_context *context);
|
void context_destroy(engine_context *context);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -23,10 +23,10 @@ const char engine_ini_defaults[] =
|
|||||||
"max_input_time = -1\n\0"
|
"max_input_time = -1\n\0"
|
||||||
;
|
;
|
||||||
|
|
||||||
static int engine_ub_write(const char *str, uint str_length TSRMLS_DC) {
|
static int engine_ub_write(const char *str, uint str_length TSRMLS_DC) {
|
||||||
engine_context *context = (engine_context *) SG(server_context);
|
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) {
|
if (written != str_length) {
|
||||||
php_handle_aborted_connection();
|
php_handle_aborted_connection();
|
||||||
}
|
}
|
||||||
|
@ -16,18 +16,41 @@ import "C"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/deuill/go-php/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Engine represents the core PHP engine bindings.
|
// Engine represents the core PHP engine bindings.
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
engine *C.struct__php_engine
|
engine *C.struct__php_engine
|
||||||
|
contexts []*context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy shuts down and frees any resources related to the PHP engine
|
// NewContext creates a new execution context on which scripts can be executed
|
||||||
// bindings.
|
// 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() {
|
func (e *Engine) Destroy() {
|
||||||
C.engine_shutdown(e.engine)
|
for _, c := range e.contexts {
|
||||||
e = nil
|
c.Destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.engine != nil {
|
||||||
|
C.engine_shutdown(e.engine)
|
||||||
|
e.engine = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New initializes a PHP engine instance on which contexts can be executed. It
|
// 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 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
|
package php
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/deuill/go-php/context"
|
|
||||||
"github.com/deuill/go-php/engine"
|
"github.com/deuill/go-php/engine"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,10 +16,3 @@ import (
|
|||||||
func New() (*engine.Engine, error) {
|
func New() (*engine.Engine, error) {
|
||||||
return engine.New()
|
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()
|
defer e.Destroy()
|
||||||
|
|
||||||
ctx, err := NewContext(os.Stdout)
|
_, err = e.NewContext(os.Stdout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("NewContext(): %s", err)
|
t.Errorf("NewContext(): %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer ctx.Destroy()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var execTests = []struct {
|
var execTests = []struct {
|
||||||
@ -68,10 +66,9 @@ func TestContextExec(t *testing.T) {
|
|||||||
var w MockWriter
|
var w MockWriter
|
||||||
|
|
||||||
e, _ := New()
|
e, _ := New()
|
||||||
ctx, _ := NewContext(&w)
|
ctx, _ := e.NewContext(&w)
|
||||||
|
|
||||||
defer e.Destroy()
|
defer e.Destroy()
|
||||||
defer ctx.Destroy()
|
|
||||||
|
|
||||||
for _, tt := range execTests {
|
for _, tt := range execTests {
|
||||||
file := path.Join(testDir, tt.file)
|
file := path.Join(testDir, tt.file)
|
||||||
@ -94,16 +91,16 @@ var evalTests = []struct {
|
|||||||
}{
|
}{
|
||||||
{"echo 'Hello World';", "Hello World"},
|
{"echo 'Hello World';", "Hello World"},
|
||||||
{"$i = 10; $d = 20; echo $i + $d;", "30"},
|
{"$i = 10; $d = 20; echo $i + $d;", "30"},
|
||||||
|
{"notascript{}!!*", ""},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContextEval(t *testing.T) {
|
func TestContextEval(t *testing.T) {
|
||||||
var w MockWriter
|
var w MockWriter
|
||||||
|
|
||||||
e, _ := New()
|
e, _ := New()
|
||||||
ctx, _ := NewContext(&w)
|
ctx, _ := e.NewContext(&w)
|
||||||
|
|
||||||
defer e.Destroy()
|
defer e.Destroy()
|
||||||
defer ctx.Destroy()
|
|
||||||
|
|
||||||
for _, tt := range evalTests {
|
for _, tt := range evalTests {
|
||||||
if err := ctx.Eval(tt.script); err != nil {
|
if err := ctx.Eval(tt.script); err != nil {
|
||||||
@ -135,10 +132,9 @@ func TestContextBind(t *testing.T) {
|
|||||||
var w MockWriter
|
var w MockWriter
|
||||||
|
|
||||||
e, _ := New()
|
e, _ := New()
|
||||||
ctx, _ := NewContext(&w)
|
ctx, _ := e.NewContext(&w)
|
||||||
|
|
||||||
defer e.Destroy()
|
defer e.Destroy()
|
||||||
defer ctx.Destroy()
|
|
||||||
|
|
||||||
for i, tt := range bindTests {
|
for i, tt := range bindTests {
|
||||||
if err := ctx.Bind(strconv.FormatInt(int64(i), 10), tt.value); err != nil {
|
if err := ctx.Bind(strconv.FormatInt(int64(i), 10), tt.value); err != nil {
|
||||||
|
@ -36,20 +36,22 @@ func (v *Value) Ptr() unsafe.Pointer {
|
|||||||
// Destroy removes all active references to the internal PHP value and frees
|
// Destroy removes all active references to the internal PHP value and frees
|
||||||
// any resources used.
|
// any resources used.
|
||||||
func (v *Value) Destroy() {
|
func (v *Value) Destroy() {
|
||||||
C.value_destroy(v.value)
|
if v.value != nil {
|
||||||
v = nil
|
C.value_destroy(v.value)
|
||||||
|
v.value = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a PHP value representtion of a Go value val. Available bindings
|
// New creates a PHP value representtion of a Go value val. Available bindings
|
||||||
// for Go to PHP types are:
|
// for Go to PHP types are:
|
||||||
//
|
//
|
||||||
// int -> integer
|
// int -> integer
|
||||||
// float64 -> double
|
// float64 -> double
|
||||||
// bool -> boolean
|
// bool -> boolean
|
||||||
// string -> string
|
// string -> string
|
||||||
// slice -> indexed array
|
// slice -> indexed array
|
||||||
// map[int|string] -> associative array
|
// map[int|string] -> associative array
|
||||||
// struct -> object
|
// struct -> object
|
||||||
//
|
//
|
||||||
// Bindings for functions and method receivers to PHP functions and classes are
|
// Bindings for functions and method receivers to PHP functions and classes are
|
||||||
// only available in the engine scope, and must be predeclared before context
|
// only available in the engine scope, and must be predeclared before context
|
||||||
|
Loading…
Reference in New Issue
Block a user