PHPackages                             wingify/wingify-fme-php-sdk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. wingify/wingify-fme-php-sdk

ActiveLibrary[API Development](/categories/api)

wingify/wingify-fme-php-sdk
===========================

Wingify Feature Management and Experimentation server-side SDK for PHP

2.10.0(2w ago)0480↑363%1Apache-2.0PHPCI failing

Since May 30Pushed 2w agoCompare

[ Source](https://github.com/wingify/wingify-fme-php-sdk)[ Packagist](https://packagist.org/packages/wingify/wingify-fme-php-sdk)[ RSS](/packages/wingify-wingify-fme-php-sdk/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (3)Dependencies (15)Versions (4)Used By (1)

Wingify Feature Management and Experimentation SDK for PHP
==========================================================

[](#wingify-feature-management-and-experimentation-sdk-for-php)

[![Latest Stable Version](https://camo.githubusercontent.com/10899769112dc130703861ff9d55464dd545f4c11365891c6e3ebad63f2e4b1a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f77696e676966792f77696e676966792d666d652d7068702d73646b2e7376673f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/wingify/wingify-fme-php-sdk)[![License](https://camo.githubusercontent.com/4601ec8ab013eb59b6f679237f23471df08978780b51d2cd4471cec29a0aadf4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f77696e676966792f77696e676966792d666d652d6e6f64652d73646b3f7374796c653d666f722d7468652d626164676526636f6c6f723d626c7565)](http://www.apache.org/licenses/LICENSE-2.0)

[![CI](https://camo.githubusercontent.com/6034cfb23ca4fcb3d2535d88f4905792534728ef2e46e2002dc36439a82e3072/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f77696e676966792f77696e676966792d666d652d7068702d73646b2f6d61696e2e796d6c3f7374796c653d666f722d7468652d6261646765266c6f676f3d676974687562)](https://github.com/wingify/wingify-fme-php-sdk/actions?query=workflow%3ACI)[![codecov](https://camo.githubusercontent.com/67f65965f1ad17abf618c455b7f50caa34416f03ca3e825c7fd0d6cd9186c2ed/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f77696e676966792f77696e676966792d666d652d7068702d73646b3f746f6b656e3d3831335559594d57474d267374796c653d666f722d7468652d6261646765266c6f676f3d636f6465636f76)](https://codecov.io/gh/wingify/wingify-fme-php-sdk)

Overview
--------

[](#overview)

The **Wingify Feature Management and Experimentation SDK** (Wingify FME PHP SDK) enables PHP developers to integrate feature flagging and experimentation into their applications. This SDK provides full control over feature rollout, A/B testing, and event tracking, allowing teams to manage features dynamically and gain insights into user behavior.

Requirements
------------

[](#requirements)

- **PHP 7.0 and onwards**

Installation
------------

[](#installation)

Install the latest version with

```
composer require wingify/wingify-fme-php-sdk
```

**Existing VWO customers** can keep `composer require wingify/wingify-fme-php-sdk` and `use wingify\Wingify` — see [wingify/wingify-fme-php-sdk on Packagist](https://packagist.org/packages/wingify/wingify-fme-php-sdk).

Basic Usage Example
-------------------

[](#basic-usage-example)

The following example demonstrates initializing the SDK with your account ID and SDK key, setting a user context, checking if a feature flag is enabled, and tracking a custom event.

```
use wingify\Wingify;

$client = Wingify::init([
  'sdkKey' => 'your_sdk_key',
  'accountId' => 'your_account_id',
]);

// set user context
$userContext = [ 'id' => 'unique_user_id'];

// returns a flag object
$getFlag = $client->getFlag('feature_key', $userContext);

// check if flag is enabled
$isFlagEnabled = $getFlag->isEnabled();

// get variable
$variableValue = $getFlag->getVariable('variable_key', 'default-value');

// track event
$trackRes = $client->trackEvent('event_name', $userContext);

// set Attribute
$attributes = [
  'attribute_key' => 'attribute_value'
];
$setAttribute = $client->setAttribute($attributes, $userContext);
```

Advanced Configuration Options
------------------------------

[](#advanced-configuration-options)

To customize the SDK further, additional parameters can be passed to the `init()` API. Here's a table describing each option:

**Parameter****Description****Required****Type****Example**`sdkKey`SDK key for the environment used to initialize the Wingify SDK. You can get this key from your FME application.Yesstring`'32-alpha-numeric-sdk-key'``accountId`Account ID for authentication.Yesstring`'123456'``gatewayService`An object representing configuration for integrating the FME Gateway Service.Noarraysee [Gateway](#gateway) section`proxy`An object representing configuration for routing all SDK network requests through a custom proxy server.NoarraySee [Proxy](#proxy) section`storage`Custom storage connector for persisting user decisions and campaign data.NoarraySee [Storage](#storage) section`logger`Toggle log levels for more insights or for debugging purposes. You can also customize your own transport in order to have better control over log messages.NoarraySee [Logger](#logger) section`Integrations`Callback function for integrating with third-party analytics services.NoobjectSee [Integrations](#integrations) sectionRefer to the [official FME PHP documentation](https://developers.vwo.com/v2/docs/fme-php-install) for additional parameter details.

### User Context

[](#user-context)

The `context` array uniquely identifies users and is crucial for consistent feature rollouts. A typical `context` includes an `id` for identifying the user. It can also include other attributes that can be used for targeting and segmentation, such as `customVariables`, `userAgent` and `ipAddress`.

#### Parameters Table

[](#parameters-table)

The following table explains all the parameters in the `context` array:

**Parameter****Description****Required****Type****Example**`id`Unique identifier for the user.Yesstring`'unique_user_id'``customVariables`Custom attributes for targeting.Noarray`['age' => 25, 'location' => 'US']``userAgent`User agent string for identifying the user's browser and operating system.Nostring`'Mozilla/5.0 ... Safari/537.36'``ipAddress`IP address of the user.Nostring`'1.1.1.1'``bucketingSeed`Custom seed for bucketing logic instead of user ID.Nostring`'custom_seed_value'``platformVariables`Optional context payload mapping. Used for Web testing campaigns.Noarray`['webTestingCampaigns' => '{"122":"1"}']`#### Example

[](#example)

```
$userContext = [
  'id' => 'unique_user_id',
  'customVariables' => ['age' => 25, 'location' => 'US'],
  'userAgent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
  'ipAddress' => '1.1.1.1',
  'bucketingSeed' => 'custom_seed_value', // Optional: overrides userId for bucketing
  'platformVariables' => [
    // Reference example only:
    // In production, fetch campaign assignments using script run in frontend and pass that object to backend as webTestingCampaigns.
    'webTestingCampaigns' => '{"122":"1","130":"2"}'
  ],
];
```

### Web testing pre-segmentation

[](#web-testing-pre-segmentation)

Server-side flag decisions can align with **Web Testing** (browser) experiments. **Campaign assignments are typically read on the frontend** (for example, Wingify/VWO cookies) and sent to your server; pass them in `platformVariables['webTestingCampaigns']` as a map of **campaign ID -&gt; variation ID** (strings), or as a **JSON string** of that object.

Pre-segment rules in the FME dashboard can use the **`campaignVariation`** operator:

Operand patternMeaning`C`User is in campaign `C` (any variation).`!C`User is **not** in campaign `C`.`C_V`User is in campaign `C` with variation `V`.`C_!V`User is in campaign `C` and assigned variation is **not** `V`.Rollout rules evaluate pre-segments from the **first variation** only; A/B testing rules use **campaign-level** segments.

### Basic Feature Flagging

[](#basic-feature-flagging)

Feature Flags serve as the foundation for all testing, personalization, and rollout rules within FME. To implement a feature flag, first use the `getFlag` API to retrieve the flag configuration. The `getFlag` API provides a simple way to check if a feature is enabled for a specific user and access its variables. It returns a feature flag object that contains methods for checking the feature's status and retrieving any associated variables.

ParameterDescriptionRequiredTypeExample`featureKey`Unique identifier of the feature flagYesstring`'new_checkout'``context`Array containing user identification and contextual informationYesarray`['id' => 'user_123']`Example usage:

```
$featureFlag = $client->getFlag('feature_key', $userContext);
$isEnabled = $featureFlag->isEnabled();

if ($isEnabled) {
  echo 'Feature is enabled!';

  // Get and use feature variable with type safety
  $variableValue = $featureFlag->getVariable('feature_variable', 'default_value');
  echo 'Variable value:', $variableValue;
} else {
  echo 'Feature is not enabled!';
}
```

### Custom Event Tracking

[](#custom-event-tracking)

Feature flags can be enhanced with connected metrics to track key performance indicators (KPIs) for your features. These metrics help measure the effectiveness of your testing rules by comparing control versus variation performance, and evaluate the impact of personalization and rollout campaigns. Use the `trackEvent` API to track custom events like conversions, user interactions, and other important metrics:

ParameterDescriptionRequiredTypeExample`eventName`Name of the event you want to trackYesstring`'purchase_completed'``context`Array containing user identification and contextual informationYesarray`['id' => 'user_123']``eventProperties`Additional properties/metadata associated with the eventNoarray`['amount' => 49.99]`Example usage:

```
$client->trackEvent('event_name', $userContext, $eventProperties);
```

See [Tracking Conversions](https://developers.vwo.com/v2/docs/fme-php-metrics#usage) documentation for more information.

### Pushing Attributes

[](#pushing-attributes)

User attributes provide rich contextual information about users, enabling powerful personalization. The `setAttribute` method provides a simple way to associate these attributes with users for advanced segmentation. Here's what you need to know about the method parameters:

ParameterDescriptionRequiredTypeExample`attributeKey`The unique identifier/name of the attribute you want to setYesstring`'plan_type'``attributeValue`The value to be assigned to the attributeYesstring/int/boolean`'premium'`, `25`, `true``context`Array containing user identification and contextual informationYesarray`['id' => 'user_123']`Example usage:

```
$client->setAttribute('attribute_name', 'attribute_value', $userContext);
```

Or

```
$attributes = [
  'attribute_name' => 'attribute_value'
];
$client->setAttribute($attributes, $userContext);
```

See [Pushing Attributes](https://developers.vwo.com/v2/docs/fme-php-attributes#usage) documentation for additional information.

### Generating UUID

[](#generating-uuid)

The `getUUID` method allows you to generate a UUID that gets stored on the platform by providing a `userId` and `accountId`. This UUID is generated using a deterministic algorithm based on the user and account identifiers, ensuring consistent UUID generation for the same user-account combination.

**Parameter****Description****Required****Type****Example**`userId`The unique identifier for the userYesString`'user-123'``accountId`The account IDYesString`'123456'`#### Return Value

[](#return-value)

Returns a UUID string formatted without dashes and in uppercase (e.g., `'CC25A368ADA0542699EAD62489811105'`).

#### Example Usage

[](#example-usage)

```
use wingify\Wingify;

// Generate UUID for a user
$userId = 'user-123';
$accountId = '123456';
$uuid = Wingify::getUUID($userId, $accountId);

echo 'Generated UUID:', $uuid;
// Output: Generated UUID: CC25A368ADA0542699EAD62489811105
```

### Custom Bucketing Seed

[](#custom-bucketing-seed)

By default, the SDK uses the user's `id` to determine which variation or feature a user is bucketed into. The `bucketingSeed` parameter lets you override this behavior by providing a custom string for bucketing calculations.

This is useful when you want to:

- Ensure consistent bucketing across different user identifiers or SDKs
- Group different users into the same bucket by using a shared seed

```
// Two different users bucketed the same way using a shared seed
$context1 = ['id' => 'user_1', 'bucketingSeed' => 'shared_seed'];
$context2 = ['id' => 'user_2', 'bucketingSeed' => 'shared_seed'];

// Both will receive the same variation
$flag1 = $client->getFlag('feature_key', $context1);
$flag2 = $client->getFlag('feature_key', $context2);
```

### Polling Interval Adjustment

[](#polling-interval-adjustment)

The `pollInterval` is an optional parameter that allows the SDK to automatically fetch and update settings from the FME server at specified intervals. Setting this parameter ensures your application always uses the latest configuration.

```
$client = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'pollInterval' => 60000,
]);
```

### Gateway

[](#gateway)

The FME Gateway Service is an optional but powerful component that enhances Wingify FME SDKs. It acts as a critical intermediary for pre-segmentation capabilities based on user location and user agent (UA). By deploying this service within your infrastructure, you benefit from minimal latency and strengthened security for all FME operations.

#### Why Use a Gateway?

[](#why-use-a-gateway)

The Gateway Service is required in the following scenarios:

- When using pre-segmentation features based on user location or user agent.
- For applications requiring advanced targeting capabilities.
- It's mandatory when using any thin-client SDK (e.g., Go).

#### How to Use the Gateway

[](#how-to-use-the-gateway)

The gateway can be customized by passing the `gatewayService` parameter in the `init` configuration.

```
$client = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'gatewayService' => [
    'url' => 'https://custom.gateway.com',
  ],
]);
```

Refer to the [Gateway Documentation](https://developers.vwo.com/v2/docs/gateway-service) for further details.

### Proxy

[](#proxy)

The `proxy` parameter allows you to redirect all SDK network calls through a custom proxy URL. This feature enables you to route all SDK network requests (settings, tracking, etc.) through your own proxy server, providing better control over network traffic and security.

```
$client = Wingify::init([
    'sdkKey' => '32-alpha-numeric-sdk-key',
    'accountId' => 123456,
    'proxy' => [
        'url' => 'http://custom.proxy.com',
        'isUrlNotSecure' => false // be default, it should be true
    ],
]);
```

The `proxy` object accepts the following parameters:

**Parameter****Description****Required****Type****Example**`url`The proxy server URL to route all SDK network requests throughYesstring`'http://localhost:8000'``isUrlNotSecure`Set to `true` if the proxy URL uses HTTP (not HTTPS). Defaults to `false` (HTTPS)Noboolean`true`### Synchronous network calls

[](#synchronous-network-calls)

Synchronous network calls differ from the default (asynchronous or fire-and-forget) tracking behavior by waiting for the tracking request to return a response from the FME server before proceeding with the rest of your application code. By default, the SDK sends tracking network calls in a way that does not block your application, providing maximum throughput and lowest latency for user actions.

**Why is it so?**

- The default asynchronous approach ensures minimal impact on user experience or application response times. Tracking calls are dispatched without waiting for a server response.
- With synchronous calls enabled (`shouldWaitForTrackingCalls => true`), your code will block and wait for the network call to complete, allowing you to detect network errors, retry, and ensure delivery before execution continues.

**When should you use synchronous calls?**

- Use synchronous tracking when tracking data integrity or acknowledgment is critical before user flow continues (e.g., checkout flows, conversion confirmations, or compliance events).
- It is recommended when you need to guarantee that server-side events are delivered, and are willing to trade a slight increase in user-facing latency for this assurance.

You can opt-in to perform network calls synchronously by passing an init parameter.

```
$client = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'shouldWaitForTrackingCalls' => true,
]);
```

Notes:

- In PHP, the default transport for tracking is a non-blocking socket-based call (fire-and-forget).
- When you enable `shouldWaitForTrackingCalls`, the SDK switches to a blocking cURL-based call so your code waits for the response.
- For synchronous (cURL) calls, retry is enabled by default. You can override via `retryConfig` in init:

```
$client = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'shouldWaitForTrackingCalls' => true,
  'retryConfig' => [
    'shouldRetry' => true,        // default: true
    'maxRetries' => 3,            // default: 3
    'initialDelay' => 2,          // seconds; default: 2
    'backoffMultiplier' => 2,     // delays: 2s, 4s, 8s; default: 2
  ],
]);
```

If you want synchronous calls but without retries, set `shouldRetry` to `false`:

```
$client = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'shouldWaitForTrackingCalls' => true,
  'retryConfig' => [
    'shouldRetry' => false,
  ],
]);
```

### Storage

[](#storage)

The SDK operates in a stateless mode by default, meaning each `getFlag` call triggers a fresh evaluation of the flag against the current user context.

To optimize performance and maintain consistency, you can implement a custom storage mechanism by passing a `storage` parameter during initialization. This allows you to persist feature flag decisions in your preferred database system (like Redis, MongoDB, or any other data store).

Key benefits of implementing storage:

- Improved performance by caching decisions
- Consistent user experience across sessions
- Reduced load on your application

The storage mechanism ensures that once a decision is made for a user, it remains consistent even if campaign settings are modified in your FME application. This is particularly useful for maintaining a stable user experience during A/B tests and feature rollouts.

```
class StorageConnector {
   private $map = [];

   public function get($featureKey, $userId) {
    $key = $featureKey . '_' . $userId;
    return isset($this->map[$key]) ? $this->map[$key] : null;
   }

   public function set($data) {
    $key = $data['featureKey'] . '_' . $data['user'];
    // Implement your storage logic here to store the data in your preferred database system using $key
   }
}

// Initialize the StorageConnector
$storageConnector = new StorageConnector();

$client = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'storage' => $storageConnector,
]);
```

### Logger

[](#logger)

The SDK by default logs all `ERROR` level messages to your server console. To gain more control over SDK logging behaviour, you can use the `logger` parameter in the `init` configuration.

**Parameter****Description****Required****Type****Example**`level`Log level to control verbosity of logsYesstring`'DEBUG'``prefix`Custom prefix for log messagesNostring`'CUSTOM LOG PREFIX'``isAnsiColorEnabled`Enable ANSI color codes for log levels in terminal outputNoboolean`true``transport`Custom logger implementationNoarraySee example below#### Example 1: Set log level to control verbosity of logs

[](#example-1-set-log-level-to-control-verbosity-of-logs)

```
$client1 = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'logger' => [
    'level' => 'DEBUG',
  ],
]);
```

#### Example 2: Add custom prefix to log messages for easier identification

[](#example-2-add-custom-prefix-to-log-messages-for-easier-identification)

```
$client2 = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'logger' => [
    'level' => 'DEBUG',
    'prefix' => 'CUSTOM LOG PREFIX',
  ],
]);
```

#### Example 3: Enable ANSI color codes for colored log levels in terminal

[](#example-3-enable-ansi-color-codes-for-colored-log-levels-in-terminal)

```
$client3 = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'accountId' => '123456',
  'logger' => [
    'level' => 'DEBUG',
    'isAnsiColorEnabled' => true, // Enable colored log levels (TRACE, DEBUG, INFO, WARN, ERROR)
  ],
]);
```

Note: ANSI color codes are only applied when `isAnsiColorEnabled` is explicitly set to `true`. This prevents unwanted color codes in log files or non-terminal outputs. When disabled or not set, log levels are displayed as plain text.

#### Example 4: Implement custom transport to handle logs your way

[](#example-4-implement-custom-transport-to-handle-logs-your-way)

The `transport` parameter allows you to implement custom logging behavior by providing your own logging functions. You can define handlers for different log levels (`debug`, `info`, `warn`, `error`, `trace`) to process log messages according to your needs.

For example, you could:

- Send logs to a third-party logging service
- Write logs to a file
- Format log messages differently
- Filter or transform log messages
- Route different log levels to different destinations

The transport object should implement handlers for the log levels you want to customize. Each handler receives the log message as a parameter.

For single transport you can use the `transport` parameter. For example:

```
$client4 = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'logger' => [
    'transport' => [
        'level' => 'DEBUG',
        'logHandler' => function($msg, $level){
          echo "$msg $level";
        }
    ],
  ]
]);
```

For multiple transports you can use the `transports` parameter. For example:

```
$client5 = Wingify::init([
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'logger' => [
    'transports' => [
        [
            'level' => 'DEBUG',
            'logHandler' => function($msg, $level){
              echo "$msg $level";
            }
        ],
        [
            'level' => 'INFO',
            'logHandler' => function($msg, $level){
              echo "$msg $level";
            }
        ]
    ]
  ]
]);
```

### Integrations

[](#integrations)

Wingify FME SDKs provide seamless integration with third-party tools like analytics platforms, monitoring services, customer data platforms (CDPs), and messaging systems. This is achieved through a simple yet powerful callback mechanism that receives SDK-specific properties and can forward them to any third-party tool of your choice.

```
function callback($properties) {
    // properties will contain all the required SDK-specific information
    echo json_encode($properties);
}

$options = [
    'sdkKey' => '32-alpha-numeric-sdk-key', // SDK Key
    'accountId' => '12345', // Account ID
    'integrations' => [
        'callback' => 'callback'
    ]
];

$client = Wingify::init($options);
```

### User Aliasing

[](#user-aliasing)

User aliasing lets you associate an existing user ID with an alternate ID (alias) so future evaluations and tracking use a unified identity across systems.

Requirements:

- Gateway must be configured
- Aliasing must be enabled during initialization: `isAliasingEnabled: true`

Initialization example:

```
$client = Wingify::init([
  'accountId' => '123456',
  'sdkKey' => '32-alpha-numeric-sdk-key',
  'isAliasingEnabled' => true,
  'gatewayService' => [ 'url' => 'https://custom.gateway.com' ],
]);
```

Usage examples:

```
// Using context array
$success1 = $client->setAlias(['id' => 'user-123'], 'alias-abc');

// Using direct userId
$success2 = $client->setAlias('user-123', 'alias-abc');
```

Behavior and validations:

- Returns `true` on success, `false` otherwise
- Requires aliasing to be enabled and gateway configured
- `aliasId` must be a non-empty string (not an array); it is trimmed before use
- When passing context, `context['id']` must be a non-empty string (not an array); it is trimmed before use
- `userId` and `aliasId` cannot be the same

### Version History

[](#version-history)

The version history tracks changes, improvements, and bug fixes in each version. For a full history, see the [CHANGELOG.md](https://github.com/wingify/wingify-fme-php-sdk/blob/master/CHANGELOG.md).

Development and Testing
-----------------------

[](#development-and-testing)

1. Install dependencies and git hooks (commit-msg, pre-commit, pre-push)

```
composer install
composer start
```

2. Run test cases

```
composer run-script test
```

### Contributing

[](#contributing)

Please go through our [contributing guidelines](https://github.com/wingify/wingify-fme-php-sdk/blob/master/CONTRIBUTING.md)

### Code of Conduct

[](#code-of-conduct)

[Code of Conduct](https://github.com/wingify/wingify-fme-php-sdk/blob/master/CODE_OF_CONDUCT.md)

### License

[](#license)

[Apache License, Version 2.0](https://github.com/wingify/wingify-fme-php-sdk/blob/master/LICENSE)

Copyright 2024-2026 Wingify Software Pvt. Ltd.

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance96

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 57.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~17 days

Total

3

Last Release

20d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/45913410?v=4)[Katsuyo](/maintainers/vwo)[@vwo](https://github.com/vwo)

---

Top Contributors

[![Abhishekjoshi2001](https://avatars.githubusercontent.com/u/161469359?v=4)](https://github.com/Abhishekjoshi2001 "Abhishekjoshi2001 (4 commits)")[![Kaustubh22327](https://avatars.githubusercontent.com/u/118050234?v=4)](https://github.com/Kaustubh22327 "Kaustubh22327 (2 commits)")[![Abhi591](https://avatars.githubusercontent.com/u/59906686?v=4)](https://github.com/Abhi591 "Abhi591 (1 commits)")

---

Tags

sdkfmewingify

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/wingify-wingify-fme-php-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/wingify-wingify-fme-php-sdk/health.svg)](https://phpackages.com/packages/wingify-wingify-fme-php-sdk)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.9M754](/packages/sylius-sylius)[knuckleswtf/scribe

Generate API documentation for humans from your Laravel codebase.✍

2.3k14.2M63](/packages/knuckleswtf-scribe)[google/gax

Google API Core for PHP

267116.3M574](/packages/google-gax)[temporal/sdk

Temporal SDK

4072.9M25](/packages/temporal-sdk)[pocketmine/bedrock-protocol

An implementation of the Minecraft: Bedrock Edition protocol in PHP

172445.0k18](/packages/pocketmine-bedrock-protocol)[liamcottle/instagram-sdk-php

This is an unofficial SDK for the Instagram Private API in PHP

1308.4k](/packages/liamcottle-instagram-sdk-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
