執(zhí)行php文件
func Test_exec(t *testing.T) {  engine.Initialize()  ctx := &engine.Context{    Output: os.Stdout,  }  err := engine.RequestStartup(ctx)  if err != nil {    fmt.Println(err)  }  defer engine.RequestShutdown(ctx)  err = ctx.Exec("/tmp/index.php")  if err != nil {    fmt.Println(err)  }}其中 /tmp/index.php 的內(nèi)容為
<?phpecho("hello/n");Eval,返回值
func Test_eval(t *testing.T) {  engine.Initialize()  ctx := &engine.Context{}  err := engine.RequestStartup(ctx)  if err != nil {    fmt.Println(err)  }  defer engine.RequestShutdown(ctx)  val, err := ctx.Eval("return 'hello';")  if err != nil {    fmt.Println(err)  }  defer engine.DestroyValue(val)  if engine.ToString(val) != "hello" {    t.FailNow()  }}返回的value的生命周期所有權(quán)是golang/196412.html">golang/71081.html">golang程序,所以我們要負(fù)責(zé)DestroyValue
設(shè)置全局變量來傳參
func Test_argument(t *testing.T) {  engine.Initialize()  ctx := &engine.Context{}  err := engine.RequestStartup(ctx)  if err != nil {    fmt.Println(err)  }  defer engine.RequestShutdown(ctx)  err = ctx.Bind("greeting", "hello")  if err != nil {    fmt.Println(err)  }  val, err := ctx.Eval("return $greeting;")  if err != nil {    fmt.Println(err)  }  defer engine.DestroyValue(val)  if engine.ToString(val) != "hello" {    t.FailNow()  }}傳遞進去的參數(shù)的生命周期是php控制的,在request shutdown的時候內(nèi)存會被釋放。
PHP 回調(diào) Golang
type greetingProvider struct {  greeting string}func (provider *greetingProvider) GetGreeting() string {  return provider.greeting}func newGreetingProvider(args []interface{}) interface{} {  return &greetingProvider{    greeting: args[0].(string),  }}func Test_callback(t *testing.T) {  engine.Initialize()  ctx := &engine.Context{}  err := engine.RequestStartup(ctx)  if err != nil {    fmt.Println(err)  }  defer engine.RequestShutdown(ctx)  err = engine.Define("GreetingProvider", newGreetingProvider)  if err != nil {    fmt.Println(err)  }  val, err := ctx.Eval(`  $greetingProvider = new GreetingProvider('hello');  return $greetingProvider->GetGreeting();`)  if err != nil {    fmt.Println(err)  }  defer engine.DestroyValue(val)  if engine.ToString(val) != "hello" {    t.FailNow()  }}PHP 錯誤日志
func Test_log(t *testing.T) {  engine.PHP_INI_PATH_OVERRIDE = "/tmp/php.ini"  engine.Initialize()  ctx := &engine.Context{    Log: os.Stderr,  }  err := engine.RequestStartup(ctx)  if err != nil {    fmt.Println(err)  }  defer engine.RequestShutdown(ctx)  _, err = ctx.Eval("error_log('hello', 4); trigger_error('sent from golang', E_USER_ERROR);")  if err != nil {    fmt.Println(err)  }}其中 /tmp/php.ini 的內(nèi)容為
error_reporting = E_ALLerror_log = "/tmp/php-error.log"
錯誤會被輸出到 /tmp/php-error.log。直接調(diào)用error_log會同時再輸出一份到stderr
HTTP 輸入輸出
func Test_http(t *testing.T) {  engine.Initialize()  recorder := httptest.NewRecorder()  ctx := &engine.Context{    Request: httptest.NewRequest("GET", "/hello", nil),    ResponseWriter: recorder,  }  err := engine.RequestStartup(ctx)  if err != nil {    fmt.Println(err)  }  defer engine.RequestShutdown(ctx)  _, err = ctx.Eval("echo($_SERVER['REQUEST_URI']);")  if err != nil {    fmt.Println(err)  }  body, err := ioutil.ReadAll(recorder.Result().Body)  if err != nil {    fmt.Println(err)  }  if string(body) != "/hello" {    t.FailNow()  }}所有的PHP超級全局變量都會被初始化為傳遞進去的Request的值,包括
$_SERVER$_GET$_POST$_FILE$_COOKIE$_ENV
echo的內(nèi)容,http code和http header會被寫回到傳入的ResponseWriter
fastcgi_finish_request
PHP-FPM 很常用的一個功能是 fastcgi_finish_request ,用于在php里做一些異步完成的事情。這個特殊的全局函數(shù)必須支持
func Test_fastcgi_finish_reqeust(t *testing.T) {  engine.Initialize()  buffer := &bytes.Buffer{}  ctx := &engine.Context{    Output: buffer,  }  err := engine.RequestStartup(ctx)  if err != nil {    fmt.Println(err)  }  defer engine.RequestShutdown(ctx)  ctx.Eval("ob_start(); echo ('hello');")  if buffer.String() != "" {    t.FailNow()  }  ctx.Eval("fastcgi_finish_request();")  if buffer.String() != "hello" {    t.FailNow()  }}實際的作用就是把output提前輸出到 ResposneWriter 里去,讓調(diào)用方知道結(jié)果。對于當(dāng)前進程的執(zhí)行其實是沒有影響的,只是影響了output。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
新聞熱點
疑難解答
圖片精選