Download the PHP package crell/tukio without Composer

On this page you can find all versions of the php package crell/tukio. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package tukio

Tukio

Latest Version on Packagist Total Downloads

Tukio is a complete and robust implementation of the PSR-14 Event Dispatcher specification. It supports normal and debug Event Dispatchers, both runtime and compiled Providers, complex ordering of Listeners, and attribute-based registration on PHP 8.

"Tukio" is the Swahili word for "Event".

Install

Via Composer

PSR-14 Usage

PSR-14 consists of two key components: A Dispatcher and a Provider. A Dispatcher is what a client library will compose and then pass Events objects to. A Provider is what a framework will give to a Dispatcher to match the Event to Listeners. Tukio includes multiple implementations of both.

The general structure of using any PSR-14-compliant implementation is:

Note that dispatch() will return $thingHappened as well, so if Listeners are expected to add data to it then you can chain a method call on it if desired:

In practice most of that will be handled through a Dependency Injection Container, but there's no requirement that it do so.

Dispatchers

Tukio includes two Dispatchers: Dispatcher is the standard implementation, which should be used 95% of the time. It can optionally take a PSR-3 Logger, in which case it will log a warning on any exception thrown from a Listener.

The second is DebugEventDispatcher, which like the names says is useful for debugging. It logs every Event that is passed and then delegates to a composed dispatcher (such as Dispatcher) to actually dispatch the Event.

For example:

Providers

Tukio includes multiple options for building Providers, and it's encouraged that you combine them with the generic ones included in the fig/event-dispatcher-util library provided by the FIG.

Which Provider or Providers you use depends on your use case. All of them are valid for certain use cases.

OrderedListenerProvider

As the name implies, OrderedListenerProvider is all about ordering. Users can explicitly register Listeners on it that will be matched against an Event based on its type.

If no order is specified, then the order that Listeners will be returned is undefined, and in practice users should expect the order to be stable, but not predictable. That makes the degenerate case super-easy:

That adds two Listeners to the Provider; one anonymous function and one named function. The anonymous function will be called for any SpecificStuffHappened event. The named function will be called for any StuffHappened or SpecificStuffHappened event. And the user doesn't really care which one happens first (which is the typical case).

Ordering listeners

However, the user can also be picky about the order in which Listeners will fire. Tukio supports two ordering mechanisms: Priority order, and Topological sorting (before/after markers). Internally, Tukio will convert priority ordering into topological ordering.

Now, the named function Listener will get called before the anonymous function does. (Higher priority number comes first, and negative numbers are totally legal.) If two listeners have the same priority then their order relative to each other is undefined.

Sometimes, though, you may not know the priority of another Listener, but it's important your Listener happen before or after it. For that we need to add a new concept: IDs. Every Listener has an ID, which can be provided when the Listener is added or will be auto-generated if not. The auto-generated value is predictable (the name of a function, the class-and-method of an object method, etc.), so in most cases it's not necessary to read the return value of listener() although that is slightly more robust.

Here, the priority of handleStuff is undefined; the user doesn't care when it gets called. However, the anonymous function, if it should get called at all, will always get called after handleStuff does. It's possible that some other Listener could also be called in between the two, but one will always happen after the other.

The listener() method is used for all registration, and can accept a priority, a list of listener IDs the new listener must come before, and a list of listener IDs the new listener must come after. It also supports specifying a custom ID, and a custom $type.

Because that's a not-small number of options, it is strongly recommended that you use named arguments for all arguments other than the listener callable itself.

The listener() method will always return the ID that was used for that listener. If desired the $type parameter allows a user to specify the Event type that the Listener is for if different than the type declaration in the function. For example, if the Listener doesn't have a type declaration or should only apply to some parent class of what it's type declaration is. (That's a rare edge case, which is why it's the last parameter.)

Service Listeners

