Segments Manager
PHP-specific segments handling
ConvertSdk\SegmentsManager is the PHP SDK's implementation of visitor segmentation: it evaluates custom segment rules, filters reporting segments, and persists both through the DataManager so they ride along on tracking payloads.
For the cross-SDK concepts — what a segment is, how it differs from an audience, and when to use each — read Segments first. This page covers the PHP surface: exact signatures, return types, and the stored shape.
Public API
You normally reach the manager through the visitor context rather than directly — see Code Examples → Segments.
| Context method | Delegates to | Returns |
|---|---|---|
setDefaultSegments(array $segments) | putSegments() | void |
runCustomSegments(array $segmentKeys, ?array $attributes = null) | selectCustomSegments() | ?array — the visitor's custom-segment ids, or null |
setCustomSegments(array $segmentKeys, ?array $attributes = null) | runCustomSegments() | Same — deprecated alias |
The manager itself exposes:
namespace ConvertSdk;
class SegmentsManager implements SegmentsManagerInterface
{
public function __construct(
Config $config,
DataManagerInterface $dataManager,
RuleManagerInterface $ruleManager,
?LogManagerInterface $loggerManager = null,
);
public function getSegments(string $visitorId): VisitorSegments;
public function putSegments(string $visitorId, ?array $segments): void;
public function selectCustomSegments(
string $visitorId,
array $segmentKeys,
?array $segmentRule = null,
): VisitorSegments|RuleError|null;
public function selectCustomSegmentsByIds(
string $visitorId,
array $segmentIds,
?array $segmentRule = null,
): VisitorSegments|RuleError|null;
}selectCustomSegments() resolves the segment definitions by key; selectCustomSegmentsByIds() resolves them by id. Both then run the same private matching routine.
Default (reporting) segments
Default segments are the standard dimensions that appear in Convert reports.
$context = $sdk->createContext('user123', ['country' => 'US']);
$context->setDefaultSegments([
'country' => 'US',
'browser' => 'chrome',
'devices' => 'desktop',
'source' => 'organic',
]);Only these keys are recognised — they are the cases of the SegmentsKeys enum:
browser, devices, source, campaign, visitorType, country, plus customSegments for the rule-matched set.
setDefaultSegments() runs its argument through DataManager::filterReportSegments(), which splits the array into recognised segment keys and everything else. Only the recognised keys are persisted — any other key passed here is dropped, and nothing is written at all when none match. (The same filter runs on createContext()'s attributes, but there the unrecognised keys are kept as visitor properties for targeting.)
visitorTypeandcustomSegmentsare camelCase. Earlier releases stored them asvisitor_typeandcustom_segments; the keys were renamed to match the JavaScript SDK and the served config, so a visitor record written by an older SDK version will not have its custom segments read back.
Custom segments
Custom segments are matched by rules rather than assigned directly.
$matched = $context->runCustomSegments(
['premium-users', 'high-value'],
['ruleData' => ['plan' => 'enterprise', 'lifetime_value' => 5000]]
);The rule data goes under a ruleData key — Context::runCustomSegments() reads $attributes['ruleData'], deep-merges it over the visitor's in-memory properties and stored segments, and passes the result to the manager as $segmentRule. A flat array of properties at the top level is ignored.
Returns the visitor's accumulated custom-segment ids as a plain array, or null when nothing new matched. A RuleError from rule evaluation is swallowed at the Context boundary and surfaces as null — call SegmentsManager::selectCustomSegments() directly if you need to distinguish the two.
How matching works
For each resolved segment definition, in order:
- If a
$segmentRulewas supplied and nothing has matched yet, the segment's ownrulestree is evaluated against it viaRuleManager::isRuleMatched(). ARuleErrorshort-circuits the whole call and is returned immediately. - A segment is accepted when there is no
$segmentRuleat all, or once a match has been found. Once one segment matches, the remaining segments in the same call are accepted without evaluating their own rules — pass one key per call if you need each rule tree evaluated independently. - Ids already present in the visitor's stored
customSegmentsare skipped, with a warning logged.
Newly accepted ids are appended to the stored set and persisted; the method returns a VisitorSegments built from the merged data, or null when nothing was added.
Stored shape
Segments live inside the visitor's record in the data store, alongside bucketing decisions:
[
'segments' => [
'country' => 'US',
'browser' => 'chrome',
'devices' => 'desktop',
'visitorType' => 'new',
'customSegments' => ['1001', '1002'], // segment ids, as strings
],
'bucketing' => [ /* experienceId => variationId */ ],
]getSegments() reads that record, re-filters it through filterReportSegments(), and returns a VisitorSegments. putSegments() applies the same filter on write, so an unrecognised key can never enter the store through this path.
Because the PSR-16 cache doubles as the data store, segments persist across requests exactly as far as that cache does — in-memory ArrayCache means per-request only. See Configuration → Persistent DataStore.
Next Steps
- Segments — cross-SDK concepts, segments vs. audiences
- Rule Evaluation & Targeting — how the rule trees these segments use are evaluated
- Return Types — the
SegmentsKeysenum - Code Examples — the Context-level calls
Updated 21 days ago