golang调用php7详解实例教程及php回调

2018-11-0513:33:18后端程序开发Comments5,498 views字数 3790阅读模式

执行php文件:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  1. func Test_exec(t *testing.T) {
  2.   engine.Initialize()
  3.   ctx := &engine.Context{
  4.     Output: os.Stdout,
  5.   }
  6.   err := engine.RequestStartup(ctx)
  7.   iferr != nil {
  8.     fmt.Println(err)
  9.   }
  10.   defer engine.RequestShutdown(ctx)
  11.   err = ctx.Exec("/tmp/index.php")
  12.   iferr != nil {
  13.     fmt.Println(err)
  14.   }
  15. }

其中 /tmp/index.php 的内容为:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  1. echo("hello\n");
  2. Eval,返回值
  3. func Test_eval(t *testing.T) {
  4.   engine.Initialize()
  5.   ctx := &engine.Context{}
  6.   err := engine.RequestStartup(ctx)
  7.   iferr != nil {
  8.     fmt.Println(err)
  9.   }
  10.   defer engine.RequestShutdown(ctx)
  11.   val, err := ctx.Eval("return 'hello';")
  12.   iferr != nil {
  13.     fmt.Println(err)
  14.   }
  15.   defer engine.DestroyValue(val)
  16.   ifengine.ToString(val) !="hello"{
  17.     t.FailNow()
  18.   }
  19. }

返回的value的生命周期所有权是golang程序,所以我们要负责DestroyValue文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

设置全局变量来传参文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  1. func Test_argument(t *testing.T) {
  2.   engine.Initialize()
  3.   ctx := &engine.Context{}
  4.   err := engine.RequestStartup(ctx)
  5.   iferr != nil {
  6.     fmt.Println(err)
  7.   }
  8.   defer engine.RequestShutdown(ctx)
  9.   err = ctx.Bind("greeting","hello")
  10.   iferr != nil {
  11.     fmt.Println(err)
  12.   }
  13.   val, err := ctx.Eval("return $greeting;")
  14.   iferr != nil {
  15.     fmt.Println(err)
  16.   }
  17.   defer engine.DestroyValue(val)
  18.   ifengine.ToString(val) !="hello"{
  19.     t.FailNow()
  20.   }
  21. }

传递进去的参数的生命周期是php控制的,在request shutdown的时候内存会被释放。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

PHP 回调 Golang文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  1. type greetingProvider struct {
  2.   greeting string
  3. }
  4. func (provider *greetingProvider) GetGreeting() string {
  5.   returnprovider.greeting
  6. }
  7. func newGreetingProvider(args []interface{})interface{} {
  8.   return&greetingProvider{
  9.     greeting: args[0].(string),
  10.   }
  11. }
  12. func Test_callback(t *testing.T) {
  13.   engine.Initialize()
  14.   ctx := &engine.Context{}
  15.   err := engine.RequestStartup(ctx)
  16.   iferr != nil {
  17.     fmt.Println(err)
  18.   }
  19.   defer engine.RequestShutdown(ctx)
  20.   err = engine.Define("GreetingProvider", newGreetingProvider)
  21.   iferr != nil {
  22.     fmt.Println(err)
  23.   }
  24.   val, err := ctx.Eval(`
  25.   $greetingProvider=newGreetingProvider('hello');
  26.   return$greetingProvider->GetGreeting();`)
  27.   iferr != nil {
  28.     fmt.Println(err)
  29.   }
  30.   defer engine.DestroyValue(val)
  31.   ifengine.ToString(val) !="hello"{
  32.     t.FailNow()
  33.   }
  34. }

PHP 错误日志文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  1. func Test_log(t *testing.T) {
  2.   engine.PHP_INI_PATH_OVERRIDE ="/tmp/php.ini"
  3.   engine.Initialize()
  4.   ctx := &engine.Context{
  5.     Log: os.Stderr,
  6.   }
  7.   err := engine.RequestStartup(ctx)
  8.   iferr != nil {
  9.     fmt.Println(err)
  10.   }
  11.   defer engine.RequestShutdown(ctx)
  12.   _, err = ctx.Eval("error_log('hello', 4); trigger_error('sent from golang', E_USER_ERROR);")
  13.   iferr != nil {
  14.     fmt.Println(err)
  15.   }
  16. }

其中 /tmp/php.ini 的内容为文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

error_reporting= E_ALL文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

error_log="/tmp/php-error.log"文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

错误会被输出到 /tmp/php-error.log。直接调用error_log会同时再输出一份到stderr文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

HTTP 输入输出文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  1. func Test_http(t *testing.T) {
  2.   engine.Initialize()
  3.   recorder := httptest.NewRecorder()
  4.   ctx := &engine.Context{
  5.     Request: httptest.NewRequest("GET","/hello", nil),
  6.     ResponseWriter: recorder,
  7.   }
  8.   err := engine.RequestStartup(ctx)
  9.   iferr != nil {
  10.     fmt.Println(err)
  11.   }
  12.   defer engine.RequestShutdown(ctx)
  13.   _, err = ctx.Eval("echo($_SERVER['REQUEST_URI']);")
  14.   iferr != nil {
  15.     fmt.Println(err)
  16.   }
  17.   body, err := ioutil.ReadAll(recorder.Result().Body)
  18.   iferr != nil {
  19.     fmt.Println(err)
  20.   }
  21.   ifstring(body) !="/hello"{
  22.     t.FailNow()
  23.   }
  24. }

所有的PHP超级全局变量都会被初始化为传递进去的Request的值,包括:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  1. $_SERVER
  2. $_GET
  3. $_POST
  4. $_FILE
  5. $_COOKIE
  6. $_ENV

echo的内容,http code和http header会被写回到传入的ResponseWriter文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

fastcgi_finish_request文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

PHP-FPM 很常用的一个功能是 fastcgi_finish_request ,用于在php里做一些异步完成的事情。这个特殊的全局函数必须支持文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  1. func Test_fastcgi_finish_reqeust(t *testing.T) {
  2.   engine.Initialize()
  3.   buffer := &bytes.Buffer{}
  4.   ctx := &engine.Context{
  5.     Output: buffer,
  6.   }
  7.   err := engine.RequestStartup(ctx)
  8.   iferr != nil {
  9.     fmt.Println(err)
  10.   }
  11.   defer engine.RequestShutdown(ctx)
  12.   ctx.Eval("ob_start(); echo ('hello');")
  13.   ifbuffer.String() !=""{
  14.     t.FailNow()
  15.   }
  16.   ctx.Eval("fastcgi_finish_request();")
  17.   ifbuffer.String() !="hello"{
  18.     t.FailNow()
  19.   }
  20. }

实际的作用就是把output提前输出到 ResposneWriter 里去,让调用方知道结果。对于当前进程的执行其实是没有影响的,只是影响了output。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7661.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/bc/7661.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定