Often, though, Listeners are themselves methods of objects that should not be instantiated until and unless needed. That's exactly what a Dependency Injection Container allows, and OrderedListenerProvider fully supports those, called "Service Listeners." They work almost exactly the same, except you specify a service and method name:

The $type, $priority, $before, $after, and $id parameters work the same way as for listener(). $service is any service name that will be retrieved from a container on-demand, and $method is the method on the object.

If the service name is the same as that of a found class (which is typical in most modern conventions), then Tukio can attempt to derive the method and type from the class. If the service name is not the same as a defined class, it cannot do so and both $method and $type are required and will throw an exception if missing.

If no $method is specified and the service name matches a class, Tukio will attempt to derive the method for you. If the class has only one method, that method will be automatically selected. Otherwise, if there is a __invoke() method, that will be automatically selected. Otherwise, the auto-detection fails and an exception is thrown.

The services themselves can be from any PSR-11-compatible Container.

In this example, we have listener methods defined in three different classes, all of which are registered with a PSR-11 container. In the first code block, we register two listeners out of a class whose service name does not match its class name. In the second, we register a method on a class whose service name does match its class name, so we can derive the event type by reflection. In the third block, we use a single-method listener class, which allows everything to be derived!

Of note, the methodB Listener is referencing the methodA listener by an explict ID. The generated ID is as noted predictable, so in most cases you don't need to use the return value. The return value is the more robust and reliable option, though, as if the requested ID is already in-use a new one will be generated.

Attribute-based registration

The preferred way to configure Tukio, however, is via attributes. There are four relevant attributes: Listener, ListenerPriority, ListenerBefore, and ListenerAfter. All can be used with sequential parameters or named parameters. In most cases, named parameters will be more self-documenting. All attributes are valid only on functions and methods.

The $before and $after parameters will accept either a single string, or an array of strings.

As multiple attributes may be included in a single block, that allows for compact syntax like so:

If you pass a listener with Listener attributes to listener() or listenerService(), the attribute defined configuration will be used. If you pass configuration in the method signature, however, that will override any values taken from the attributes.

Subscribers

A "Subscriber" (a name openly and unashamedly borrowed from Symfony) is a class with multiple listener methods on it. Tukio allows you to bulk-register any listener-like methods on a class, just by registering the class.

As before, if the service name is the same as that of the class, it may be omitted. A method will be registered if either:

For example:

Listener classes

As hinted above, one of the easiest ways to structure a listener is to make it the only method on a class, particularly if it is named __invoke(), and give the service the same name as the class. That way, it can be registered trivially and derive all of its configuration through attributes. Since it is extremely rare for a listener to be registered twice (use cases likely exist, but we are not aware of one), this does not cause a name collision issue.

Tukio has two additional features to make it even easier. One, if the listener method is __invoke(), then the ID of the listener will by default be just the class name. Two, the Listener attributes may also be placed on the class, not the method, in which case the class-level settings will inherit to every method.

The result is that the easiest way to define listeners is as single-method classes, like so:

Now, the API call itself is trivially easy. Just specify the class name. ListenerTwo::__invoke() will be called before ListnerOne::__invoke(), regardless of the order in which they were registered. When ListenerOne is requested from your DI container, the container will fill in its dependencies automatically.

This is the recommended way to write listeners for use with Tukio.

Deprecated functionality

A few registration mechanisms left over from Tukio version 1 are still present, but explicitly deprecated. They will be removed in a future version. Please migrate off of them as soon as possible.

Dedicated registration methods

The following methods still work, but are just aliases around calling listener() or listenerService(). They are less capable than just using listener(), as listener() allows for specifying a priority, before, and after all at once, including multiple before/after targets. The methods below do neither. Please migrate to listener() and listenerService().

Subscriber interface

In Tukio v1, there was an optional SubscriberInterface to allow for customizing the registration of methods as listeners via a static method that bundled the various addListener*() calls up within the class. With the addition of attributes in PHP 8, however, that functionality is no longer necessary as attributes can do everything the Subscriber interface could, with less work.

