frankenphp package - github.com/dunglas/frankenphp - Go Packages (original) (raw)
Package frankenphp embeds PHP in Go projects and provides a SAPI for net/http.
This is the core of the FrankenPHP app server, and can be used in any Go program.
func NewRequestWithContext(r *http.Request, opts ...RequestOption) (*http.Request, error)
func PHPAssociativeArray[T any](arr AssociativeArray[T]) unsafe.Pointer
func ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) error
- func WithContext(ctx context.Context) Option
- func WithLogger(l *slog.Logger) Option
- func WithMaxThreads(maxThreads int) Option
- func WithMaxWaitTime(maxWaitTime time.Duration) Option
- func WithMetrics(m Metrics) Option
- func WithNumThreads(numThreads int) Option
- func WithPhpIni(overrides map[string]string) Option
- func WithWorkers(name, fileName string, num int, options ...WorkerOption) Option
- func (m *PrometheusMetrics) DequeuedRequest()
- func (m *PrometheusMetrics) DequeuedWorkerRequest(name string)
- func (m *PrometheusMetrics) QueuedRequest()
- func (m *PrometheusMetrics) QueuedWorkerRequest(name string)
- func (m *PrometheusMetrics) ReadyWorker(name string)
- func (m *PrometheusMetrics) Shutdown()
- func (m *PrometheusMetrics) StartRequest()
- func (m *PrometheusMetrics) StartWorker(name string)
- func (m *PrometheusMetrics) StartWorkerRequest(name string)
- func (m *PrometheusMetrics) StopRequest()
- func (m *PrometheusMetrics) StopWorker(name string, reason StopReason)
- func (m *PrometheusMetrics) StopWorkerRequest(name string, duration time.Duration)
- func (m *PrometheusMetrics) TotalThreads(num int)
- func (m *PrometheusMetrics) TotalWorkers(string, int)
- func WithMercureHub(hub *mercure.Hub) RequestOption
- func WithOriginalRequest(r *http.Request) RequestOption
- func WithRequestDocumentRoot(documentRoot string, resolveSymlink bool) RequestOption
- func WithRequestEnv(env map[string]string) RequestOption
- func WithRequestLogger(logger *slog.Logger) RequestOption
- func WithRequestPreparedEnv(env PreparedEnv) RequestOption
- func WithRequestResolvedDocumentRoot(documentRoot string) RequestOption
- func WithRequestSplitPath(splitPath []string) RequestOption
- func WithWorkerName(name string) RequestOption
- func WithWorkerEnv(env map[string]string) WorkerOption
- func WithWorkerMaxFailures(maxFailures int) WorkerOption
- func WithWorkerMaxThreads(num int) WorkerOption
- func WithWorkerOnReady(f func(int)) WorkerOption
- func WithWorkerOnServerShutdown(f func()) WorkerOption
- func WithWorkerOnServerStartup(f func()) WorkerOption
- func WithWorkerOnShutdown(f func(int)) WorkerOption
- func WithWorkerRequestOptions(options ...RequestOption) WorkerOption
- func WithWorkerWatchMode(watch []string) WorkerOption
var ( ErrInvalidRequest = errors.New("not a FrankenPHP request") ErrAlreadyStarted = errors.New("FrankenPHP is already started") ErrInvalidPHPVersion = errors.New("FrankenPHP is only compatible with PHP 8.2+") ErrMainThreadCreation = errors.New("error creating the main thread") ErrScriptExecution = errors.New("error during PHP script execution") ErrNotRunning = errors.New("FrankenPHP is not running. For proper configuration visit: https://frankenphp.dev/docs/config/#caddyfile-config")
ErrInvalidRequestPath = [ErrRejected](#ErrRejected){"invalid request path", [http](/net/http).[StatusBadRequest](/net/http#StatusBadRequest)}
ErrInvalidContentLengthHeader = [ErrRejected](#ErrRejected){"invalid Content-Length header", [http](/net/http).[StatusBadRequest](/net/http#StatusBadRequest)}
ErrMaxWaitTimeExceeded = [ErrRejected](#ErrRejected){"maximum request handling time exceeded", [http](/net/http).[StatusServiceUnavailable](/net/http#StatusServiceUnavailable)})
EmbeddedAppPath contains the path of the embedded PHP application (empty if none)
EXPERIMENTAL: DrainWorkers finishes all worker scripts before a graceful shutdown
ExecuteScriptCLI executes the PHP script passed as parameter. It returns the exit status code of the script.
package main
import ( "log" "os"
"github.com/dunglas/frankenphp")
func main() { if len(os.Args) <= 1 { log.Println("Usage: my-program script.php") os.Exit(1) }
os.Exit(frankenphp.ExecuteScriptCLI(os.Args[1], os.Args))}
EXPERIMENTAL: GoMap converts a zval having a zend_array value to an unordered Go map
EXPERIMENTAL: GoPackedArray converts a zval with a zend_array value to a Go slice
EXPERIMENTAL: GoString copies a zend_string to a Go string.
EXPERIMENTAL: GoValue converts a PHP zval to a Go value
Zval having the null, bool, long, double, string and array types are currently supported. Arrays can curently only be converted to any[] and AssociativeArray[any]. Any other type will cause an error. More types may be supported in the future.
func Init(options ...Option) error
Init starts the PHP runtime and the configured workers.
NewRequestWithContext creates a new FrankenPHP request context.
EXPERIMENTAL: PHPAssociativeArray converts a Go AssociativeArray to a PHP zval with a zend_array value
EXPERIMENTAL: PHPMap converts an unordered Go map to a PHP zend_array
EXPERIMENTAL: PHPPackedArray converts a Go slice to a PHP zval with a zend_array value.
EXPERIMENTAL: PHPString converts a Go string to a zend_string with copy. The string can be non-persistent (automatically freed after the request by the ZMM) or persistent. If you choose the second mode, it is your repsonsability to free the allocated memory.
EXPERIMENTAL: PHPValue converts a Go any to a PHP zval
nil, bool, int, int64, float64, string, []any, and map[string]any are currently supported. Any other type will cause a panic. More types may be supported in the future.
RegisterExtension registers a new PHP extension.
RestartWorkers attempts to restart all workers gracefully
ServeHTTP executes a PHP script according to the given context.
package main
import ( "log" "net/http"
"github.com/dunglas/frankenphp")
func main() { if err := frankenphp.Init(); err != nil { panic(err) } defer frankenphp.Shutdown()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
req, err := frankenphp.NewRequestWithContext(r, frankenphp.WithRequestDocumentRoot("/path/to/document/root", false))
if err != nil {
panic(err)
}
if err := frankenphp.ServeHTTP(w, req); err != nil {
panic(err)
}
})
log.Fatal(http.ListenAndServe(":8080", nil))}
package main
import ( "log" "net/http"
"github.com/dunglas/frankenphp")
func main() { if err := frankenphp.Init( frankenphp.WithWorkers("worker1", "worker1.php", 4, frankenphp.WithWorkerEnv(map[string]string{"ENV1": "foo"}), frankenphp.WithWorkerWatchMode([]string{}), frankenphp.WithWorkerMaxFailures(0), ), frankenphp.WithWorkers("worker2", "worker2.php", 2, frankenphp.WithWorkerEnv(map[string]string{"ENV2": "bar"}), frankenphp.WithWorkerWatchMode([]string{}), frankenphp.WithWorkerMaxFailures(0), ), ); err != nil { panic(err) } defer frankenphp.Shutdown()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
req, err := frankenphp.NewRequestWithContext(r, frankenphp.WithRequestDocumentRoot("/path/to/document/root", false))
if err != nil {
panic(err)
}
if err := frankenphp.ServeHTTP(w, req); err != nil {
panic(err)
}
})
log.Fatal(http.ListenAndServe(":8080", nil))}
Shutdown stops the workers and the PHP runtime.
func WithExtensionWorkers(name, fileName string, numThreads int, options ...WorkerOption) (Workers, Option)
EXPERIMENTAL: WithExtensionWorkers allow extensions to create workers.
A worker script with the provided name, fileName and thread count will be registered, along with additional configuration through WorkerOptions.
Workers are designed to run indefinitely and will be gracefully shut down when FrankenPHP shuts down.
Extension workers receive the lowest priority when determining thread allocations. If the requested number of threads cannot be allocated, then FrankenPHP will panic and provide this information to the user (who will need to allocate more total threads). Don't be greedy.
AssociativeArray represents a PHP array with ordered key-value pairs
EXPERIMENTAL: GoAssociativeArray converts a zend_array to a Go AssociativeArray
type ErrRejected struct {
}
type FrankenPHPDebugState struct { ThreadDebugStates []ThreadDebugState ReservedThreadCount int }
EXPERIMENTAL: FrankenPHPDebugState prints the state of all PHP threads - debugging purposes only
func DebugState() FrankenPHPDebugState
EXPERIMENTAL: DebugState prints the state of all PHP threads - debugging purposes only
type Metrics interface {
StartWorker(name [string](/builtin#string))
ReadyWorker(name [string](/builtin#string))
StopWorker(name [string](/builtin#string), reason [StopReason](#StopReason))
TotalWorkers(name [string](/builtin#string), num [int](/builtin#int))
TotalThreads(num [int](/builtin#int))
StartRequest()
StopRequest()
StopWorkerRequest(name [string](/builtin#string), duration [time](/time).[Duration](/time#Duration))
StartWorkerRequest(name [string](/builtin#string))
Shutdown()
QueuedWorkerRequest(name [string](/builtin#string))
DequeuedWorkerRequest(name [string](/builtin#string))
QueuedRequest()
DequeuedRequest()}
type Option func(h *opt) error
Option instances allow to configure FrankenPHP.
WithContext sets the main context to use.
WithLogger configures the global logger to use.
func WithMaxThreads(maxThreads int) Option
WithMaxWaitTime configures the max time a request may be stalled waiting for a thread.
func WithMetrics(m Metrics) Option
func WithNumThreads(numThreads int) Option
WithNumThreads configures the number of PHP threads to start.
WithPhpIni configures user defined PHP ini settings.
func WithWorkers(name, fileName string, num int, options ...WorkerOption) Option
WithWorkers configures the PHP workers to start
type PHPConfig struct { Version PHPVersion ZTS bool ZendSignals bool ZendMaxExecutionTimers bool }
type PHPVersion struct { MajorVersion int MinorVersion int ReleaseVersion int Version string VersionID int }
func Version() PHPVersion
Version returns infos about the PHP version.
type PrometheusMetrics struct {
}
func (m *PrometheusMetrics) DequeuedRequest()
func (m *PrometheusMetrics) DequeuedWorkerRequest(name string)
func (m *PrometheusMetrics) QueuedRequest()
func (m *PrometheusMetrics) QueuedWorkerRequest(name string)
func (m *PrometheusMetrics) Shutdown()
func (m *PrometheusMetrics) StartRequest()
func (m *PrometheusMetrics) StartWorkerRequest(name string)
func (m *PrometheusMetrics) StopRequest()
func (m *PrometheusMetrics) TotalThreads(num int)
type RequestOption func(h *frankenPHPContext) error
RequestOption instances allow to configure a FrankenPHP Request.
WithMercureHub sets the mercure.Hub to use to publish updates
func WithRequestDocumentRoot(documentRoot string, resolveSymlink bool) RequestOption
WithRequestDocumentRoot sets the root directory of the PHP application. if resolveSymlink is true, oath declared as root directory will be resolved to its absolute value after the evaluation of any symbolic links. Due to the nature of PHP opcache, root directory path is cached: when using a symlinked directory as root this could generate errors when symlink is changed without PHP being restarted; enabling this directive will set $_SERVER['DOCUMENT_ROOT'] to the real directory path.
WithRequestEnv set CGI-like environment variables that will be available in $_SERVER. Values set with WithEnv always have priority over automatically populated values.
WithRequestLogger sets the logger associated with the current request
func WithRequestPreparedEnv(env PreparedEnv) RequestOption
func WithRequestResolvedDocumentRoot(documentRoot string) RequestOption
WithRequestResolvedDocumentRoot is similar to WithRequestDocumentRoot but doesn't do any checks or resolving on the path to improve performance.
func WithRequestSplitPath(splitPath []string) RequestOption
WithRequestSplitPath contains a list of split path strings.
The path in the URL will be split into two, with the first piece ending with the value of splitPath. The first piece will be assumed as the actual resource (CGI script) name, and the second piece will be set to PATH_INFO for the CGI script to use.
Future enhancements should be careful to avoid CVE-2019-11043, which can be mitigated with use of a try_files-like behavior that 404s if the FastCGI path info is not found.
WithWorkerName sets the worker that should handle the request
EXPERIMENTAL: ThreadDebugState prints the state of a single PHP thread - debugging purposes only
type WorkerOption func(*workerOpt) error
WorkerOption instances allow configuring FrankenPHP worker.
WithWorkerEnv sets environment variables for the worker
func WithWorkerMaxFailures(maxFailures int) WorkerOption
WithWorkerMaxFailures sets the maximum number of consecutive failures before panicking
func WithWorkerMaxThreads(num int) WorkerOption
WithWorkerMaxThreads sets the max number of threads for this specific worker
func WithWorkerOnReady(f func(int)) WorkerOption
func WithWorkerOnServerShutdown(f func()) WorkerOption
WithWorkerOnServerShutdown adds a function to be called right before server shutdown. Useful for extensions.
func WithWorkerOnServerStartup(f func()) WorkerOption
WithWorkerOnServerStartup adds a function to be called right after server startup. Useful for extensions.
func WithWorkerOnShutdown(f func(int)) WorkerOption
func WithWorkerRequestOptions(options ...RequestOption) WorkerOption
WithWorkerRequestOptions sets options for the main dummy request created for the worker
func WithWorkerWatchMode(watch []string) WorkerOption
WithWorkerWatchMode sets directories to watch for file changes
EXPERIMENTAL: Workers allows you to register a worker.