Skip to main content

PHP API

This page is a complete reference of the PHP API which is available inside a PHP worker action, i.e. the Worker-PHP-Local or Worker-PHP action. If you build a custom action as PHP class, please take a look at the PHP API for custom actions instead.

Structure​

The code of a PHP worker action is a PHP file which returns a function. Fusio calls this function on every invocation of the action and passes six arguments:

<?php

use Fusio\Worker;
use Fusio\Engine;
use Psr\Log\LoggerInterface;

return function(
Worker\ExecuteRequest $request,
Worker\ExecuteContext $context,
Engine\ConnectorInterface $connector,
Engine\Response\FactoryInterface $response,
Engine\DispatcherInterface $dispatcher,
LoggerInterface $logger
) {
return $response->ok([
'hello' => 'world',
]);
};
ArgumentTypeDescription
$requestFusio\Worker\ExecuteRequestThe incoming request, contains the arguments and the payload
$contextFusio\Worker\ExecuteContextInformation about the invocation, i.e. the user and app
$connectorFusio\Engine\ConnectorInterfaceReturns the clients of your configured connections
$responseFusio\Engine\Response\FactoryInterfaceBuilds the response of your action
$dispatcherFusio\Engine\DispatcherInterfaceDispatches events
$loggerPsr\Log\LoggerInterfaceWrites log messages

$request​

The request contains all data which the client has sent.

MethodDescription
getArguments(): RecordAll path and query parameters, i.e. the id of the path /posts/:id or ?search=foo
getPayload(): mixedThe parsed request body, which was validated against the incoming schema of the operation
getContext(): ExecuteRequestContextDetails of the HTTP request, i.e. the method and headers

Arguments​

The arguments are a PSX\Record\Record which contains the path and query parameters:

$arguments = $request->getArguments();

$id = $arguments->get('id'); // returns the value or null
$count = $arguments->getOrDefault('count', 16); // returns the value or a default
$hasSearch = $arguments->containsKey('search'); // checks whether a parameter exists
$all = $arguments->getAll(); // returns all parameters as array

Payload​

The payload contains the request body. You can access the fields of a JSON body as properties:

$payload = $request->getPayload();

$title = $payload->title ?? null;
$tags = $payload->tags ?? [];

For GET and DELETE requests, or if the operation has no incoming schema, the payload is empty.

Request context​

We recommend to read data only through getArguments() and getPayload(). Through this your action does not depend on HTTP and works the same way when it is invoked i.e. through a cronjob, a trigger or MCP. If you need details of the HTTP request, i.e. a header, you can use the request context:

MethodDescription
getType(): ?stringThe type of the context, i.e. an HTTP request
getMethod(): ?stringThe HTTP method, i.e. POST
getPath(): ?stringThe requested path, i.e. /posts/12
getUriFragments(): ?RecordThe path parameters
getQueryParameters(): ?RecordThe query parameters
getHeaders(): ?RecordThe request headers
$requestContext = $request->getContext();

$method = $requestContext->getMethod();
$userAgent = $requestContext->getHeaders()?->get('user-agent');

If the action was not invoked through HTTP, i.e. through a cronjob, these values can be null.

$context​

The context contains information about the invocation which is not part of the request.

MethodDescription
getOperationId(): ?intThe id of the operation which was invoked
getBaseUrl(): ?stringThe base URL of your Fusio instance, i.e. to build links
getTenantId(): ?stringThe tenant id, in case you run Fusio with multiple tenants
getAction(): ?stringThe name of the action
getApp(): ?ExecuteContextAppThe app which was used by the client
getUser(): ?ExecuteContextUserThe user which has invoked the action

App​

MethodDescription
getAnonymous(): ?boolWhether the request was made without an app
getId(): ?intThe id of the app
getName(): ?stringThe name of the app

User​

MethodDescription
getAnonymous(): ?boolWhether the request was made without an access token
getId(): ?intThe id of the user
getName(): ?stringThe name of the user
getEmail(): ?stringThe email of the user
getPoints(): ?intThe remaining points of the user, s. Monetization
getPlanId(): ?stringThe id of the plan which the user has subscribed

The user is anonymous in case the operation is public and the client has sent no access token. The following example returns only the posts of the authenticated user:

$user = $context->getUser();
if ($user === null || $user->getAnonymous()) {
return $response->forbidden('Please login to see your posts');
}

$posts = $connector->getConnection('App')->fetchAllAssociative('SELECT * FROM app_post WHERE user_id = :user_id', [
'user_id' => $user->getId(),
]);

return $response->ok(['entries' => $posts]);

$connector​

The connector returns a configured client for a connection. You only provide the name of the connection, all credentials are managed at the backend:

/** @var \Doctrine\DBAL\Connection $connection */
$connection = $connector->getConnection('App');
MethodDescription
getConnection(string|int $connectionId)Returns the client of a connection by its name

