
## Why migrate?

* **Performance**: PHP Core evaluates faster than the legacy SDK.
* **New Features**: Access to Parameter Stores, CMAB (Contextual Multi-Armed Bandits), observabilityClient, and more.
* **Future Support**: All new features and improvements are only available in PHP Core.
* **Maintenance**: The legacy PHP SDK is in maintenance mode and only receives critical bug fixes.

## Installation and setup

For the PHP Core SDK, configure `composer.json` to **run the provided `post-install.php` file**:

{% codetabs %}
```bash PHP Core
composer require statsig/statsig-php-core

// composer.json
{
  "name": "awesome-php-project",
  ...
  "scripts": {
    ...
    "post-install-cmd": [
      "cd vendor/statsig/statsig-php-core && php post-install.php"
    ],
    "post-update-cmd": [
      "cd vendor/statsig/statsig-php-core && php post-install.php"
    ]
  }
}
```

```bash PHP Legacy
composer require statsig/statsigsdk
```
{% /codetabs %}

Both require a cron job to fetch configs and flush events:

{% codetabs %}
```bash PHP Core
# Setup chron job / scheduled job to sync config and flush events
*/1 * * * * /usr/bin/php /var/www/example.com/bin/StatsigSyncConfig.php 1>> /dev/null 2>&1
*/1 * * * * /usr/bin/php /var/www/example.com/bin/StatsigFlushEvents.php 1>> /dev/null 2>&1
```

```bash Legacy Php
# Create a cron job that runs as statsigsync every minute
echo '*/1 * * * * statsigsync php /my/path/to/statsig/sync.php --secret <STATSIG_SECRET_KEY> > /dev/null' | sudo tee /etc/cron.d/statsigsync
echo '*/1 * * * * statsigdata php /my/path/to/statsig/send.php --secret <STATSIG_SECRET_KEY> > /dev/null' | sudo tee /etc/cron.d/statsigdata
sudo service cron reload   
```
{% /codetabs %}

## StatsigUser

{% codetabs %}
```php Php Core
// We introduced the user builder pattern
$user_builder = StatsigUserBuilder::withUserID('my_user');
$user_builder->withEmail("example@abc.com");
$user = $user_builder->build()
```

```php PHP Legacy
$user = StatsigUser::withUserID("my_user");
$user = user->setEmail("example@abc.com");
```
{% /codetabs %}

{% callout type="info" %}
For usage of big IDLists (>1000 items id list), contact us before using it in php-core
{% /callout %}

## API changes

### Key package and class changes

| Feature        | Php Core SDK                                    | Legacy Php SDK             | Status                   |
| -------------- | ----------------------------------------------- | -------------------------- | ------------------------ |
| Package        | `statsig/statsig-php-core`                      | `statsig`                  | ⚠️ Renamed               |
| Import         | `use Statsig/Statsig`                           | `use Statsig/Statsig`      | Same                     |
| Options        | `StatsigOptions`                                | `StatsigOptions`           | ✓ Same                   |
| User           | `StatsigUser (With StatsigUserBuilder pattern)` | `StatsigUser`              | Construction api changed |
| Initialize     | `statsig->initialize()`                         | `statsig->initialize()`    | ✓ Same                   |
| Check Gate     | `statsig->checkGate()`                          | `statsig->checkGate()`     | ✓ Same                   |
| Get Config     | `statsig->getDynamicConfig()`                   | `statsig->getConfig()`     | ⚠️ Naming change                  |
| Get Experiment | `statsig->getExperiment()`                      | `statsig->getExperiment()` | ✓ Same                   |
| Get Layer      | `statsig->getLayer()`                           | `statsig->getLayer()`      | ✓ Same                   |
| Log Event      | `statsig->logEvent()`                           | `statsig->logEvent()`      | ✓ Same                   |
| Shutdown       | `statsig->shutdown()`                           | `statsig->shutdown()`      | Same                     |

For more details on the new API, refer to the [PHP Core SDK documentation](/server-core/php-core).

## Behavioral changes

