PHP bindings for the Go programming language (Golang)

Overview

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.

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.

    opened by walker-walks 21
  • 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.
    
    
    opened by RajibBiswas 13
  • 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.

    bug 
    opened by tsabsch 10
  • 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 ?

    enhancement 
    opened by elwinar 4
  • 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.

    opened by sailenicolas 3
  • 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.

    opened by thekid 3
  •  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
    
    opened by vus520 3
  • 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 ?

    opened by alash3al 3
  • 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
    
    opened by taowen 3
  • 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

    opened by deuill 3
  • 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
    
    bug 
    opened by dimaxgl 3
  • 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?

    opened by mitar 1
  • 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.

    opened by dukryung 2
  • 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

    opened by Dexus 1
  • 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 ===
    
    opened by jonnywang 0
  • 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.

    opened by deuill 0
Releases(0.11.0)
  • 0.11.0(Feb 27, 2016)

    Main features/changes are:

    • Support for Go 1.6. #19
    • Partial cleanup of Context/Receiver dependencies. #18

    Several changes to the API were also made, which however should not break existing workflows.

    Source code(tar.gz)
    Source code(zip)
  • 0.10.0(Jan 26, 2016)

    This version is considered stable, and contains the following features and bug-fixes over version 0.9.0:

    • Building against PHP 7 is now supported. A large amount of work was done in order to support both versions 5.x and 7.x at the same time. #12
    • Code was restructured and placed in a single directory, which resulted in the ability for better testing. #13 #14
    • ZTS support was removed, since it was never particularly well-tested or stable, and ZTS has been removed from PHP 7. #12
    • Several bugs and memory leaks fixed. #14 #16

    Code coverage is approximately at 92%, and will be improved in the coming releases. The package does not currently contain benchmarks, and certain features (such as method receiver bindings) will probably be at least somewhat slow, due to heavy use of reflection. YMMV.

    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Jan 2, 2016)

    This is a beta/pre-release version, and may contain bugs or other general suckiness. Features include:

    • Ability to execute PHP script files, as well as standalone strings within seperate execution contexts.
    • Two-way bindings for values. This allows for binding Go values into PHP contexts as global variables, as well as returning PHP values for use in the Go context.
    • Ability to define Go method receivers as PHP classes, with full support for calling attached methods, as well as getting, setting and checking for embedded fields (only for struct method receivers).
    • Provisional support for ZTS-enabled PHP builds.

    Note that this library has only been tested against the PHP 5.6 series. Compatibility with other 5.x versions is unknown, and compatibility with PHP 7 is most definitely not there.

    While the included test-suite covers most common use-cases, code coverage is probably way below 100%. Next versions will include improvements to the test-suite to ensure 100% code coverage, at least for the Go parts.

    Documentation is also somewhat lacking.

    Source code(tar.gz)
    Source code(zip)
Owner
Alex Palaistras
Code Person. Likes tabs for indentation.
Alex Palaistras
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

Spiral Scout 6.9k Nov 27, 2022
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

Vadym Slizov 897 Nov 20, 2022
A compiler for the ReCT programming language written in Golang

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

null 8 Nov 17, 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,

null 4.9k Nov 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

Google 1.8k Nov 27, 2022
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

daniel 3k Nov 28, 2022
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

The V Programming Language 30.9k Nov 23, 2022
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

Maurice Tollmien 241 Nov 3, 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

Konstantin 34 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

TARDIS Go 423 Nov 27, 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/

Robert Krimen 6.9k Nov 22, 2022
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 "

Steve Kemp 289 Nov 23, 2022
Expression evaluation in golang

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

null 555 Nov 19, 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

Helloyi He 13 Nov 11, 2022
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

mattn 1.3k Nov 21, 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

George Lester 2.8k Nov 19, 2022
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

wander 189 Nov 18, 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.

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

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

krhubert 1 Apr 26, 2022