The SubscriberInterface is still supported, but deprecated. It will be removed in a future version. Please migrate to attributes.

The basic case works like this:

As before, onThingsHappen() will be registered automatically. However, somethingElse() will also be registered as a Listener with a priority of 10, and onSpecialEvent() will be registered to fire after it.

Compiled Provider

All of that registration and ordering logic is powerful, and it's surprisingly fast in practice. What's even faster, though, is not having to re-register on every request. For that, Tukio offers a compiled provider option.

The compiled provider comes in three parts: ProviderBuilder, ProviderCompiler, and a generated provider class. ProviderBuilder, as the name implies, is an object that allows you to build up a set of Listeners that will make up a Provider. They work exactly the same as on OrderedListenerProvider, and in fact it exposes the same OrderedProviderInterface.

ProviderCompiler then takes a builder object and writes a new PHP class to a provided stream (presumably a file on disk) that matches the definitions in the builder. That built Provider is fixed; it cannot be modified and no new Listeners can be added to it, but all the ordering and sorting has already been done, making it notably faster (to say nothing of skipping the registration process itself).

Let's see it in action:

$builder can do anything that OrderedListenerProvider can do, except that it only supports statically-defined Listeners. That means it does not support anonymous functions or methods of an object, but it will still handle functions, static methods, services, and subscribers just fine. In practice when using a compiled container you will most likely want to use almost entirely service listeners and subscribers, since you'll most likely be using it with a container.

That gives you a file on disk named MyCompiledProvider.php, which contains Name\Space\Of\My\App\MyCompiledProvider. (Name it something logical for you.) At runtime, then, do this:

And boom! $provider is now a fully functional Provider you can pass to a Dispatcher. It will work just like any other, but faster.

Alternatively, the compiler can output a file with an anonymous class. In this case, a class name or namespace are irrelevant.

Because the compiled container will be instantiated by including a file, but it needs a container instance to function, it cannot be easily just require()ed. Instead, use the loadAnonymous() method on a ProviderCompiler instance to load it. (It does not need to be the same instance that was used to create it.)

But what if you want to have most of your listeners pre-registered, but have some that you add conditionally at runtime? Have a look at the FIG's AggregateProvider, and combine your compiled Provider with an instance of OrderedListenerProvider.

Compiler optimization

The ProviderBuilder has one other trick. If you specify one or more events via the optimizeEvent($class) method, then the compiler will pre-compute what listeners apply to it based on its type, including its parent classes and interfaces. The result is a constant-time simple array lookup for those events, also known as "virtually instantaneous."

CallbackProvider

The third option Tukio provides is a CallbackProvider, which takes an entirely different approach. In this case, the Provider works only on events that have a CallbackEventInterface. The use case is for Events that are carrying some other object, which itself has methods on it that should be called at certain times. Think lifecycle callbacks for a domain object, for example.

To see it in action, we'll use an example straight out of Tukio's test suite:

In this example, the provider is configured not with Listeners but with method names that correspond to Events. Those methods are methods on the "subject" object. The Provider will now return callables for [$entity, 'load'] and [$entity, 'all'] when called with a LoadEvent. That allows a domain object itself to have Listeners on it that will get called at the appropriate time.

Change log

Please see CHANGELOG for more information on what has changed recently.

Testing

Contributing

Please see CODE_OF_CONDUCT for details.

Security

If you discover any security related issues, please use the GitHub security reporting form rather than the issue queue.

Credits

License

The Lesser GPL version 3 or later. Please see License File for more information.


All versions of tukio with dependencies

PHP Build Version
Package Version
Requires php Version ~8.1
crell/attributeutils Version ^1.1
crell/ordered-collection Version v2.x-dev
fig/event-dispatcher-util Version ^1.3
psr/container Version ^1.0 || ^2.0
psr/event-dispatcher Version ^1.0
psr/log Version ^1.0 || ^2.0 || ^3.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package crell/tukio contains the following files

Loading the files please wait ....