{% accordion-group %}
{% accordion title="User-Agent Parsing" %}
The SDK now uses a lightweight YAML-based User-Agent parser based on a reduced version of the [ua-parser regex definitions](https://github.com/statsig-io/statsig-server-core/blob/00ad0e4024ca5d30f21892c8f2f23e836165a509/statsig-rust/resources/ua_parser_regex_lite.yaml#L4).

This parser supports the following commonly used browsers:

* Chrome
* Firefox & Firefox Mobile
* Safari & Mobile Safari
* Chrome Mobile
* Android
* Edge & Edge Mobile
* IE Mobile
* Opera Mobile

If your use case requires identifying less common browsers, parse the User-Agent externally before sending it to Statsig.
{% /accordion %}

{% accordion title="Lazy Initialization: User-Agent Parser & Country Lookup" %}
User-Agent parsing and country lookup are now **lazy-loaded by default** to improve SDK initialization performance.

If your application requires these features to be ready immediately after `initialize()`, opt in by setting:

* `wait_for_user_agent_init`
* `wait_for_country_lookup_init`

Enabling these options increases total initialization time.

To disable these features entirely, set the `StatsigOptions` flags `disable_user_agent_parsing` and `disable_country_lookup`.
{% /accordion %}

{% accordion title="ID List Feature" %}
The ID List functionality is **disabled by default**.

To enable it, set the `StatsigOptions` flag `enable_id_lists`.
{% /accordion %}

{% accordion title="Endpoint Changes (v1 to v2)" %}
The core SDK now fetches configuration specs from a new endpoint:

* **Old**: `v1/download_config_specs`
* **New**: `v2/download_config_specs`

If you are hosting your own **pass-through proxy**, ensure it supports and correctly routes the `v2` endpoint.

* If you are using the **Statsig Forward Proxy (SFP)**, this endpoint migration is handled automatically.
{% /accordion %}

{% accordion title="Environment Evaluation" %}
There are different places you can define environment StatsigUser and StatsigOptions, server-core try StatsigUser then StatsigOptions, then default to production.
Node SDK has different orders: StatsigOptions -> StatsigUser -> default to production.
{% /accordion %}

{% accordion title="DataStore cache format" %}
**New DataStore cache format**

* **Old**: (Except Node v6+)
  * config_spec cache key is: statsig.cache
  * IDLists statsig.id_lists
* **New**
  * config_spec cache key: `statsig|/v2/download_config_specs|plain_text|{SHA256HashedBase64(secretkey)}`
  * IDLists: We don't support idlist data store.
{% /accordion %}
{% /accordion-group %}

## StatsigOptions changes

The table below shows the mapping between legacy SDK options and Server Core SDK options:

| Old Option | New / Notes |
| ----------------- | ----------- |
| `environmentTier` | Renamed to be `environment` |
| `eventQueueSize` | Renamed to be `event_logging_max_queue_size` |
| `dataAdapter` | Renamed to be `specs_adapter` |
| `logging_adapter` | Renamed to be `event_logging_adapter` |

For a full list of new configuration options, refer to the [PHP Core SDK documentation](/server-core/php-core).

## Recommended migration path

{% steps %}
{% step title="Add the new Dependencies" %}
* Add the new SDK package/module and any required platform-specific dependencies for your environment.
* Update import or require statements to reference the new SDK namespace or module.
* Keep the old package in place during local testing; having both running in parallel briefly can help. Alias the new package if needed.
{% /step %}

{% step title="Update Initialization" %}
* Switch to the new initialization syntax. New SDK keys are not required. If you update them, ensure they have the same target apps.
* Use the appropriate builder or configuration pattern for setting options, and migrate the StatsigOptions you use, because some were renamed.
{% /step %}

{% step title="Update User Creation" %}
* Migrate to the new format for creating user objects.
* Use the builder pattern or updated constructor to set user properties if needed.
{% /step %}

{% step title="Update Method Calls" %}
* Start by migrating a few calls, replacing `oldStatsig.getExperiment()` with `newStatsig.getExperiment()`.
* Test your service locally or with existing test patterns to build confidence in the new SDK's operation.
* As you migrate additional calls, update method names that changed (notably, `get_config()` to `get_dynamic_config()`).
* After completing the initial migration, use refactoring tools to migrate remaining calls in bulk.
{% /step %}

{% step title="Test Thoroughly" %}
* Verify that all of your configs are successfully migrated - run your test suites end-to-end.
{% /step %}

{% step title="Remove old SDK" %}
* Remove references to the old SDK, and clean up old initialization and import logic.
{% /step %}
{% /steps %}

## Need help?

If you encounter any issues during migration, reach out:

* [Statsig Slack Community](https://statsig.com/slack)
* [GitHub Issues](https://github.com/statsig-io/statsig-server-core/issues)
