annotations

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package annotations discovers annotated PHP files in a source tree and gives them a lifecycle: routed endpoints are served over HTTP, startup jobs run once before the server listens, and scheduled jobs run on an interval.

Two annotations are recognised, both written as comments:

  • `// @route GET /users/{id}` registers an HTTP endpoint.
  • `// @startup` marks a file the server executes before it listens.
  • `// @schedule daily -- prune` runs a file on a clock or interval.

Routes

The `@route` tag takes an HTTP method and a path, optionally separated from the tag by a colon, one route per line:

  • `// @route GET /users/{id}`
  • `// @route POST /users/{id}`
  • `// @route: /users/{id}`

The tag can be repeated to register multiple handlers. In the case of a duplicate handler being registered, the last one wins and a warning is printed in the logs.

If method is omitted, only GET and POST are routed to the handler. This ignores requests like HEAD and OPTIONS, ideally leaving these to be resolved in the router, rather than invoking PHP.

Specific HTTP methods like PUT are only reachable when explicitly stated.

This functionality fills a phpscript-specific auto-global value:

  • `$_PATH`, specifically `$_PATH['id']`.

It relies on the Go standard library to extract path parameters present.

Startup jobs

A file carrying `@startup` runs once, in path order, before the server listens. It executes with the CLI SAPI, so it can migrate a schema or warm a cache. An error aborts startup.

Scheduled jobs

A file may repeat `@schedule` with an interval spec and optional `-- args` passed as `$argv`. Specs: `every N seconds|minutes|hours`, `hourly`, `daily`, `weekly`, `monthly`, `every weekday`, `every sunday` (any weekday name), `N times per hour|day`. Calendar specs fire at local midnight. A tick is skipped when the previous run is still going. Output is recorded on the oida span as `output`.

Discovery

The .php files are scanned recursively, so you may keep them in a single folder, or just place them in arbitrary subfolders. Files without annotations are skipped, as are `vendor` directories: a composer dependency does not get to publish routes into the application, or to run at startup.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HasStartup

func HasStartup(src []byte) bool

HasStartup reports whether src carries an @startup comment, marking a file the server executes once before it listens. `phpscript list` uses it to show startup files alongside routed ones.

func ParseRoutes

func ParseRoutes(src []byte) []model.RouteAnnotation

ParseRoutes returns the @route declarations found in src. A path-only annotation expands to both GET and POST, matching the HTTP router.

Types

type Option

type Option func(*config)

Option configures how annotated PHP files are discovered and executed. The same options apply to Route and Startup: both scan one source tree and run PHP files out of it.

func WithExcludedDirectory

func WithExcludedDirectory(name string) Option

WithExcludedDirectory skips a top-level directory while scanning.

func WithExprCache

func WithExprCache(cache *runner.ExprCache) Option

WithExprCache sets a shared expression cache used by routed endpoints.

func WithFlatstack

func WithFlatstack(enabled bool) Option

WithFlatstack enables the flat bytecode runtime with interpreter fallback.

func WithObservers

func WithObservers(observers ...runner.Observer) Option

WithObservers attaches runtime observers to every annotated PHP file.

func WithOutput

func WithOutput(out io.Writer) Option

WithOutput sets where a startup job writes its output. Routed endpoints write to the HTTP response instead, and ignore this.

func WithRootDir

func WithRootDir(dir string) Option

WithRootDir grants annotated PHP files access to the project directory, backing filesystem functions like fopen().

func WithRunnerOptions

func WithRunnerOptions(options runner.Options) Option

WithRunnerOptions configures the runtimes created for annotated PHP files.

func WithRuntimeFunc

func WithRuntimeFunc(fn RuntimeFunc) Option

WithRuntimeFunc registers fn to customize each runtime after the standard library and the request context have been installed on it.

type Registrar

type Registrar interface {
	Handle(method string, path string, handler http.Handler)
}

Registrar binds a handler to an HTTP method and path. It is the seam between discovered routes and whichever router the application runs.

type Route

type Route struct {
	platform.UnimplementedModule
	// contains filtered or unexported fields
}

Route serves the @route endpoints of a PHP source tree. It is a platform.Module, and registers on a standard library mux just as well.

func NewRoute

func NewRoute(root fs.FS, options ...Option) *Route

NewRoute creates a route module reading annotated endpoints from root.

func (*Route) Mount

func (r *Route) Mount(_ context.Context, router platform.Router) error

Mount registers all discovered routes with the platform router.

func (*Route) Register

func (r *Route) Register(registrar Registrar) error

Register walks the source tree and hands every @route annotation it finds to registrar, backed by a handler that executes the file it was declared in.

func (*Route) RegisterMux

func (r *Route) RegisterMux(mux *http.ServeMux) error

RegisterMux registers all discovered routes on a standard library mux.

type RuntimeFunc

type RuntimeFunc func(*runner.Runtime)

RuntimeFunc customizes a PHP runtime before an annotated PHP file executes.

type Schedule

type Schedule struct {
	Raw      string
	Args     []string
	Every    time.Duration
	Weekdays []time.Weekday
	MonthDay int
	Align    align
}

Schedule is one `@schedule` annotation: when to run, and argv after `--`.

func ParseSchedules

func ParseSchedules(src []byte) []Schedule

ParseSchedules returns the @schedule declarations found in src. A line may carry `-- args` after the interval spec; those become $argv[1:].

func (Schedule) Next

func (s Schedule) Next(t time.Time) time.Time

Next returns the first instant strictly after t at which the job should run.

type Scheduler

type Scheduler struct {
	platform.UnimplementedModule
	// contains filtered or unexported fields
}

Scheduler runs @schedule jobs for the life of the server. Start returns immediately; each job waits until its next due time in its own goroutine.

func NewScheduler

func NewScheduler(root fs.FS, options ...Option) *Scheduler

NewScheduler creates a schedule module reading jobs from root.

func (*Scheduler) Start

func (s *Scheduler) Start(ctx context.Context) error

Start discovers jobs and runs them until ctx is cancelled.

type Startup

type Startup struct {
	platform.UnimplementedModule
	// contains filtered or unexported fields
}

Startup runs the @startup jobs of a PHP source tree once, in path order, before the platform starts its server. An error aborts startup.

func NewStartup

func NewStartup(root fs.FS, options ...Option) *Startup

NewStartup creates a startup lifecycle module reading jobs from root.

func (*Startup) Start

func (s *Startup) Start(ctx context.Context) error

Start executes every PHP file carrying an @startup annotation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL