triggers and callbacks - phpgt/Input GitHub Wiki

One common pattern in PHP applications is to branch behaviour based on submitted input. A button press might trigger one action, while the presence of a certain field might trigger another.

Trigger lets us express that flow directly from the Input object.

do() for action buttons

The do() helper is shorthand for matching a submitted do parameter:

<button name="do" value="save">Save</button>
<button name="do" value="archive">Archive</button>
$input->do("save")->call(function() {
	// Save the current record.
});

$input->do("archive")->call(function() {
	// Archive the current record.
});

Note

This pattern is already hooked up in WebEngine, so do_*() functions are the expected trigger for "do buttons".

when() for matching keys or key/value pairs

Use when() when the trigger is based on the presence of one or more keys:

$input->when("confirm")->call(function() {
	// Runs when the "confirm" key is present.
});

We can also match exact values:

$input->when(["status" => "published"])->call(function() {
	// Runs only when status=published.
});

Multiple conditions can be combined:

$input->when(
	["status" => "published"],
	"notify"
)->call(function() {
	// Runs only when both conditions are met.
});

Passing only the input a callback needs

Callbacks receive an InputData object as their first argument. By default that object contains all request data.

Often that is more than the callback should know about, so select() lets us narrow the input down, enforcing good encapsulation throughout the project:

$input->when(["do" => "save"])
	->select("title", "summary")
	->call(function(InputData $data) {
		// $data contains only title and summary.
	});

To exclude keys instead, use selectAllExcept():

$input->when("register")
	->selectAllExcept("csrf", "password-confirm")
	->call(function($data) {
		// All input except the excluded keys.
	});

If we want to pass the whole request explicitly, use selectAll():

$input->when("register")
	->selectAll()
	->call(function($data) {
		// All request input.
	});

Matching keys by prefix

selectPrefix() is useful when a family of keys follows a naming convention:

$input->selectPrefix("io_")->call(function($data) {
	// Runs when at least one input key begins with "io_".
});

This method creates a trigger based on key presence. If no matching key exists, it returns a trigger that never fires.

For backwards compatibility the older names still exist:

  • with() is an alias of select()
  • without() is an alias of selectAllExcept()
  • withAll() is an alias of selectAll()

The select* names are clearer and should be preferred in new code.

Fallback callbacks

After call(), we can add an orCall() fallback:

$input->do("delete")
	->call(function() {
		// Deletion path.
	})
	->orCall(function() {
		// Runs only when the trigger did not fire.
	});

orCall() must come after call(). If it is called first, the library throws CallOrOutOfSequenceException.

Passing extra arguments

Additional string arguments supplied to call() are passed on after the InputData object:

$input->do("save")->call(
	function($data, string $mode, string $actor) {
		// ...
	},
	"draft",
	$currentUsername
);

Use this when the callback needs a small amount of extra context alongside the selected input.


Next: Working with InputData

⚠️ **GitHub.com Fallback** ⚠️