The type of the returned client depends on the connection:

ConnectionReturned clientDocumentation
SQLDoctrine\DBAL\ConnectionDoctrine DBAL
SQL-AdvancedDoctrine\DBAL\ConnectionDoctrine DBAL
HTTPGuzzleHttp\ClientGuzzle
MongoDBMongoDB\DatabaseMongoDB PHP library
ElasticsearchElasticsearch\ClientElasticsearch PHP client
AirtableSdkFabric\Airtable\ClientSDK Fabric
DiscordSdkFabric\Discord\ClientSDK Fabric
NotionSdkFabric\Notion\ClientSDK Fabric
TwitterSdkFabric\Twitter\ClientSDK Fabric
note

The table lists the connections which are supported by the remote Worker-PHP. The Worker-PHP-Local action runs directly on your Fusio instance and can use every connection which is available at Fusio, s. PHP API for custom actions.

$response​

The response factory builds the response of your action. Always return the result of one of these methods:

MethodStatus codeBody
build(int $statusCode, array $headers, mixed $body)AnyThe provided body
ok(mixed $body, array $headers = [])200 OKThe provided body
created(mixed $body, array $headers = [])201 CreatedThe provided body
accepted(mixed $body, array $headers = [])202 AcceptedThe provided body
noContent(array $headers = [])204 No ContentNo body
badRequest(string $message, array $headers = [])400 Bad Request{"success": false, "message": "..."}
forbidden(string $message, array $headers = [])403 Forbidden{"success": false, "message": "..."}
notFound(string $message, array $headers = [])404 Not Found{"success": false, "message": "..."}
conflict(string $message, array $headers = [])409 Conflict{"success": false, "message": "..."}
gone(string $message, array $headers = [])410 Gone{"success": false, "message": "..."}
internalServerError(string $message, array $headers = [])500 Internal Server Error{"success": false, "message": "..."}
notImplemented(string $message, array $headers = [])501 Not Implemented{"success": false, "message": "..."}
proxy(ResponseInterface $response)Of the proxied responseOf the proxied response

The body can be any value which can be encoded as JSON, i.e. an array or object. The proxy method forwards a PSR-7 response, i.e. of the Guzzle client, unchanged to the client, s. HTTP.

return $response->created(['id' => $id], ['Location' => '/posts/' . $id]);

$dispatcher​

The dispatcher dispatches an event. Fusio then sends the payload to all webhooks which have subscribed to the event and invokes all triggers of the event. The delivery happens in the background, so dispatching an event does not slow down your action.

MethodDescription
dispatch(string $eventName, mixed $payload)Dispatches an event, the payload is encoded as JSON
$dispatcher->dispatch('post_created', ['id' => $id, 'title' => $title]);

$logger​

The logger is a PSR-3 logger which writes messages to the Fusio log. This helps you to debug your action:

MethodUse case
debug(string $message, array $context = [])Detailed debug information
info(string $message, array $context = [])Interesting events, i.e. a post was created
notice(string $message, array $context = [])Normal but significant events
warning(string $message, array $context = [])Unusual events which are not errors
error(string $message, array $context = [])Errors which should be monitored
critical(string $message, array $context = [])Critical conditions, i.e. a service is unavailable
alert(string $message, array $context = [])Action must be taken immediately
emergency(string $message, array $context = [])The system is unusable
$logger->error('Could not create post', ['title' => $title]);

Complete example​

The following action creates a new post for the authenticated user. It validates the payload, inserts the post into the database, dispatches an event and returns the id of the new post:

<?php

use Fusio\Worker;
use Fusio\Engine;
use Psr\Log\LoggerInterface;

return function(Worker\ExecuteRequest $request, Worker\ExecuteContext $context, Engine\ConnectorInterface $connector, Engine\Response\FactoryInterface $response, Engine\DispatcherInterface $dispatcher, LoggerInterface $logger) {
$user = $context->getUser();
if ($user === null || $user->getAnonymous()) {
return $response->forbidden('Please login to create a post');
}

$payload = $request->getPayload();
$title = $payload->title ?? null;
if (empty($title)) {
return $response->badRequest('Provided no title');
}

/** @var \Doctrine\DBAL\Connection $connection */
$connection = $connector->getConnection('App');

try {
$connection->insert('app_post', [
'user_id' => $user->getId(),
'title' => $title,
'content' => $payload->content ?? '',
'insert_date' => (new \DateTime())->format('Y-m-d H:i:s'),
]);

$id = (int) $connection->lastInsertId();
} catch (\Doctrine\DBAL\Exception $e) {
$logger->error('Could not create post: ' . $e->getMessage());
return $response->internalServerError('Could not create post');
}

$dispatcher->dispatch('post_created', ['id' => $id, 'title' => $title]);

return $response->created(['id' => $id]);
};

More examples for common tasks can be found at the SQL and HTTP pages.