# PHP Code

Run a PHP function body with full WordPress access when no built-in step fits the job.

![Permission-locked nodes in the Add a node panel](/documentation/flowcrafter/screenshots/locked-premium-nodes.png)

## When to use it

Use PHP Code for small, trusted transformations or calls to code already on your site.

:::caution[PHP Code has full site access]
Prefer built-in steps where possible: this code is not sandboxed and can read secrets, change data, make requests, or break the run. Only run code you trust and understand.
:::

![PHP Code connected to Form Submitted](/documentation/flowcrafter/screenshots/action-php-code-workflow.png)

## Settings

![PHP Code settings with safety warnings and a function body returning workshop data](/documentation/flowcrafter/screenshots/action-php-code-settings.png)

| Setting | What it controls |
| --- | --- |
| Code | Required PHP function body. Do not include `<?php` or `?>`. Return an array, scalar, or `null`. |

Available values include `$input` for the nearest upstream output, `$context->node('Step name')` for one step's output, and `$context->token('{{ "Step name".key }}')` for one flow tag value. `$context->merge_tag('{Field:3}')` resolves a Gravity Forms merge tag against `$input` by default; `$input` must be an entry-shaped array for field tags to work. Pass another entry array as the second argument when needed.

Flow tags are **not** replaced throughout the PHP source. Resolve them at runtime with `$context->token()`.

:::danger[Only trusted administrators should edit this step]
By default, editing PHP Code requires the `edit_plugins` capability, and on multisite it requires a super administrator. The capability can be changed by a developer.
:::

## Output and branches

The step has one output. Array keys become flow tag values; a scalar is returned as **result**; `null` produces no output. Nested arrays are allowed, but objects and resources are rejected. Parse errors, thrown errors, or invalid return values fail the step.

## Example

This returns a normalized email address from an earlier step:

```php
$email = $context->token('{{ "Form Submitted"["3"] }}');
return [ 'email' => strtolower( trim( (string) $email ) ) ];
```

A later step can use `{{ "Normalize email".email }}`.
