golang 调用 php7详解及实例

 更新时间:2017年01月04日 17:14:18   投稿:lqh  
这篇文章主要介绍了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 '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。

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • php面向对象程序设计中self与static的区别分析

    php面向对象程序设计中self与static的区别分析

    这篇文章主要介绍了php面向对象程序设计中self与static的区别,结合实例形式分析了php面向对象程序设计中self与static的功能、以及在继承过程中实现多态的区别,并总结了static静态延迟绑定的原理,需要的朋友可以参考下
    2019-05-05
  • 详解PHP伪静态的实现方法

    详解PHP伪静态的实现方法

    伪静态技术通过将动态URL转换为静态样式,不仅提高了用户体验,也增强了搜索引擎的抓取效率,本文将详细介绍什么是伪静态,以及如何在 PHP中实现伪静态,需要的可以了解下
    2024-11-11
  • php实现Mysql简易操作类

    php实现Mysql简易操作类

    这个PHP实现的mysql的操作类完整版已经使用过了,而这个简化版是经过修改完整版后的简化版,适用在一般的 PHP 应用中,功能上可以实现基本的增删改查的操作,以及打印 MYSQL 错误,自我感觉不错,如果网站应用不是很强大,应用这个 MYSQL 的操作类已经足够了,
    2015-10-10
  • php模拟post提交数据的方法

    php模拟post提交数据的方法

    这篇文章主要介绍了php模拟post提交数据的方法,实例分析了socket方法模拟post提交数据的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Smarty模板学习笔记之Smarty简介

    Smarty模板学习笔记之Smarty简介

    Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。
    2014-05-05
  • PHP定界符的使用及注意事项

    PHP定界符的使用及注意事项

    这篇文章主要给大家介绍了关于PHP定界符的使用及注意事项的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • php+redis实现注册、删除、编辑、分页、登录、关注等功能示例

    php+redis实现注册、删除、编辑、分页、登录、关注等功能示例

    这篇文章主要介绍了php+redis实现注册、删除、编辑、分页、登录、关注等功能,结合实例形式分析了php+redis项目开发中常用的注册,删除,编辑,分页,登录,关注功能相关实现技巧,需要的朋友可以参考下
    2017-02-02
  • JSON在PHP中的应用介绍

    JSON在PHP中的应用介绍

    目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。故整理一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识
    2012-09-09
  • php实现统计目录文件大小的函数

    php实现统计目录文件大小的函数

    本文给大家介绍了使用php实现统计目录文件大小的函数,其主要的思路是通过递归遍历目录中的所有文件从而计算出文件总大小的,有需要的小伙伴可以参考下
    2015-12-12
  • 简单谈谈php中ob_flush和flush的区别

    简单谈谈php中ob_flush和flush的区别

    本文简单的对php中ob_flush和flush进行了对比分析,得出了他们之间的区别,给需要的小伙伴参考下。
    2014-11-11

最新评论