PHP-ETL - Operations
Building Blocks - If
The IfConfig operation evaluates a Rule Engine condition against the item’s data and routes it to exactly
one sub-chain based on the result — then when the condition is met, else (if configured) otherwise.
Unlike Split, only one branch ever runs for a given item, so that branch is free to transform or replace the
item; there’s no risk of conflicting modifications from branches running in parallel.
Key characteristics:
- Evaluates a condition using a typed
RuleConfigInterfaceor anExpression— same options asFilterDataConfig - Routes the item to exactly one of
then/else— never both - The chosen branch can freely modify the item, since no other branch runs alongside it
elseis optional — without it, a not-met condition just lets the item continue unchanged- Useful for branching logic within a single step, instead of filtering the item out entirely
Configuration
use Oliverde8\Component\PhpEtl\OperationConfig\IfConfig;
use Oliverde8\Component\PhpEtl\ChainConfig;
use Oliverde8\Component\RuleEngine\RuleConfig\GetRuleConfig;
$ifConfig = new IfConfig(
then: $thenChainConfig, // ChainConfig run when the condition evaluates truthy
rules: new GetRuleConfig('IsSubscribed'), // Typed rule, evaluated against the item's data
else: $elseChainConfig, // Optional ChainConfig run otherwise
negate: false, // Optional: invert the condition result
isolateContext: false // Optional: isolate the chosen branch's context from the parent
);
For a simple boolean condition, an Expression is often less verbose than a typed rule — a Symfony Expression Language string evaluated against data (the item’s data) and context (the execution context’s parameters):
use Oliverde8\Component\PhpEtl\Expression\Expression;
$ifConfig = new IfConfig(
then: $thenChainConfig,
rules: new Expression('data["Country"] == "US"'),
else: $elseChainConfig,
);
Parameters:
then: AChainConfigrun when the condition evaluates truthy (or falsy, ifnegateistrue)rules: ARuleConfigInterfaceor anExpression— same options asFilterDataConfig. A plain array is also accepted but deprecated, see Legacy Array Syntaxelse: An optionalChainConfigrun otherwise. Without it, the item just continues to the next step unchangednegate: Inverts the condition result. DefaultfalseisolateContext: Whentrue, the chosen branch runs against its own clone of the execution context instead of the parent’s. Defaultfalse
Isolating Context
By default, all branches share the same execution context as the main chain — a parameter set with
$context->setParameter() inside one branch is visible in every other branch and in the main chain once the
conditional is done. Pass isolateContext: true to give each branch its own independent copy instead:
$ifConfig = new IfConfig(
// ...
isolateContext: true
);
Branches can then no longer see each other’s context changes, and nothing leaks back to the main chain. The file system and logger stay shared — only context parameters are isolated.
See Execution Context for more.
Example: Different Handling for Subscribed Customers
use Oliverde8\Component\PhpEtl\ChainConfig;
use Oliverde8\Component\PhpEtl\OperationConfig\Extract\CsvExtractConfig;
use Oliverde8\Component\PhpEtl\OperationConfig\IfConfig;
use Oliverde8\Component\PhpEtl\OperationConfig\Transformer\RuleTransformConfig;
use Oliverde8\Component\PhpEtl\OperationConfig\Loader\CsvFileWriterConfig;
use Oliverde8\Component\RuleEngine\RuleConfig\GetRuleConfig;
$chainConfig = new ChainConfig();
$chainConfig
->addLink(new CsvExtractConfig())
->addLink(new IfConfig(
rules: new GetRuleConfig('IsSubscribed'),
then: (new ChainConfig())
->addLink((new RuleTransformConfig(false))
->addColumn('status', [['constant' => ['value' => 'subscribed']]])
),
else: (new ChainConfig())
->addLink((new RuleTransformConfig(false))
->addColumn('status', [['constant' => ['value' => 'not-subscribed']]])
)
))
->addLink(new CsvFileWriterConfig('customers-tagged.csv'));
Result: Every row continues to customers-tagged.csv, tagged subscribed or not-subscribed depending on
the branch it went through — a single output stream shaped differently per item, which Split can’t do since
neither of its branches could modify the item without racing the other.
Common Use Cases
- Conditional transformation: Apply different transformation rules depending on the item’s data
- Conditional side effects: Only call an API, log, or write to a file when a condition is met
- Data normalization: Fill in defaults or fix up data only for the records that need it