PHP,是一种被广泛应用的开源通用脚本语言,尤其适用于 Web 开发并可嵌入 HTML 中去,而Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易.在此我想给PHPer提供另外一种方式来学习go,这样不但学习了新语言go,同时对php的内部机制也会有深入的了解。
首先,我们来生成PHP的动态库,这是学习的基础环境之一,只要在平时我们编译PHP的时候,加上如下参数即可
--enable-embed
这样就会在php的安装目录(即–prefix的目录,默认应该在/usr/local/php)下的lib目录看到一个libphp5.so或libphp7.so文件,具体那个文件取决于你编译的php版本。
生成动态库后,为了方便程序引用动态库,我们需要修改下库文件的配置。/etc/ld.so.conf 此文件记录了编译时使用的动态库的路径,也就是加载so库的路径,默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件,我们执行如下命令即可。
echo "/usr/local/php/lib" > /etc/ld.so.conf.d/php.conf ldconfig
ldconfig这个程序它的作用是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用,因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新的搜索路径,需要运行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,即使修改了配置文件可能也会找不到刚安装的库。
2:GO环境搭建
go的环境没有什么特殊之处,只要下载相应版本,配置好PATH和GOROOT环境变量即可,在此不做过多说明.
3:C中嵌入php
- PHP_EMBED_START_BLOCK 表示PHP嵌入代码块开始
- PHP_EMBED_END_BLOCK 表示PHP嵌入代码块结束
- zend_eval_string 执行变量内的PHP代码
- php_execute_script 执行PHP脚本文件
3.1执行php代码变量
demo1.c代码如下
#include "sapi/embed/php_embed.h" int main(int argc, char * argv[]){ PHP_EMBED_START_BLOCK(argc,argv); char * script = " echo \"Hello World!\n\";"; zend_eval_string(script, NULL,"Simple Hello World App" TSRMLS_CC); PHP_EMBED_END_BLOCK(); return 0; }
编译文件
gcc -I /usr/local/php/include/php/ -I /usr/local/php/include/php/main/ -I /usr/local/php/include/php/Zend/ -I /usr/local/php/include/php/TSRM/ -lphp7 -o demo1 demo1.c
gcc 是编译器,一般linux系统都自带了,不用安装。-I参数指定包含头文件的搜索路径,要不然找不到php的头文件,-l指定库文件,-o指定编译文件和目标文件。
运行目标文件
./demo1
输出如下内容
Hello World!
3.2执行php代码文件
demo2.c代码如下
#include <stdio.h> #include <sapi/embed/php_embed.h> int main(int argc, char *argv[]) { zend_file_handle script; if ( argc <= 1 ) { fprintf(stderr, "Usage: %s <filename.php> <arguments>\n", argv[0]); return -1; } script.type = ZEND_HANDLE_FP; script.filename = argv[1]; script.opened_path = NULL; script.free_filename = 0; if ( !(script.handle.fp = fopen(script.filename, "rb")) ) { fprintf(stderr, "Unable to open: %s\n", argv[1]); return -1; } argc --; argv ++; PHP_EMBED_START_BLOCK(argc, argv) php_execute_script(&script TSRMLS_CC); PHP_EMBED_END_BLOCK() return 0; }
编译文件
gcc -I /usr/local/php/include/php/ -I /usr/local/php/include/php/main/ -I /usr/local/php/include/php/Zend/ -I /usr/local/php/include/php/TSRM/ -lphp7 -o demo2 demo2.c
运行目标文件
./demo2 test.php
test.php文件代码可以任意,比如”<?php echo ‘Hello World’;“,最终后输出”Hello World”。
4:CGO
在很多场景下,在Go的程序中需要调用c函数或者是用c编写的库那么该如何调用呢?Go可是更好的C语言啊,当然提供了和c语言交互的功能,称为Cgo,Cgo封装了#cgo伪c文法,参数CFLAGS用来传入编译选项,LDFLAGS来传入链接选项。这个用来调用非c标准的第三方c库。
示例代码如下,大家一看即懂。
package main /* #include <stdio.h> void hi() { printf("hello world!\n"); } */ import "C" //这里可看作封装的伪包C, 这条语句要紧挨着上面的注释块,不可在它俩之间间隔空行! func main() { C.hi() } 5:GO和PHP愉快的玩耍 package main /* #cgo CFLAGS: -I/usr/local/php5/include/php #cgo CFLAGS: -I/usr/local/php5/include/php/main #cgo CFLAGS: -I/usr/local/php5/include/php/TSRM #cgo CFLAGS: -I/usr/local/php5/include/php/Zend #cgo LDFLAGS: -lphp5 -L/usr/local/php5/lib/ #include "sapi/embed/php_embed.h" void eval_str() { int argc = 1; char * argv[] = {"test"}; PHP_EMBED_START_BLOCK(argc,argv); char * script = " echo \"Hello World!\n\";"; zend_eval_string(script, NULL,"Simple Hello World App" TSRMLS_CC); PHP_EMBED_END_BLOCK(); } */ import "C" func main() { C.eval_str() }
这篇我们就可以让go与php愉快的玩耍了,是不是很好玩呀?
这篇文章只是抛砖引玉,更多玩耍方式及其应用还需要大家的研究,在此列举以下资料供大家参考
1:PHP混合Go协程并发
2:golang调用php7
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/6931/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料