当前位置:首页 > PHP教程 > php高级应用 > 列表

golang调用php7详解及实例教程

发布:smiling 来源: PHP粉丝网  添加日期:2018-10-31 23:05:43 浏览: 评论:0 

执行php文件:

  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.   } 

其中 /tmp/index.php 的内容为:

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

返回的value的生命周期所有权是golang程序,所以我们要负责DestroyValue

设置全局变量来传参

  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.   } 

传递进去的参数的生命周期是php控制的,在request shutdown的时候内存会被释放。

PHP 回调 Golang

  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.   } 

PHP 错误日志

  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.   } 

其中 /tmp/php.ini 的内容为

error_reporting= E_ALL

error_log="/tmp/php-error.log"

错误会被输出到 /tmp/php-error.log。直接调用error_log会同时再输出一份到stderr

HTTP 输入输出

  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.   } 

所有的PHP超级全局变量都会被初始化为传递进去的Request的值,包括:

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

echo的内容,http code和http header会被写回到传入的ResponseWriter

fastcgi_finish_request

PHP-FPM 很常用的一个功能是 fastcgi_finish_request ,用于在php里做一些异步完成的事情。这个特殊的全局函数必须支持

  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.   } 

实际的作用就是把output提前输出到 ResposneWriter 里去,让调用方知道结果。对于当前进程的执行其实是没有影响的,只是影响了output。

Tags: golang php7

分享到: