PHP bindings for the Go programming language (Golang)

PHP bindings for Go

API Documentation MIT License

This package implements support for executing PHP scripts, exporting Go variables for use in PHP contexts, attaching Go method receivers as PHP classes and returning PHP variables for use in Go contexts.

Both PHP 5.x and PHP 7.x series are supported.

Building

Building this package requires that you have PHP installed as a library. For most Linux systems, this can usually be found in the php-embed package, or variations thereof.

Once the PHP library is available, the bindings can be compiled with go build and are go get-able.

Note: Building against PHP 5.x requires that the php5 tag is provided, i.e.:

go get -tags php5 github.com/deuill/go-php

This is due to the fact that PHP 7.x is the default build target.

Status

Executing PHP script files as well as inline strings is supported and stable.

Binding Go values as PHP variables is allowed for most base types, and PHP values returned from eval'd strings can be converted and used in Go contexts as interface{} values.

It is possible to attach Go method receivers as PHP classes, with full support for calling expored methods, as well as getting and setting embedded fields (for struct-type method receivers).

Caveats

Be aware that, by default, PHP is not designed to be used in multithreaded environments (which severely restricts the use of these bindings with Goroutines) if not built with ZTS support. However, ZTS support has seen major refactoring between PHP 5 and PHP 7, and as such is currently unsupported by this package.

Currently, it is recommended to either sync use of seperate Contexts between Goroutines, or share a single Context among all running Goroutines.

Roadmap

Currently, the package lacks in several respects:

  • ZTS/multi-threading support. This basically means using Go-PHP in Goroutines is severely limited.
  • Documentation and examples, both package-level and external.
  • Performance. There's no reason to believe Go-PHP suffers from any serious performance issues in particular, but adding benchmarks, especially compared against vanilla PHP, might help.
  • Your feature request here?

These items will be tackled in order of significance (which may not be the order shown above).

Usage

Basic

Executing a script is simple:

package main

import (
    php "github.com/deuill/go-php"
    "os"
)

func main() {
    engine, _ := php.New()

    context, _ := engine.NewContext()
    context.Output = os.Stdout

    context.Exec("index.php")
    engine.Destroy()
}

The above will execute script file index.php located in the current folder and will write any output to the io.Writer assigned to Context.Output (in this case, the standard output).

Binding and returning variables

The following example demonstrates binding a Go variable to the running PHP context, and returning a PHP variable for use in Go:

package main

import (
    "fmt"
    php "github.com/deuill/go-php"
)

func main() {
    engine, _ := php.New()
    context, _ := engine.NewContext()

    var str string = "Hello"
    context.Bind("var", str)

    val, _ := context.Eval("return $var.' World';")
    fmt.Printf("%s", val.Interface())
    // Prints 'Hello World' back to the user.

    engine.Destroy()
}

A string value "Hello" is attached using Context.Bind under a name var (available in PHP as $var). A script is executed inline using Context.Eval, combinding the attached value with a PHP string and returning it to the user.

Finally, the value is returned as an interface{} using Value.Interface() (one could also use Value.String(), though the both are equivalent in this case).

License

All code in this repository is covered by the terms of the MIT License, the full text of which can be found in the LICENSE file.

