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 相关文章推荐
不用数据库的多用户文件自由上传投票系统(1)
Oct 09 PHP
生成静态页面的PHP类
Nov 25 PHP
在PHP中读取和写入WORD文档的代码
Apr 09 PHP
php更改目录及子目录下所有的文件后缀的代码
Sep 24 PHP
PHP 中检查或过滤IP地址的实现代码
Nov 27 PHP
php5.3 goto函数介绍和示例
Mar 21 PHP
PHP+jquery+ajax实现即时聊天功能实例
Dec 23 PHP
PHP模板引擎Smarty内建函数详解
Apr 11 PHP
PHP面向对象程序设计方法实例详解
Dec 24 PHP
PHP登录验证功能示例【用户名、密码、验证码、数据库、已登陆验证、自动登录和注销登录等】
Feb 25 PHP
PHP全局使用Laravel辅助函数dd
Dec 26 PHP
TP框架实现上传一张图片和批量上传图片的方法分析
Apr 23 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 Document 代码注释规范
2009/04/13 PHP
初识php MVC
2014/09/10 PHP
php实现的读取CSV文件函数示例
2017/02/07 PHP
php实现QQ小程序发送模板消息功能
2019/09/18 PHP
PhpStorm2020.1 安装 debug - Postman 调用的详细教程
2020/08/17 PHP
ExtJS 2.2.1的grid控件在ie6中的显示问题
2009/05/04 Javascript
爆炸式的JS圆形浮动菜单特效代码
2010/03/03 Javascript
关于jQuery的inArray 方法介绍
2011/10/08 Javascript
如何正确使用Nodejs 的 c++ module 链接到 OpenSSL
2014/08/03 NodeJs
JavaScript基础函数整理汇总
2015/01/30 Javascript
javascript实现Table排序的方法
2015/05/15 Javascript
jquery实现可自动收缩的TAB网页选项卡代码
2015/09/06 Javascript
JavaScript SweetAlert插件实现超酷消息警告框
2016/01/28 Javascript
js判断价格,必须为数字且不能为负数的实现方法
2016/10/07 Javascript
Jquery Easyui自定义下拉框组件使用详解(21)
2020/12/31 Javascript
JS中闭包的经典用法小结(2则示例)
2016/12/28 Javascript
vue2.0构建单页应用最佳实战
2017/04/01 Javascript
利用JavaScript如何查询某个值是否数组内
2017/07/30 Javascript
jquery实现图片跟随鼠标的实例
2017/10/17 jQuery
Koa 使用小技巧(小结)
2018/10/22 Javascript
JS实现移动端在线签协议功能
2019/08/22 Javascript
JS如何定义用字符串拼接的变量
2020/07/11 Javascript
编写Python脚本来实现最简单的FTP下载的教程
2015/05/04 Python
基于Django模板中的数字自增(详解)
2017/09/05 Python
Python编程django实现同一个ip十分钟内只能注册一次
2017/11/03 Python
python通过http下载文件的方法详解
2019/07/26 Python
django实现将后台model对象转换成json对象并传递给前端jquery
2020/03/16 Python
python 实现分组求和与分组累加求和代码
2020/05/18 Python
如何使用Pytorch搭建模型
2020/10/26 Python
Oakley官网:运动太阳镜、雪镜和服装
2016/09/30 全球购物
编写一个类体现构造,公有,私有方法,静态,私有变量
2013/08/10 面试题
日期和时间问题
2015/01/04 面试题
公司年会策划方案
2014/05/17 职场文书
汽车技术服务与贸易专业求职信
2014/07/20 职场文书
2015年三万活动总结
2015/03/25 职场文书
死亡诗社观后感
2015/06/05 职场文书