PHP-ETL - Operations
Building Blocks - Switch
The SwitchConfig operation evaluates several conditions against the item’s data, in the order they were added,
and routes the item to the branch of the first matching case. If none match, it falls back to an optional
default branch, or lets the item continue unchanged. It’s the N-way generalization of If:
If gives you exactly two outcomes (then/else), Switch gives you as many as you need without nesting
If inside If.
Key characteristics:
- Cases are evaluated in order; the first one whose condition matches wins
- Routes the item to exactly one branch — never more than one
- The chosen branch can freely modify the item, since no other branch runs alongside it
defaultis optional — without it, no case matching just lets the item continue unchanged- Each case’s condition is a typed
RuleConfigInterfaceor anExpression— same options asFilterDataConfig/If
Configuration
Build cases fluently with addCase(), mirroring addSplit()/addMerge()/addLink():
use Oliverde8\Component\PhpEtl\OperationConfig\SwitchConfig;
use Oliverde8\Component\PhpEtl\ChainConfig;
use Oliverde8\Component\PhpEtl\Expression\Expression;
$switchConfig = (new SwitchConfig(default: $defaultChainConfig)) // default is optional, like If's `else`
->addCase($usChainConfig, new Expression('data["country"] == "US"'))
->addCase($frChainConfig, new Expression('data["country"] == "FR"'));
$chainConfig->addLink($switchConfig);
Each case can use a typed RuleConfigInterface instead of an Expression:
use Oliverde8\Component\RuleEngine\RuleConfig\GetRuleConfig;
$switchConfig->addCase($chainConfig, new GetRuleConfig('IsPremium'));
Parameters:
default: An optionalChainConfigrun when no case matches. Without it, the item just continues to the next step unchangedisolateContext: Whentrue, the chosen branch runs against its own clone of the execution context instead of the parent’s. Defaultfalse
addCase(ChainConfig $then, RuleConfigInterface|Expression|array $rules = []):
$then: AChainConfigrun when this case’s condition matches$rules: ARuleConfigInterfaceor anExpression, evaluated against the item’s data. A plain array is also accepted but deprecated, see Legacy Array Syntax
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
switch is done. Pass isolateContext: true to give each branch its own independent copy instead:
$switchConfig = new SwitchConfig(
// ...
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: Routing Orders by Country
use Oliverde8\Component\PhpEtl\ChainConfig;
use Oliverde8\Component\PhpEtl\Expression\Expression;
use Oliverde8\Component\PhpEtl\OperationConfig\Extract\CsvExtractConfig;
use Oliverde8\Component\PhpEtl\OperationConfig\SwitchConfig;
use Oliverde8\Component\PhpEtl\OperationConfig\Transformer\RuleTransformConfig;
use Oliverde8\Component\PhpEtl\OperationConfig\Loader\CsvFileWriterConfig;
$chainConfig = new ChainConfig();
$chainConfig
->addLink(new CsvExtractConfig())
->addLink((new SwitchConfig(
default: (new ChainConfig())
->addLink((new RuleTransformConfig(false))
->addColumn('region', [['constant' => ['value' => 'international']]])
)
))
->addCase(
(new ChainConfig())
->addLink((new RuleTransformConfig(false))
->addColumn('region', [['constant' => ['value' => 'north-america']]])
),
new Expression('data["country"] in ["US", "CA", "MX"]')
)
->addCase(
(new ChainConfig())
->addLink((new RuleTransformConfig(false))
->addColumn('region', [['constant' => ['value' => 'europe']]])
),
new Expression('data["country"] in ["FR", "DE", "ES"]')
))
->addLink(new CsvFileWriterConfig('orders-tagged.csv'));
Result: Every row continues to orders-tagged.csv, tagged with a region based on the first matching case —
north-america, europe, or international if nothing matched, all in one output stream.
Common Use Cases
- Multi-way routing: Tag or transform items differently depending on which of several conditions matches
- Replacing nested
If: Flatten what would otherwise beIfnested insideIf’selse, three or more cases deep - Rule-based dispatch: Route items to per-category processing logic (by country, status, tier, type, etc.)