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 相关文章推荐
PHP - Html Transfer Code
Oct 09 PHP
php SQL防注入代码集合
Apr 25 PHP
PHP 导出数据到淘宝助手CSV的方法分享
Feb 27 PHP
php生成缩略图示例代码分享(使用gd库实现)
Jan 20 PHP
PHP中字符安全过滤函数使用小结
Feb 25 PHP
修改WordPress中文章编辑器的样式的方法详解
Dec 15 PHP
讲解WordPress中用于获取评论模板和搜索表单的PHP函数
Dec 28 PHP
3种方法轻松处理php开发中emoji表情的问题
Jul 18 PHP
php实现批量修改文件名称的方法
Jul 23 PHP
PHP二进制与字符串之间的相互转换教程
Oct 14 PHP
php5.3后静态绑定用法详解
Nov 11 PHP
PHP实现图片防盗链破解操作示例【解决图片防盗链问题/反向代理】
May 29 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
乐信RP2100的电路分析和打磨
2021/03/02 无线电
PHP批量删除、清除UTF-8文件BOM头的代码实例
2014/04/14 PHP
PHP语法自动检查的Vim插件
2014/08/11 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
2018/02/06 PHP
PHP中的访问修饰符简单比较
2019/02/02 PHP
JavaScript 布尔操作符解析  &amp;&amp; || !
2012/08/10 Javascript
javascript时区函数介绍
2012/09/14 Javascript
js弹出层包含flash 不能关闭隐藏的2种处理方法
2013/06/17 Javascript
js中的replace方法使用介绍
2013/10/28 Javascript
探究JavaScript函数式编程的乐趣
2015/12/14 Javascript
js代码实现下拉菜单【推荐】
2016/12/15 Javascript
AngularJS使用angular.bootstrap完成模块手动加载的方法分析
2017/01/19 Javascript
js面向对象编程总结
2017/02/16 Javascript
详解Angular2 关于*ngFor 嵌套循环
2017/05/22 Javascript
详解cordova打包成webapp的方法
2017/10/18 Javascript
移动端效果之IndexList详解
2017/10/20 Javascript
vue技术分享之你可能不知道的7个秘密
2018/04/09 Javascript
详解使用element-ui table组件的筛选功能的一个小坑
2018/11/02 Javascript
原生JavaScript实现日历功能代码实例(无引用Jq)
2019/09/23 Javascript
小程序实现横向滑动日历效果
2019/10/21 Javascript
Vue 打包体积优化方案小结
2020/05/20 Javascript
JS实现手风琴特效
2020/11/08 Javascript
JavaScript实现网页tab栏效果制作
2020/11/20 Javascript
Python 读取指定文件夹下的所有图像方法
2018/04/27 Python
详解flask入门模板引擎
2018/07/18 Python
python提取log文件内容并画出图表
2019/07/08 Python
python GUI库图形界面开发之PyQt5简单绘图板实例与代码分析
2020/03/08 Python
美国中小型企业领先的办公家具供应商:Office Designs
2016/11/26 全球购物
Lookfantastic香港官网:英国知名美妆购物网站
2018/06/19 全球购物
French Connection官网:女装、男装及家居用品
2019/03/18 全球购物
测试工程师职业规划书
2014/02/06 职场文书
法人授权委托书
2014/04/03 职场文书
三八妇女节超市活动方案
2014/08/18 职场文书
个人融资协议书范本两则
2014/10/15 职场文书
2014年民警工作总结
2014/11/25 职场文书
2014年体育教师工作总结
2014/12/03 职场文书