Php Code

Type key: php_code_node
Group: Utilities
Category: utility
Tier: CORE

The PHP Code node executes arbitrary PHP code inside a sandboxed closure. It provides direct access to the current $input data array and the $context (ExecutionContext), making it the most powerful and flexible node for custom logic that cannot be expressed through the standard node library.

Handles

Handle Direction Description
input Input Data passed as $input inside the code closure
output Output Emits whatever value is returned by the return statement

Configuration

Field Type Default Description
code string return $input; PHP code string to execute; <?php tag is stripped automatically
output_fields array [] Optional list of field names to extract from the return value; if empty, the full return value is emitted

Execution Environment

The code is executed inside a PHP closure, providing access to:

Variable Type Description
$input array The incoming data array
$context ExecutionContext Full execution context (variables, credentials, run metadata)

The closure signature is:

PHP
$fn = function (array $input, ExecutionContext $context) {
    // your code here
    return $result;
};

The return statement value becomes the node's output. Any PHP type is accepted: array, string, int, bool, or null.

Code Preprocessing

Before execution, the engine:

  1. Strips a leading <?php tag if present
  2. Wraps the code in a closure that binds $input and $context
  3. Evaluates the closure with eval()
  4. Catches any Throwable and returns ExecutionResult::failure() with the exception message

Context API

Inside the code, $context exposes:

PHP
// Read a workflow variable
$tenantId = $context->getVariable('tenant_id');

// Set a workflow variable
$context->setVariable('processed_count', 42);

// Access execution metadata
$runId    = $context->executionId;
$workflow = $context->workflow;

// Access credentials (returns a CredentialProxy)
// Use ->execute() with an action such as 'get_auth_headers', 'get_api_client', etc.
$credential = $context->getCredential('my_api_credential');
$headers    = $credential->execute('get_auth_headers');

Examples

Passthrough (Default)

PHP
return $input;

Data Transformation

PHP
return [
    'full_name'   => $input['first_name'] . ' ' . $input['last_name'],
    'email_lower' => strtolower($input['email']),
    'age'         => (int) $input['age'],
    'is_adult'    => (int) $input['age'] >= 18,
];

Conditional Logic

PHP
$discount = 0;

if ($input['total'] > 500) {
    $discount = 0.15;
} elseif ($input['total'] > 100) {
    $discount = 0.05;
}

return array_merge($input, [
    'discount_rate'   => $discount,
    'discounted_total' => round($input['total'] * (1 - $discount), 2),
]);

Using Laravel Helpers

PHP
use Illuminate\Support\Str;

return [
    'slug'      => Str::slug($input['title']),
    'uuid'      => Str::uuid()->toString(),
    'excerpt'   => Str::limit($input['body'], 160),
    'timestamp' => now()->toIso8601String(),
];

Calling an Eloquent Model

PHP
$user = \App\Models\User::find($input['user_id']);

if (! $user) {
    return ['found' => false];
}

return [
    'found'    => true,
    'name'     => $user->name,
    'plan'     => $user->subscription?->plan,
    'is_admin' => $user->hasRole('admin'),
];

HTTP Request with Guzzle

PHP
$credential = $context->getCredential('openai');
$authHeaders = $credential->execute('get_auth_headers');

$response = \Illuminate\Support\Facades\Http::withHeaders($authHeaders)
    ->post('https://api.openai.com/v1/embeddings', [
        'model' => 'text-embedding-3-small',
        'input' => $input['text'],
    ]);

return $response->json();

Aggregate Calculation

PHP
$items = $input['items'] ?? [];

$subtotal = array_sum(array_column($items, 'price'));
$vat      = round($subtotal * 0.22, 2);

return [
    'items'    => $items,
    'subtotal' => $subtotal,
    'vat'      => $vat,
    'total'    => round($subtotal + $vat, 2),
];

output_fields Filtering

When output_fields is set, only the specified keys are emitted:

YAML
output_fields: [full_name, email_lower]

Given a return value of ['full_name' => 'John Doe', 'email_lower' => 'john@example.com', 'raw' => '...'], only full_name and email_lower will be forwarded downstream.

Error Handling

Any exception or fatal error thrown inside the code is caught by the engine:

PHP
throw new \RuntimeException("Custom error: {$input['id']} not processable");

The node emits ExecutionResult::failure() with:

  • error_message: The exception message
  • error_code: PHP_CODE_EXCEPTION

Use a Catch node to handle these failures.

Security Considerations

Warning: The PHP Code node executes arbitrary PHP via eval(). It should be accessible only to trusted administrators.

  • Restrict access using Filament Shield policies; do not expose it to end-users
  • Avoid storing sensitive credentials directly in code; use $context->getCredential() instead
  • In multi-tenant environments, ensure workflow editing is limited to trusted roles

Notes

  • The node is ideal for one-off transformations that would require multiple standard nodes to express
  • For recurring, complex logic, consider creating a Custom Node instead
  • eval() operates in the same PHP process and memory space — heavy operations can impact performance; offload to queues
  • All Laravel facades, Eloquent models, and helpers are available in scope