资讯专栏INFORMATION COLUMN

golang 调用 php7

nidaye / 3281人阅读

摘要:回调错误日志其中的内容为错误会被输出到。这个特殊的全局函数必须支持实际的作用就是把提前输出到里去,让调用方知道结果。对于当前进程的执行其实是没有影响的,只是影响了。

使用 https://github.com/taowen/go-php7
基于 https://github.com/deuill/go-php 修改而来,fork缘由(https://github.com/deuill/go-...)

执行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. if err != nil {
  8. fmt.Println(err)
  9. }
  10. defer engine.RequestShutdown(ctx)
  11. err = ctx.Exec("/tmp/index.php")
  12. if err != nil {
  13. fmt.Println(err)
  14. }
  15. }

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

</>复制代码

  1. Eval,返回值
  2. </>复制代码

    1. func Test_eval(t *testing.T) {
    2. engine.Initialize()
    3. ctx := &engine.Context{}
    4. err := engine.RequestStartup(ctx)
    5. if err != nil {
    6. fmt.Println(err)
    7. }
    8. defer engine.RequestShutdown(ctx)
    9. val, err := ctx.Eval("return "hello";")
    10. if err != nil {
    11. fmt.Println(err)
    12. }
    13. defer engine.DestroyValue(val)
    14. if engine.ToString(val) != "hello" {
    15. t.FailNow()
    16. }
    17. }
  3. 返回的value的生命周期所有权是golang程序,所以我们要负责DestroyValue

  4. 设置全局变量来传参
  5. </>复制代码

    1. func Test_argument(t *testing.T) {
    2. engine.Initialize()
    3. ctx := &engine.Context{}
    4. err := engine.RequestStartup(ctx)
    5. if err != nil {
    6. fmt.Println(err)
    7. }
    8. defer engine.RequestShutdown(ctx)
    9. err = ctx.Bind("greeting", "hello")
    10. if err != nil {
    11. fmt.Println(err)
    12. }
    13. val, err := ctx.Eval("return $greeting;")
    14. if err != nil {
    15. fmt.Println(err)
    16. }
    17. defer engine.DestroyValue(val)
    18. if engine.ToString(val) != "hello" {
    19. t.FailNow()
    20. }
    21. }
  6. 传递进去的参数的生命周期是php控制的,在request shutdown的时候内存会被释放。

  7. PHP 回调 Golang
  8. </>复制代码

    1. type greetingProvider struct {
    2. greeting string
    3. }
    4. func (provider *greetingProvider) GetGreeting() string {
    5. return provider.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. if err != nil {
    17. fmt.Println(err)
    18. }
    19. defer engine.RequestShutdown(ctx)
    20. err = engine.Define("GreetingProvider", newGreetingProvider)
    21. if err != nil {
    22. fmt.Println(err)
    23. }
    24. val, err := ctx.Eval(`
    25. $greetingProvider = new GreetingProvider("hello");
    26. return $greetingProvider->GetGreeting();`)
    27. if err != nil {
    28. fmt.Println(err)
    29. }
    30. defer engine.DestroyValue(val)
    31. if engine.ToString(val) != "hello" {
    32. t.FailNow()
    33. }
    34. }
  9. PHP 错误日志
  10. </>复制代码

    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. if err != 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. if err != nil {
    14. fmt.Println(err)
    15. }
    16. }
  11. 其中 /tmp/php.ini 的内容为

  12. </>复制代码

    1. error_reporting = E_ALL
    2. error_log = "/tmp/php-error.log"
  13. 错误会被输出到 /tmp/php-error.log。直接调用error_log会同时再输出一份到stderr

  14. HTTP 输入输出
  15. </>复制代码

    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. if err != nil {
    10. fmt.Println(err)
    11. }
    12. defer engine.RequestShutdown(ctx)
    13. _, err = ctx.Eval("echo($_SERVER["REQUEST_URI"]);")
    14. if err != nil {
    15. fmt.Println(err)
    16. }
    17. body, err := ioutil.ReadAll(recorder.Result().Body)
    18. if err != nil {
    19. fmt.Println(err)
    20. }
    21. if string(body) != "/hello" {
    22. t.FailNow()
    23. }
    24. }
  16. 所有的PHP超级全局变量都会被初始化为传递进去的Request的值,包括

  17. </>复制代码

    1. $_SERVER
    2. $_GET
    3. $_POST
    4. $_FILE
    5. $_COOKIE
    6. $_ENV
  18. echo的内容,http code和http header会被写回到传入的ResponseWriter

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

  21. </>复制代码

    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. if err != nil {
    9. fmt.Println(err)
    10. }
    11. defer engine.RequestShutdown(ctx)
    12. ctx.Eval("ob_start(); echo ("hello");")
    13. if buffer.String() != "" {
    14. t.FailNow()
    15. }
    16. ctx.Eval("fastcgi_finish_request();")
    17. if buffer.String() != "hello" {
    18. t.FailNow()
    19. }
    20. }
  22. 实际的作用就是把output提前输出到 ResposneWriter 里去,让调用方知道结果。对于当前进程的执行其实是没有影响的,只是影响了output。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22078.html

相关文章

  • Swoole协程之旅-前篇

    摘要:协程完全有用户态程序控制,所以也被成为用户态的线程。目前支持协程的语言有很多,例如等。协程之旅前篇结束,下一篇文章我们将深入分析原生协程部分的实现。 写在最前   Swoole协程经历了几个里程碑,我们需要在前进的道路上不断总结与回顾自己的发展历程,正所谓温故而知新,本系列文章将分为协程之旅前、中、后三篇。 前篇主要介绍协程的概念和Swoole几个版本协程实现的主要方案技术; 中篇主...

    terasum 评论0 收藏0
  • Dockerfile 与 Compose 环境搭建学习笔记(一)

    摘要:的主要作用是自己根据基础镜像,重新定制镜像,而不是直接从官方仓库拿现成的使用。以接下来要构建的环境来说明下,下面我将要搭建一个的开发环境,需要进行配合。它的主要作用是持久化数据,避免容器销毁后内部数据丢失暴露到宿主机的端口。 以前一直使用 Vagrant 作为自己的开发环境,并且在上家公司也推行大家采用 Vagrant 作为开发环境,保障公司使用的是同一套开发环境。随着docker的流...

    TZLLOG 评论0 收藏0
  • Dockerfile 与 Compose 环境搭建学习笔记(一)

    摘要:的主要作用是自己根据基础镜像,重新定制镜像,而不是直接从官方仓库拿现成的使用。以接下来要构建的环境来说明下,下面我将要搭建一个的开发环境,需要进行配合。它的主要作用是持久化数据,避免容器销毁后内部数据丢失暴露到宿主机的端口。 以前一直使用 Vagrant 作为自己的开发环境,并且在上家公司也推行大家采用 Vagrant 作为开发环境,保障公司使用的是同一套开发环境。随着docker的流...

    ityouknow 评论0 收藏0
  • PHP新手开发者的路线建议

    摘要:年开发者应该熟练使用,并且知道版本更新内容。对开发和运维人员来说,最希望的就是一次性创建或配置,可以在任意地方正常运行。是标准规范,是开发的实践标准。对开发者来说语言推荐和,全栈的选择非常多,推荐热门的 前言 在前天(2018-08-02)已经发布了PHP 7.3.0.beta1 Released 如果你还没有使用 PHP7 ,那真的很遗憾。2018年PHP开发者应该熟练使用 PHP7...

    klinson 评论0 收藏0

发表评论

0条评论

nidaye

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<