GO和PHP可以在一起愉快的玩耍了

PHP,是一种被广泛应用的开源通用脚本语言,尤其适用于 Web 开发并可嵌入 HTML 中去,而Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易.在此我想给PHPer提供另外一种方式来学习go,这样不但学习了新语言go,同时对php的内部机制也会有深入的了解。

1: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:Cphp

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

此条目发表在 好文推荐, 网站开发 分类目录,贴了 标签。将固定链接加入收藏夹。

发表评论