站長資訊網
        最全最豐富的資訊網站

        一起看看golang調用php7詳解及實例

        一起看看golang調用php7詳解及實例

        執行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 的內容為

        <?php echo("hellon");

        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的生命周期所有權是golang程序,所以我們要負責DestroyValue

        設置全局變量來傳參

        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()   } }

        傳遞進去的參數的生命周期是php控制的,在request shutdown的時候內存會被釋放。

        PHP 回調 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 的內容為

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

        錯誤會被輸出到 /tmp/php-error.log。直接調用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的內容,http code和http header會被寫回到傳入的ResponseWriter

        fastcgi_finish_request

        PHP-FPM 很常用的一個功能是 fastcgi_finish_request ,用于在php里做一些異步完成的事情。這個特殊的全局函數必須支持

        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 里去,讓調用方知道結果。對于當前進程的執行其實是沒有影響的,只是影響了output。

        相關學習推薦:PHP7教程

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产偷窥熟女高潮精品视频| 久久er国产精品免费观看8| 国产高清国内精品福利99久久| 亚洲色精品vr一区二区三区| 91精品国产综合久久香蕉| 国产精品香港三级国产AV| 亚洲午夜福利精品无码| 国内精品国产成人国产三级| 久久亚洲精品中文字幕三区| 国产精品成人观看视频国产奇米| 亚洲精品色午夜无码专区日韩| 久久精品国产亚洲精品| 国产精品99久久久久久董美香 | 久久国产乱子伦精品免费强| 日韩精品一区二区三区色欲AV | 久久er国产精品免费观看8| 国产福利电影一区二区三区,亚洲国模精品一区 | 亚洲精品国精品久久99热一| 欧美精品亚洲精品日韩专区| 久草热8精品视频在线观看| 国产精品福利区一区二区三区四区| 国产原创精品视频| 国产高清在线精品一区| 91原创国产精品| 99久久免费国产精品热| 国产国产成人精品久久| 欧美精品在线一区二区三区| 2022精品国偷自产免费观看| 成人精品一区二区三区在线观看| 国产成人综合精品一区| 精品国产香蕉伊思人在线在线亚洲一区二区| 国产精品福利在线观看免费不卡 | 一本久久精品一区二区| 中文字幕久精品免费视频| 亚洲精品成人久久久| 伊在人亚洲香蕉精品区麻豆| 亚洲精品成人网站在线观看 | 国产亚洲精品精品国产亚洲综合 | 999久久久无码国产精品 | 亚洲动漫精品无码av天堂| 麻豆亚洲AV永久无码精品久久|