首頁 後端開發 PHP7 一起看看golang呼叫php7詳解及實例

一起看看golang呼叫php7詳解及實例

Jul 18, 2020 pm 05:32 PM
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("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 &#39;hello&#39;;")
  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(&#39;hello&#39;);
  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(&#39;hello&#39;, 4); trigger_error(&#39;sent from golang&#39;, 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[&#39;REQUEST_URI&#39;]);")
  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 (&#39;hello&#39;);")
  if buffer.String() != "" {
    t.FailNow()
  }
  ctx.Eval("fastcgi_finish_request();")
  if buffer.String() != "hello" {
    t.FailNow()
  }
}

實際的作用就是把output提前輸出到 ResposneWriter 裡去,讓呼叫方知道結果。對於目前進程的執行其實是沒有影響的,只是影響了output。

相關學習推薦:PHP7教學

以上是一起看看golang呼叫php7詳解及實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

Rimworld Odyssey溫度指南和Gravtech
1 個月前 By Jack chen
初學者的Rimworld指南:奧德賽
1 個月前 By Jack chen
PHP變量範圍解釋了
4 週前 By 百草
撰寫PHP評論的提示
3 週前 By 百草
在PHP中評論代碼
3 週前 By 百草

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1604
29
PHP教程
1509
276
Golang和C:並發與原始速度 Golang和C:並發與原始速度 Apr 21, 2025 am 12:16 AM

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

Golang vs. Python:利弊 Golang vs. Python:利弊 Apr 21, 2025 am 12:17 AM

Golangisidealforbuildingscalablesystemsduetoitsefficiencyandconcurrency,whilePythonexcelsinquickscriptinganddataanalysisduetoitssimplicityandvastecosystem.Golang'sdesignencouragesclean,readablecodeanditsgoroutinesenableefficientconcurrentoperations,t

Apache連接MySQL數據庫的詳細配置步驟 Apache連接MySQL數據庫的詳細配置步驟 May 16, 2025 pm 10:12 PM

配置Apache連接MySQL數據庫需要以下步驟:1.確保已安裝Apache和MySQL;2.配置Apache支持PHP,通過在httpd.conf或apache2.conf中添加LoadModule和AddHandler指令;3.配置PHP以連接MySQL,在php.ini中啟用mysqli擴展;4.創建並測試連接的PHP文件。通過這些步驟,可以成功實現Apache與MySQL的連接。

配置Apache連接PostgreSQL數據庫的方法 配置Apache連接PostgreSQL數據庫的方法 May 21, 2025 pm 10:48 PM

配置Apache連接PostgreSQL數據庫的步驟包括:1)確保Apache已安裝PHP模塊並在配置文件中啟用;2)在PHP腳本中編寫連接PostgreSQL的代碼;3)使用ORM工具如Doctrine可簡化數據庫操作。通過這些步驟,你可以成功配置Apache與PostgreSQL的連接,並在實際項目中應用這些知識。

將Golang服務與現有Python基礎架構集成的策略 將Golang服務與現有Python基礎架構集成的策略 Jul 02, 2025 pm 04:39 PM

TOIntegrategolangServicesWithExistingPypythoninFrasture,userestapisorgrpcForinter-serviceCommunication,允許GoandGoandPyThonAppStoStoInteractSeamlessSeamLlyThroughlyThroughStandArdArdAdrotized Protoccols.1.usererestapis(ViaFrameWorkslikeSlikeSlikeGiningOandFlaskInpyThon)Orgrococo(wirs Propococo)

減小Docker鏡像體積的最佳實踐和技巧 減小Docker鏡像體積的最佳實踐和技巧 May 19, 2025 pm 08:42 PM

減小Docker鏡像體積的方法包括:1.使用.dockerignore文件排除不必要的文件;2.選擇精簡的基礎鏡像,如alpine版本;3.優化Dockerfile,合併RUN命令並使用--no-cache選項;4.採用多階段構建,只複製最終需要的文件;5.管理依賴版本,定期清理不再使用的依賴。這些方法不僅能減小鏡像體積,還能提高應用的啟動速度和運行效率。

配置Nginx的錯誤頁面顯示自定義內容 配置Nginx的錯誤頁面顯示自定義內容 May 19, 2025 pm 07:30 PM

配置Nginx錯誤頁面以顯示自定義內容可以通過以下步驟實現:1.使用error_page指令定義錯誤頁面,例如error_page404/404.html;2.設置internal指令限制頁面訪問權限,確保只能通過error_page訪問;3.利用重定向和動態生成錯誤頁面,增強錯誤處理功能;4.檢查錯誤頁面文件是否存在,避免出現新的錯誤頁面;5.通過緩存機制優化錯誤頁面的加載速度。這些方法能有效提升用戶體驗和錯誤管理。

讓PhpStorm適配Nginx服務器的詳細設置 讓PhpStorm適配Nginx服務器的詳細設置 May 20, 2025 pm 07:33 PM

配置PhpStorm與Nginx服務器協同工作的步驟包括:1.確保PhpStorm已安裝並配置好PHP解釋器,檢查PHP版本的一致性。 2.設置Deployment配置,使用SFTP連接到Nginx服務器。 3.配置Nginx服務器,確保正確處理PHP文件。 4.在PhpStorm中進行調試,設置PHPRemoteDebug配置。 5.啟用PhpStorm的自動部署功能,同步文件到Nginx服務器。 6.優化Nginx配置,提升性能,並使用PhpStorm的代碼分析工具。

See all articles