# How SunLicense Checks for Duplicate License Keys in PHP

> Discover how SunLicense prevents duplicate license keys in PHP. Learn about its internal $keys property and efficient check() method using in_array for robust license management.

- Repository: [Mehmet Selcuk Batal/php-license-key-generator](https://github.com/msbatal/php-license-key-generator)
- Tags: internals
- Published: 2026-03-07

---

**The `SunLicense` class detects duplicate license keys by storing every generated key in the public `$keys` property and using the private `check()` method with `in_array()` to perform a linear search through the key history.**

The `msbatal/php-license-key-generator` repository provides a lightweight PHP solution for generating license keys. Understanding how the `SunLicense` class prevents duplicate keys requires examining its internal storage mechanism and validation logic implemented in [`SunLicense.php`](https://github.com/msbatal/php-license-key-generator/blob/main/SunLicense.php).

## The Duplicate Detection Architecture

The duplicate checking system relies on two core components: a public property that tracks all generated keys and a private method that validates new candidates against this history.

### The $keys Storage Property

The `SunLicense` class maintains a public property `$keys` that serves as an internal registry. Every successfully generated license key is appended to this array, creating a complete history of all keys produced during the instance lifecycle.

```php
public $keys = [];

```

This property is populated during the `generate()` method execution, providing the data source against which duplicate checks are performed.

### The check() Method Implementation

Located at lines 106-112 in [`SunLicense.php`](https://github.com/msbatal/php-license-key-generator/blob/main/SunLicense.php), the private `check()` method performs the actual duplicate validation using PHP's `in_array()` function:

```php
private function check($key = null) {
    if (in_array($key, $this->keys)) {
        return true;            // key was generated before
    }
    return false;               // key is new
}

```

The method performs a **linear search** through `$this->keys`, returning `true` if the supplied `$key` matches any previously stored entry. This O(n) complexity approach is sufficient for typical license key generation volumes but becomes less efficient as the key history grows.

## How the generate() Method Uses Duplicate Checking

The `generate()` method implements a generation loop intended to prevent duplicates from entering the final output. However, examining the implementation at lines 121-124 reveals a critical logic issue:

```php
$key = null;
while (!$this->check($key) && count($this->keys) < $this->keyCount) {
    $this->keys[] = $this->license();   // generate and store a new key
}

```

**Critical Implementation Detail:** The variable `$key` is initialized as `null` and never updated inside the loop. Consequently, `check()` receives `null` on every iteration rather than the newly generated key. Since `null` is unlikely to exist in the `$keys` array (unless explicitly added), `check()` consistently returns `false`, and the loop terminates only when the desired key count is reached.

This means **the current implementation does not actually prevent duplicate keys** — the duplicate detection logic exists but is bypassed due to the missing parameter assignment.

### Corrected Implementation Example

To properly utilize the duplicate checking mechanism, the `generate()` method should pass the candidate key to `check()` before storage:

```php
while (count($this->keys) < $this->keyCount) {
    $candidate = $this->license();
    if (!$this->check($candidate)) {
        $this->keys[] = $candidate;   // only store if not a duplicate
    }
}

```

This modification ensures that `in_array()` actually compares the generated key against the existing registry, preventing duplicates from entering the `$keys` array.

## Practical Usage Examples

### Basic Key Generation

```php
require 'SunLicense.php';

$lic = new SunLicense();          // default settings
$key = $lic->generate();          // returns a string
echo $key;

```

### Generating Multiple Keys with Custom Parameters

```php
require 'SunLicense.php';

$lic = new SunLicense('MYAPP', null, 'upper', 5);
$keys = $lic->generate();        // returns an array of 5 keys
print_r($keys);

```

## Summary

- The `SunLicense` class tracks generated keys in the public `$keys` property.
- Duplicate detection relies on the private `check()` method using `in_array()` to perform linear searches through the key history.
- The `check()` method is located at lines 106-112 in [`SunLicense.php`](https://github.com/msbatal/php-license-key-generator/blob/main/SunLicense.php) and returns `true` for duplicates, `false` for new keys.
- The current `generate()` implementation contains a logic error where `null` is passed to `check()` instead of the candidate key, effectively bypassing duplicate detection.
- To properly prevent duplicates, the generation loop must pass each candidate key to `check()` before adding it to the `$keys` array.

## Frequently Asked Questions

### How does SunLicense store previously generated keys?

The class maintains a public array property named `$keys` that accumulates every license key produced during the instance lifecycle. When you call the `generate()` method, new keys are appended to this array, creating a complete registry that the `check()` method searches when evaluating duplicates.

### What algorithm does the check() method use to find duplicates?

The `check()` method utilizes PHP's built-in `in_array()` function, which performs a **linear search** (O(n) complexity) through the `$keys` array. It compares the candidate key against each stored entry using loose equality checking by default, returning `true` immediately upon finding a match or `false` if the search completes without finding the key.

### Why doesn't the current implementation prevent duplicate keys?

The `generate()` method initializes `$key = null` but never updates this variable with the actual generated key inside the while loop. Consequently, `check($key)` receives `null` on every iteration rather than the candidate license key. Since `null` typically doesn't exist in the `$keys` array, `check()` always returns `false`, and the loop terminates based solely on count limits without ever detecting duplicates.

### How can I fix the duplicate detection in SunLicense?

To enable proper duplicate checking, modify the `generate()` method to generate the candidate key before the check and pass it to the `check()` method:

```php
while (count($this->keys) < $this->keyCount) {
    $candidate = $this->license();
    if (!$this->check($candidate)) {
        $this->keys[] = $candidate;
    }
}

```

This ensures `in_array()` actually compares the generated key against existing entries, preventing duplicates from entering the final output array.