deuill / go-php

PHP bindings for the Go programming language (Golang)
MIT License
925 stars 105 forks source link

Add Ini() method to change ini values on an engine context #61

Open thekid opened 5 years ago

thekid commented 5 years ago

Example usage:

context, _:= engine.NewContext()
if err != nil {
  fmt.Printf("Could not create a new context: %v", err)
  os.Exit(1)
}
defer context.Destroy()

// Set ini file values here
context.Ini("include_path", ".:/path/to/php/includes")
context.Ini("date.timezone", "Europe/Berlin")

// Now run script using Exec() or Eval().
context.Eval("...");
deuill commented 5 years ago

Would it make more sense to allow for setting the initial INI values for the engine, since these can not be changed in a per-context basis, and allow callers to set per-context values with plain calls to ini_set rather than adding any specific code for these cases?

For example, this code will work fine for any INI values that aren't in this list:

package main

import (
    "fmt"
    "os"

    "github.com/deuill/go-php"
)

func setConfig(ctx *php.Context, name, value string) {
    ctx.Eval("ini_set('" + name + "', '" + value + "');")
}

func getConfig(ctx *php.Context, name string) string {
    val, _ := ctx.Eval("return ini_get('" + name + "');")
    defer val.Destroy()

    return val.String()
}

func main() {
    engine, err := php.New()
    if err != nil {
        fmt.Printf("could not initialize PHP engine: %s", err)
        os.Exit(1)
    }

    defer engine.Destroy()

    context, err := engine.NewContext()
    if err != nil {
        fmt.Printf("could not initialize PHP context: %s", err)
        os.Exit(1)
    }

    defer context.Destroy()
    context.Output = os.Stdout

    fmt.Printf("Before: %s\n", getConfig(context, os.Args[1]))

    setConfig(context, os.Args[1], os.Args[2])
    fmt.Printf("After: %s\n", getConfig(context, os.Args[1]))
}
$ ini-test date.timezone Europe/Berlin
Before: 
After: Europe/Berlin
$ ini-test max_input_time 42
Before: -1
After: -1

IMO asking users to define functions such as getConfig and setConfig (which need some sanitization of input for stray quotes etc) isn't too big an ask, and my assumption is that, in most cases, contexts will be used to run entire scripts, not standalone snippets.

I did some initial work on getting php.New to accept options (either as a map[string]string or a filename), but never finished the code, so I'd be glad to accept any help in that regard, or this PR if the question above doesn't make sense.