Workflow procedures for PHP

0.8.0 2023-10-06 22:29 UTC


🔔 Subscribe to the newsletter to don't miss any update regarding Chevere.


Build Code size Apache-2.0 PHPStan Mutation testing badge

Quality Gate Status Maintainability Rating Reliability Rating Security Rating Coverage Technical Debt CodeFactor Codacy Badge



A Workflow is a configurable stored procedure that will run one or more jobs. Jobs are independent from each other, but interconnected as you can pass response references between jobs. Jobs supports conditional running based on variables and previous job responses.

Quick start

Install with Composer.

composer require chevere/workflow

Workflow provides the following functions at the Chevere\Workflow namespace:

Function Purpose
workflow Create workflow made of named jobs
sync Create synchronous blocking job
async Create asynchronous non-blocking job
variable Define workflow-level variable
response Define a job response reference
  • A Job is defined by its Action
  • Jobs are independent from each other, define shared variables using function variable
  • Reference [job A response] -> [job B input] by using function response

Hello, world

Run live example: php demo/hello-world.php

The basic example Workflow defines a greet for a given username. The job greet is a named argument and it takes the GreetAction plus its run arguments.

use function Chevere\Workflow\workflow;
use function Chevere\Workflow\sync;

$workflow = workflow(
    greet: sync(
        new GreetAction(),
        username: variable('username'),
$variables = [
    'username' => $argv[1] ?? 'Walala',
$run = run($workflow, $variables);
echo $run->getResponse('greet')->string();
// Hello, Walala!

Full example

Run live example: php demo/image-resize.php

For this example Workflow defines an image resize procedure in two sizes. All jobs are defined as async, but as there are dependencies between jobs (see variable and response) the system resolves a suitable run strategy.

use function Chevere\Workflow\workflow;
use function Chevere\Workflow\async;
use function Chevere\Workflow\response;
use function Chevere\Workflow\variable;

$workflow = workflow(
    thumb: async(
        new ImageResize(),
        file: variable('image'),
        fit: 'thumbnail',
    poster: async(
        new ImageResize(),
        file: variable('file'),
        fit: 'poster',
    storeThumb: async(
        new StoreFile(),
        file: response('thumb'),
        path: variable('savePath'),
    storePoster: async(
        new StoreFile(),
        file: response('poster'),
        path: variable('savePath'),

The graph for the Workflow above shows that thumb and poster run async, just like storeThumb and storePoster but the storage jobs run after the first dependency level gets resolved.

  graph TD;

Use function run to run the Workflow, variables are passed as named arguments.

use function Chevere\Workflow\run;

$run = run(
    image: '/path/to/image-to-upload.png',
    savePath: '/path/to/storage/'

// Alternative syntax
$variables = [
    'image' => '/path/to/image-to-upload.png',
    'savePath' => '/path/to/storage/'
$run = run($workflow, ...$variables);

Use getResponse to retrieve a job response as a CastArgument object which can be used to get a typed response.

$thumbFile = $run->getResponse('thumb')->string();

Notes on async

Actions must support serialization for being used on async jobs. For not serializable Actions as these interacting with connections (namely streams, database clients, etc.) you should use sync job.


Documentation is available at


Copyright 2023 Rodolfo Berrios A.

This software is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.