golang 调用 php7详解及实例


Posted in PHP onJanuary 04, 2017

执行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 相关文章推荐
4.与数据库的连接
Oct 09 PHP
使用VisualStudio开发php的图文设置方法
Aug 21 PHP
PHP警告Cannot use a scalar value as an array的解决方法
Jan 11 PHP
PHP sprintf() 函数的应用(定义和用法)
Jun 29 PHP
解析mysql left( right ) join使用on与where筛选的差异
Jun 18 PHP
php中将一段数据存到一个txt文件中并显示其内容
Aug 15 PHP
php实现压缩多个CSS与JS文件的方法
Nov 11 PHP
PHP批量查询WordPress留言者E-mail地址实现方法
Feb 15 PHP
php基于socket实现SMTP发送邮件的方法
Mar 05 PHP
php+ajax实现无刷新动态加载数据技术
Apr 28 PHP
分析php://output和php://stdout的区别
May 06 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
Mar 24 PHP
PHP 与 UTF-8 的最佳实践详细介绍
Jan 04 #PHP
详解Yii2 定制表单输入字段的标签和样式
Jan 04 #PHP
PHPExcel导出2003和2007的excel文档功能示例
Jan 04 #PHP
CI框架实现优化文件上传及多文件上传的方法
Jan 04 #PHP
PHP搭建大文件切割分块上传功能示例
Jan 04 #PHP
php实现的简单中文验证码功能示例
Jan 03 #PHP
php与c 实现按行读取文件实例代码
Jan 03 #PHP
You might like
PHP实现文件安全下载
2006/10/09 PHP
使用php判断浏览器的类型和语言的函数代码
2013/02/28 PHP
WordPress中使主题支持小工具以及添加插件启用函数
2015/12/22 PHP
PHP之图片上传类实例代码(加了缩略图)
2016/06/30 PHP
PHP实现简单的计算器
2020/08/28 PHP
js 对象是否存在判断
2009/07/15 Javascript
jQuery选择头像并实时显示的代码
2010/06/27 Javascript
JS控制阿拉伯数字转为中文大写示例代码
2013/09/04 Javascript
jquery实现浮动的侧栏实例
2015/06/25 Javascript
JavaScript如何调试有哪些建议和技巧附五款有用的调试工具
2015/10/28 Javascript
javascript弹性运动效果简单实现方法
2016/01/08 Javascript
详解JavaScript中|单竖杠运算符的使用方法
2016/05/23 Javascript
详解Vue路由开启keep-alive时的注意点
2017/06/20 Javascript
JS实现图片手风琴效果
2020/04/17 Javascript
jQuery选择器之子元素选择器详解
2017/09/18 jQuery
js核心基础之闭包的应用实例分析
2019/05/11 Javascript
vue elementui el-form rules动态验证的实例代码详解
2019/05/23 Javascript
详解用async/await来处理异步
2019/08/28 Javascript
解决nuxt页面中mounted、created、watch执行两遍的问题
2020/11/05 Javascript
[47:20]DAC2018 4.4 淘汰赛 Optic vs Mineski 第一场
2018/04/05 DOTA
Python数据分析中Groupby用法之通过字典或Series进行分组的实例
2017/12/08 Python
Python语言实现百度语音识别API的使用实例
2017/12/13 Python
使用Scrapy爬取动态数据
2018/10/21 Python
Python3使用Matplotlib 绘制精美的数学函数图形
2019/04/11 Python
python算法题 链表反转详解
2019/07/02 Python
python3实现往mysql中插入datetime类型的数据
2020/03/02 Python
HTML5+lufylegend实现游戏中的卷轴
2016/02/29 HTML / CSS
英国最大的化装舞会服装网站:Fancydress.com
2017/08/15 全球购物
Aosom西班牙:家具在线商店
2020/06/11 全球购物
人事专员的职责
2014/02/26 职场文书
党政领导班子民主生活会整改措施
2014/09/18 职场文书
2016年中秋祝酒词
2015/11/26 职场文书
Python数据可视化之绘制柱状图和条形图
2021/05/25 Python
使用python+pygame开发消消乐游戏附完整源码
2021/06/10 Python
Python matplotlib 利用随机函数生成变化图形
2022/04/26 Python
Android Gradle 插件自定义Plugin实现注意事项
2022/06/16 Java/Android