当前位置:首页 > 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.   } 
  15. } 

其中 /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.   } 
  20. } 

返回的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.   } 
  21. } 

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

PHP 回调 Golang

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

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

其中 /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.   } 
  24. } 

所有的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.   } 
  20. } 

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

Tags: golang php7

分享到: