Download the PHP package iak/result without Composer

On this page you can find all versions of the php package iak/result. 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 result

Result

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

A Result is a return type for operations that can fail. Instead of throwing an exception for an outcome you fully expect — an expired card, an empty stock, a closed kitchen — you return it. For example, check out the following code:

Two operations that can each fail, one place where failure is handled, and not a try/catch in sight. Every possible outcome is right there in the types — your IDE sees them, your static analyser sees them, and the next developer sees them.

Installation

That's it. Results require PHP 8.2+ and nothing else — no framework, no configuration, no service provider.

Your First Result

Let's build something real: placing an order. You've probably written this controller a hundred times:

It works — until someone adds a fourth failure mode to PlaceOrder and this controller quietly starts responding with 500s. Nothing in handle()'s signature says what it throws, and nothing checks that you caught it all.

Let's rebuild it with a Result. First, give every failure a name. An enum is perfect for this, and it gives the error messages a home too:

Next, instead of throwing, return the outcome — either way:

Notice the docblock: Result<Order, OrderError>. That one line now documents every way this operation can end. No source-diving, no tribal knowledge.

Finally, the controller shrinks to a single expression:

[!NOTE] Where did the try/catch go? There's nothing to catch — failure is just a return value now. And unlike a catch block, match() can't be forgotten: it's the only way to get at the order, and it requires both arms.

And when someone adds that fourth failure mode? They add an enum case, the match inside message() immediately demands a message for it, and every consumer of the error gets flagged by static analysis. The failure mode is born handled.

That's the whole pattern. Everything else in this package is convenience on top of it.

Available Methods

expect · isFailure · match · tapError · valueOrElse

Method Listing

success()

The static success method wraps a value in a successful result:

You may call it without arguments when the operation has nothing meaningful to return — "it worked" is the whole message:

failure()

The static failure method wraps an error in a failed result. The error may be anything: an enum, a value object carrying context, a string, or an exception if you already have one:

all()

The static all method combines a collection of results into a single result. If every result succeeded, you get one success holding all the values with their keys preserved. If any failed, you get the first failure back, untouched:

You may pass any iterable. Iteration stops at the first failure, so a lazy generator won't do more work than necessary.

isSuccess()

The isSuccess method determines whether the operation succeeded:

isFailure()

The isFailure method is the mirror of isSuccess. It shines in guard clauses, keeping the happy path flat:

[!NOTE] Prefer these methods over instanceof checks. Static analysers can't carry the value and error types through a bare instanceof, but isSuccess() and isFailure() keep them intact.

value()

The value method returns the success value:

If the result is a failure, value throws a ResultException. An unguarded call is therefore an assertion — "this can't fail here, and if I'm wrong I want to hear about it." When you're not asserting, guard with valueOr.

error()

The error method returns the error value, throwing a ResultException if the result is actually a success. You'll use it after a guard, and all over your tests:

expect()

The expect method works like value, but the exception carries your message — so when the impossible happens, whoever's on call knows what you were assuming:

expectError()

The expectError method is expect for the error side:

valueOr()

The valueOr method returns the success value, or your fallback if the operation failed — for when you don't care why:

valueOrElse()

The valueOrElse method computes the fallback from the error, and only when it's actually needed:

map()

The map method transforms the success value without unpacking the result. A failure passes through untouched:

mapError()

The mapError method transforms the error instead. It's the tool for translating low-level errors into your domain's language at a boundary:

tap()

The tap method runs a side effect on the success value — logging, metrics, notifications — and hands the result back unchanged:

tapError()

The tapError method does the same for the failure side. Together they let you observe a pipeline without interrupting it:

chain()

The chain method pipes the success value into the next operation that can itself fail. The first failure short-circuits everything after it, so a whole workflow needs exactly one failure handler:

Notice how the error types stack up: add a step, and every handler downstream is made aware of what it might have to deal with.

[!NOTE] Why isn't this called then()? Promise libraries — Guzzle, and therefore Laravel's Http::async(), and ReactPHP — treat any object with a public then() method as a promise and try to resolve it. A Result named that way would break inside promise pipelines, so it's chain().

orElse()

The orElse method is recovery: on failure, try something else that can itself succeed or fail. A success passes straight through:

match()

The match method handles both outcomes in one expression. Both arms are required — the failure path can't be forgotten:

Handling Different Error Types

Once you start chaining, the error side becomes a union — OrderError|PaymentError — and you may want to treat them differently. PHP's own match has you covered:

Static analysers check that inner match against the union — add a third error type to the chain and this exact spot gets flagged until you handle it.

If every error is handled the same way, skip the dispatch entirely and give your errors a shared interface:

And when a union grows past comfort, normalize early: use mapError at each boundary so downstream code only ever sees one error type.

Good to Know

Development

License

MIT. See LICENSE.md.


All versions of result with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
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 iak/result contains the following files

Loading the files please wait ...