Description
n8n-nodes-php
English | Русский
!GitHub License 
This is an n8n community node. It lets you execute arbitrary PHP code directly in your n8n workflows.
n8n is a fair-code licensed workflow automation platform.
Installation
Operations
Credentials
Compatibility
Usage
Security
Migrating from 1.x
Resources
Version history
Installation
Follow the installation guide in the n8n community nodes documentation.
In short:
1. In your n8n instance open Settings → Community nodes.
2. Select Install a community node.
3. Enter the package name: n8n-nodes-php.
4. Agree to the risks of using community nodes and confirm.
Self-hosted only. This node does not work on n8n Cloud, because it requires a local PHP binary.
Prerequisites
- A self-hosted n8n instance
- PHP CLI installed on the same machine as n8n and available in
PATH:
php -v
Operations
The node pipes your code to the PHP interpreter’s standard input (nothing is written to disk) and sends the workflow payload over a dedicated extra pipe. After execution it parses stdout:
{ "output": "" } .{ "error": ... } items when Continue On Fail is enabled).Data injection method
Choose how the current item’s data reaches the script via Data Injection Method:
{{ $json.email }} before execution.Inside your script you always have access to:
| Variable | Contents |
| ——– | ——– |
| $n8nInput | The current item’s JSON as an associative array |
| $n8nItems | All incoming items as an array of associative arrays |
| $n8nContext | Workflow metadata: nodeName, nodeId, workflowId, workflowName, executionId, runIndex, mode |
Execution mode
$n8nItems contains all of them). If the script returns as many output elements as there were input items, they are paired 1:1; otherwise all outputs pair to the first input item.Options
| Option | Default | Description |
| —— | ——- | ———– |
| Timeout (Seconds) | 30 | Maximum execution time. On timeout the process receives SIGTERM first and is force-killed only after a 2-second grace period. |
| PHP Binary Path | php | Path to the PHP CLI binary, e.g. /usr/bin/php8.3. |
| Strict JSON Mode | off | Fail when the output cannot be parsed as JSON instead of wrapping it in { output }. |
| Composer Autoload Path | empty | Prepends vendor/autoload.php via autoprependfile; warns instead of failing when the file does not exist. |
| Memory Limit (MB) | 128 | Applies -d memory_limit=; exceeding it raises a clear memory-limit error. |
| Security Level | Restricted | See Security. |
| Result Cache TTL (Seconds) | 0 (off) | Identical executions within the window return cached results without spawning PHP. |
Captured stdout and stderr are capped at 10 MB each; exceeding the cap kills the process and returns an error.
Additional files
Use Additional Files to ship helper scripts alongside your main code. Files are written into the sandbox directory before execution, and the PHP process runs with that directory as its working directory, so plain includes work:
encode(["result" => myhelper(21)]);
File names must be simple (letters-digits._-); content is free-form PHP.
Credentials
None required. The node uses the PHP binary available locally.
> Security note: executed code runs with the permissions of the n8n process. Only use your own trusted code, and never expose this node to untrusted input without validation.
Compatibility
| n8n version | Tested |
| ———– | —— |
| 2.x | ✅ |
Requires Node.js ≥ 22 for development. No minimum PHP version is enforced; any CLI version works (7.4+ recommended).
Usage
Return JSON from your script
Echo valid JSON to return structured items:
"success", "time" => time()],
["status" => "success", "time" => time() + 1],
];
echo json_encode($data);
Result: two items with the fields status and time.
Plain text output
Result: one item { "output": "Hello from PHP at 14:05" }.
Work with the current item ($n8nInput)
With the default STDIN injection method the current item arrives pre-decoded in $n8nInput — safe for quotes and any special characters:
"ok", "data" => $n8nInput]);
For an incoming item { "email": "a"b@c.ru" } the result is:
{ "status": "ok", "data": { "email": "a"b@c.ru" } }
Process all items at once (batch mode)
Switch Execution Mode → Run Once for All Items and loop over $n8nItems:
$item["email"], "score" => strlen($item["email"])];
}
echo json_encode($out);
Returning one element per input item keeps the 1:1 pairing intact.
Use workflow context
$n8nContext["workflowName"],
"run" => $n8nContext["runIndex"],
]);
Access incoming data via expressions (legacy)
Set Data Injection Method → Handlebars (Legacy) and use standard n8n expressions in the code field, e.g. {{ $json.email }}, to interpolate values before execution:
"Hello, {{ $json.name }}"]);
> Note: interpolated values are pasted into the PHP source as-is; quotes inside data can break the code. Prefer STDIN.
Security
The Security Level option controls how much the sandbox restricts executed code:
| | Restricted (default) | Unrestricted |
| - | -------------------- | ------------ |
| Shell functions (exec, shellexec, system, passthru, popen, procopen, …) | disabled via disable_functions | allowed |
| Network primitives (fsockopen, streamsocket*, curlinit/curlexec, socketcreate, …) | disabled via disablefunctions | allowed |
| Static analysis of the code before execution | blocks shell calls, backticks and remote URL fetchers (in the main code and additional files) | skipped |
| Remote file access (allowurlfopen / allowurlinclude) | disabled | follows php.ini |
| File access scope | sandbox directory (+ Composer vendor dir if configured) | unrestricted |
| OS user | drops to nobody when n8n runs as root | n8n process user |
| Working directory | /tmp/n8n-php-sandbox | /tmp/n8n-php-sandbox |
| Memory / timeout / output caps | enforced | enforced |
Restricted mode is designed so that even hostile code cannot escape to a shell or read arbitrary paths; use Unrestricted only for fully trusted scripts.
Migrating from 1.x
jsondecode(fileget_contents('php://stdin'), true) with $n8nInput.FILE/DIR pointing at a temp script, note they now resolve to Standard input code.true maps to Restricted, false to Unrestricted; workflows that never saved the option now run Restricted and will block shell functions until you switch them to Unrestricted.42 returns { "output": 42 } as a number).Resources
Version history
2.0.4
@n8n/node-cli 0.44.5 → 0.46.0 and prettier 3.8.3 → 3.9.6; CI workflows use actions/setup-node@v7; docs refreshed.2.0.3
@n8n/node-cli 0.33.1 → 0.44.5 with fixed transitive dependencies (axios, undici, js-yaml, lodash, form-data, minimatch), clearing most Dependabot security alerts; bundled zod resolves to 3.25.76.2.0.2
actions/checkout@v7; dev tooling updated (release-it 21, transitive ip-address 10.5).2.0.1
phpCode resolved for every input item (Restricted mode).fsockopen, streamsocket, curl, socket*).2.0.0
$n8nInput / $n8nItems / $n8nContext variables instead of php://stdin; FILE/DIR resolve to Standard input code.safeMode values are mapped automatically.pairedItem mapping.disablefunctions, remote-file-access off, openbasedir, static pre-execution analysis, privilege drop to nobody under root.executionTimeMs, peakMemoryUsageMb, exitCode) logged and attached under Continue On Fail.1.0.0
php).{ output }.vendor/autoload.php via autoprependfile when the file exists.exec, shellexec, system, passthru, popen, procopen) and confines file access to the temporary script directory (open_basedir).-d memory_limit.pairedItem reference.0.3.0
0.2.0
php is missing from PATH.usableAsTool); dark-theme icon.master, scalar JSON output handling, lint compliance.