Owner
Alex Palaistras
Code Person. Likes tabs for indentation.
Alex Palaistras
Comments
  • Installation Error on OS X 10.11.6

    Installation Error on OS X 10.11.6

    Hi, @deuill . I'm making a portable server to help my graphic designers friends on FrontEnd development with golang/echo framework. https://github.com/walker-walks/quick_serv They said it would be useful if the server executes php files. so I was trying to call and execute php from go in a way I don't have License problem..

    So I'm trying to use go-php library but I'm having the same issue with some people when I'm doing go get.

    engine/context.go:11:11: error: 'main/php.h' file not found with <angled> include; use "quotes" instead
     #include <main/php.h>
              ^~~~~~~~~~~~
              "main/php.h
    

    I don't know if it's correct but, I downloaded the php source file and put the php-7/main into go-php/engine/main and passed this part and them appeared another error which is.

    In file included from engine/context.go:11:
    ./main/php.h:35:10: fatal error: 'zend.h' file not found
    #include "zend.h"
             ^
    

    I moved all the files were in php-7/Zend to go-php/engine/main. and Now I have the issue below that I can't understand.

    In file included from engine/context.go:11:
    In file included from ./main/php.h:35:
    In file included from ./main/zend.h:31:
    In file included from ./main/zend_types.h:27:
    ./main/zend_portability.h:48:11: fatal error: 'zend_config.h' file not found
    # include <zend_config.h>
    

    I wold be very happy if you could give me any suggestions. thanks.

  • Installation Error

    Installation Error

    # go get -tags php5 github.com/deuill/go-php
    # github.com/deuill/go-php/engine
    work/src/github.com/deuill/go-php/engine/context.go:11:23: fatal error: main/php.h: No such file or directory
     // #include <main/php.h>
                           ^
    compilation terminated.
    
    
  • unknown type name 'uint32_t'

    unknown type name 'uint32_t'

    When I try to go-get go-php, I'm receiving the following error:

    workspace/src/github.com/deuill/go-php/engine/context.c: In function ‘context_eval’:
    workspace/src/github.com/deuill/go-php/engine/context.c:71:2: error: unknown type name ‘uint32_t’
      uint32_t compiler_options = CG(compiler_options);
      ^
    

    My gcc version is 4.8.5. I'm not familiar with C, so I'd be glad if you could help me to solve my issue.

  • Need a way to support mulitple include paths

    Need a way to support mulitple include paths

    I'm currently working in a docker to compile and run tests, and it happens that the docker container for golang is based upon Debian Jessie.

    On Jessie (and probably many other distributions), the correct include path for main/php.h is /usr/include/php5, which is not the value given in the various CGO headers.

    Any though on how to make this more portable ?

  • PHP 8.1.3

    PHP 8.1.3

    Hi, I'm trying to make it work in PHP8.1.3, but I find myself with a problem I can't really fix because I don't really understand Go. You can read the error here: https://gitlab.com/sailenicolas/gophp/-/jobs/2191492914

    Apparently the problematic function is: receiver_define.
    Basically this line: https://gitlab.com/sailenicolas/gophp/-/blob/php8/src/receiver.c#L236

    The call to zend_register_internal_class causes a panic. If you don't mind, is there any way to make it work? I'm asking if you can point me in the right direction. The function calls are as follows: TestEngineDefine -> e.Define -> C.receiver_define -> zend_register_internal_class() and there it throws PANIC. I already checked other SAPI modules, php-src and PHP7 internals, I can't find the problem from the PHP8 side, so I think the problem is in the Go tests (I am only assuming).

    The code is mostly the same...

    Sorry for my english.

  • Fix

    Fix "warning: initialization from incompatible pointer type"

    This pull request fixes the following error:

    engine.c:97:2: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
      engine_log_message,          // Log Message
      ^~~~~~~~~~~~~~~~~~
    engine.c:97:2: note: (near initialization for ‘engine_module.log_message’)
    

    The extra parameter syslog_type_int was introduced in PHP 7.1, see this commit.

  •  error: unknown type name 'zend_string'

    error: unknown type name 'zend_string'

    $ go get github.com/deuill/go-php
    # github.com/deuill/go-php
    In file included from ../../../deuill/go-php/engine.go:14:
    In file included from include/receiver.h:15:
    include/php7/_receiver.h:12:34: error: unknown type name 'zend_string'; did you mean 'zend_stream'?
    static int _receiver_method_call(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS);
                                     ^~~~~~~~~~~
                                     zend_stream
    /usr/include/php/Zend/zend_stream.h:60:3: note: 'zend_stream' declared here
    } zend_stream;
      ^
    In file included from ../../../deuill/go-php/engine.go:14:
    In file included from include/receiver.h:15:
    include/php7/_receiver.h:13:66: error: unknown type name 'zend_string'; did you mean 'zend_stream'?
    static zend_function *_receiver_method_get(zend_object **object, zend_string *name, const zval *key);
                                                                     ^~~~~~~~~~~
                                                                     zend_stream
    /usr/include/php/Zend/zend_stream.h:60:3: note: 'zend_stream' declared here
    } zend_stream;
      ^
    2 errors generated.
    
    
    $ which php
    /usr/local/bin/php
    
    $ which phpize
    /usr/bin/phpize
    
    $ which php-config
    /usr/local/bin/php-config
    
    $ uname -a
    Darwin bogon 16.5.0 Darwin Kernel Version 16.5.0: Fri Mar  3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64
    
  • ubuntu 16.04 PHP7

    ubuntu 16.04 PHP7 "fatal error: main/php.h: No such file or directory"

    sorry, this may be a wrong place ? i've ubuntu 16.04, the php include path is located at /usr/include/php/20151012, is there any trick that will solve that issue using any ENV var ?

  • gc_possible_root: Assertion `(ref)->gc.u.v.type == 7 || (ref)->gc.u.v.type == 8' failed.

    gc_possible_root: Assertion `(ref)->gc.u.v.type == 7 || (ref)->gc.u.v.type == 8' failed.

    package php
    
    import (
        "testing"
        "github.com/stretchr/testify/assert"
        "github.com/deuill/go-php/engine"
    )
    
    func Test_map_value(t *testing.T) {
        should := assert.New(t)
        theEngine, err := engine.New()
        should.Nil(err)
        defer theEngine.Destroy()
        context, err := theEngine.NewContext()
        should.Nil(err)
        defer context.Destroy()
        context.Bind("hello", map[string]interface{}{})
    }
    
        for _, v := range c.values {
            v.Destroy()
        }
        c.values = nil
    
        C.context_destroy(c.context)
        c.context = nil
    

    when the values destroyed, then the context destroy will trigger gc_possible_root assertion error. Found in php-7.0.12

    Complete error message

    php.test: /home/xiaoju/disf-php/php-src/php-7.0.12/Zend/zend_gc.c:226: gc_possible_root: Assertion `(ref)->gc.u.v.type == 7 || (ref)->gc.u.v.type == 8' failed.
    SIGABRT: abort
    PC=0x7f051472e428 m=0
    signal arrived during cgo execution
    
  • php7: Allow for additional `php7.debian` build tag

    php7: Allow for additional `php7.debian` build tag

    The additional php7.debian build tag allows Go-PHP to be built against PHP7 on Debian (and Debian-derived, such as Ubuntu) distributions. This additional build tag is required due to the non-standard include and library file locations.

    Relates-To: #26

  • Doesn't work in Go 1.6

    Doesn't work in Go 1.6

    I try to compile with Go 1.6rc1. Here is compiler output:

    /usr/local/go/bin/go run -tags php7 /home/me/gocode/src/github.com/hello/world/src/embed_php7/main.go
    panic: runtime error: cgo argument has Go pointer to Go pointer
    
    goroutine 1 [running]:
    github.com/deuill/go-php/engine._cgoCheckPointer0(0x69aec0, 0xc820012500, 0x0, 0x0, 0x0, 0x0)
        ??:0 +0x4d
    github.com/deuill/go-php/engine.NewContext(0xc8200c0000, 0x0, 0x0)
        /home/me/gocode/src/github.com/deuill/go-php/engine/context.go:45 +0x152
    github.com/deuill/go-php/engine.(*Engine).NewContext(0xc820016f60, 0x0, 0x0, 0x0)
        /home/me/gocode/src/github.com/deuill/go-php/engine/engine.go:53 +0x2e
    main.main()
        /home/me/gocode/src/github.com/hello/world/src/embed_php7/main.go:10 +0x36
    exit status 2
    
  • Status of the project?

    Status of the project?

    There does not seem to be any updates since 2018? Is it still maintained?

    There is now PHP 8 out. PHP 7 achieved end of life. PHP 5 is probably not something which needs to be supported anymore. Would removing support for PHP 5 allow code cleanup and easier support for ZTS?

  • Compilation Error

    Compilation Error

    go:11:23: fatal error: main/php.h: No such file or directory // #include <main/php.h> ^ compilation terminated.

    OS -> windows 10.

    i don't know how to fix it.

  • would this package profit from this?

    would this package profit from this?

    Hello @deuill,

    would this package profit from https://github.com/basvanbeek/embed2-sapi ?

    Its not php7 but i think it would make it easy to use for concurrency php... with some trweaks.

    Regards, Josef

  • warning

    warning

    engine.c:43:10: warning: enumeration values 'SAPI_HEADER_DELETE_ALL' and 'SAPI_HEADER_SET_STATUS' not handled in switch [-Wswitch]
    engine.c:43:10: note: add missing switch cases
    # github.com/deuill/go-php
    receiver.c:79:1: warning: control reaches end of non-void function [-Wreturn-type]
    # github.com/deuill/go-php
    value.c:121:47: warning: incompatible pointer types passing 'unsigned long *' to parameter of type 'zend_ulong *' (aka 'unsigned long long *') [-Wincompatible-pointer-types]
    src/github.com/deuill/go-php/include/php7/_value.h:14:87: note: passing argument to parameter 'num_index' here
    /private/var/folders/w6/qc4d3cs57tb1zmnq81d91b_40000gn/T/___go_build_embed_go_darwin #gosetup
    Hello World[Mon Oct  8 14:54:30 2018]  Script:  '-'
    Zend/zend_string.h(122) :  Freeing 0x0000000009a01820 (40 bytes), script=-
    Last leak repeated 1 time
    === Total 2 memory leaks detected ===
    
  • Fix error logging with default engine configuration

    Fix error logging with default engine configuration

    By default, configuration values for log_errors and display_errors depend on how PHP has been configured, and need to be made consistent in order for functionality to conform to expectations.

    Additionally, the list of errors handled has been expanded to E_ALL instead of whatever the default value is.

High-performance PHP application server, load-balancer and process manager written in Golang
High-performance PHP application server, load-balancer and process manager written in Golang

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Dec 30, 2022
PHP parser written in Go
PHP parser written in Go

PHP Parser written in Go This project uses goyacc and ragel tools to create PHP parser. It parses source code into AST. It can be used to write static

Dec 25, 2022
A compiler for the ReCT programming language written in Golang

ReCT-Go-Compiler A compiler for the ReCT programming language written in Golang

Nov 30, 2022
Elvish = Expressive Programming Language + Versatile Interactive Shell

Elvish: Expressive Programming Language + Versatile Interactive Shell Elvish is an expressive programming language and a versatile interactive shell,

Dec 25, 2022
Starlark in Go: the Starlark configuration language, implemented in Go

Starlark in Go This is the home of the Starlark in Go project. Starlark in Go is an interpreter for Starlark, implemented in Go. Starlark was formerly

Jan 2, 2023
A fast script language for Go
A fast script language for Go

The Tengo Language Tengo is a small, dynamic, fast, secure script language for Go. Tengo is fast and secure because it's compiled/executed as bytecode

Dec 30, 2022
Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. https://vlang.io
Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. https://vlang.io

The V Programming Language vlang.io | Docs | Changelog | Speed | Contributing & compiler design Key Features of V Simplicity: the language can be lear

Jan 4, 2023
Compiler for a small language into x86-64 Assembly

Compiler This project is a small compiler, that compiles my own little language into X86-64 Assembly. It then uses yasm and ld to assemble and link in

Dec 13, 2022
Transpiling fortran code to golang code

f4go Example of use > # Install golang > # Compile f4go > go get -u github.com/Konstantin8105/f4go > cd $GOPATH/src/github.com/Konstantin8105/f4go > g

Sep 26, 2022
Golang->Haxe->CPP/CSharp/Java/JavaScript transpiler

TARDIS Go -> Haxe transpiler Haxe -> C++ / C# / Java / JavaScript Project status: a non-working curiosity, development currently on-ice The advent of

Dec 30, 2022
A JavaScript interpreter in Go (golang)

otto -- import "github.com/robertkrimen/otto" Package otto is a JavaScript parser and interpreter written natively in Go. http://godoc.org/github.com/

Jan 2, 2023
A BASIC interpreter written in golang.
A BASIC interpreter written in golang.

05 PRINT "Index" 10 PRINT "GOBASIC!" 20 PRINT "Limitations" Arrays Line Numbers IF Statement DATA / READ Statements Builtin Functions Types 30 PRINT "

Dec 24, 2022
Expression evaluation in golang
Expression evaluation in golang

Gval Gval (Go eVALuate) provides support for evaluating arbitrary expressions, in particular Go-like expressions. Evaluate Gval can evaluate expressio

Dec 27, 2022
golang AST matcher

goastch (GO AST matCH) Introduction Inspired by ast matcher. There are four different basic categories of matchers: Node Matchers: Matchers that match

Nov 11, 2022
Scriptable interpreter written in golang
Scriptable interpreter written in golang

Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor

Dec 23, 2022
Arbitrary expression evaluation for golang

govaluate Provides support for evaluating arbitrary C-like artithmetic/string expressions. Why can't you just write these expressions in code? Sometim

Jan 2, 2023
hotbuild - a cross platform hot compilation tool for golang
hotbuild - a cross platform hot compilation tool for golang

hotbuild A cross platform hot compilation tool By monitoring the modification of the project directory file, the recompilation and running are automat

Dec 12, 2022
The golang tool of the zig compiler automatically compiles different targets according to the GOOS GOARCH environment variable. You need to install zig.

The golang tool of the zig compiler automatically compiles different targets according to the GOOS GOARCH environment variable. You need to install zig.

Nov 18, 2022
Tgo - Test Helpers for Standard Golang Packages

Test Helpers for Standard Golang Packages see example_test.go go test --- FAIL:

Apr 26, 2022