PHPackages                             qdenka/ultimatelinkchecker - 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. [Security](/categories/security)
4. /
5. qdenka/ultimatelinkchecker

ActiveLibrary[Security](/categories/security)

qdenka/ultimatelinkchecker
==========================

A powerful PHP library for checking links against multiple security services

2.0(3mo ago)31MITPHPPHP ^8.1CI passing

Since May 14Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/QDenka/UltimateLinkChecker)[ Packagist](https://packagist.org/packages/qdenka/ultimatelinkchecker)[ RSS](/packages/qdenka-ultimatelinkchecker/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (12)Versions (5)Used By (0)

Ultimate Link Checker
=====================

[](#ultimate-link-checker)

[![License](https://camo.githubusercontent.com/811b13ffa2112cead3bf31c671aaea7da106521a75de92d3edb1cd0ed1b86757/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7164656e6b612f756c74696d6174656c696e6b636865636b6572)](https://camo.githubusercontent.com/811b13ffa2112cead3bf31c671aaea7da106521a75de92d3edb1cd0ed1b86757/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7164656e6b612f756c74696d6174656c696e6b636865636b6572)[![PHP Version](https://camo.githubusercontent.com/f870cee2a2e2a442c6b62c8bf79f45ec0ce794dc5af13834902518c9107230f9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e312532422d626c75652e737667)](https://camo.githubusercontent.com/f870cee2a2e2a442c6b62c8bf79f45ec0ce794dc5af13834902518c9107230f9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e312532422d626c75652e737667)

A powerful, flexible PHP library for checking links against multiple security services.

Features
--------

[](#features)

- 🔍 Check URLs against multiple security services with a unified API
- 🚀 Supports Google Safe Browsing, Yandex Safe Browsing, Facebook, VirusTotal, and more
- ⚡ Asynchronous checking capability with Promise-based API
- 🔧 Easily extensible to add new providers
- 💾 Optional caching of results to reduce API calls
- 📊 Detailed threat information and comprehensive reports
- 🔄 Configurable retry logic with incremental backoff
- 📝 PSR-3 compatible logging

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

[](#installation)

```
composer require qdenka/ultimatelinkchecker
```

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

[](#requirements)

- PHP 8.1 or higher
- Composer
- API keys for the services you want to use

Quick Start
-----------

[](#quick-start)

```
use Qdenka\UltimateLinkChecker\UltimateLinkChecker;
use Qdenka\UltimateLinkChecker\Provider\GoogleSafeBrowsingProvider;

// Create the link checker with a provider
$checker = new UltimateLinkChecker();
$checker->addProvider(new GoogleSafeBrowsingProvider('your-api-key'));

// Check a single URL
$result = $checker->check('https://example.com');

// Check if it's safe
if ($result->isSafe()) {
    echo "The URL is safe!";
} else {
    echo "Threats found:" . PHP_EOL;
    foreach ($result->getThreats() as $providerName => $threats) {
        foreach ($threats as $threat) {
            echo "  [{$providerName}] " . $threat->getDescription() . PHP_EOL;
        }
    }
}

// Check multiple URLs at once
$results = $checker->checkBatch([
    'https://example.com',
    'https://another-example.com'
]);

foreach ($results as $url => $result) {
    echo "$url: " . ($result->isSafe() ? "Safe" : "Unsafe") . PHP_EOL;
}
```

Using Multiple Providers
------------------------

[](#using-multiple-providers)

```
use Qdenka\UltimateLinkChecker\UltimateLinkChecker;
use Qdenka\UltimateLinkChecker\Provider\GoogleSafeBrowsingProvider;
use Qdenka\UltimateLinkChecker\Provider\YandexSafeBrowsingProvider;
use Qdenka\UltimateLinkChecker\Provider\VirusTotalProvider;

$checker = new UltimateLinkChecker();

// Add multiple providers
$checker->addProvider(new GoogleSafeBrowsingProvider('google-api-key'));
$checker->addProvider(new YandexSafeBrowsingProvider('yandex-api-key'));
$checker->addProvider(new VirusTotalProvider('virustotal-api-key'));

// Check against all providers
// CONSENSUS_ANY = unsafe if ANY provider flags it (strictest, default)
// CONSENSUS_ALL = unsafe only if ALL providers flag it (most lenient)
// CONSENSUS_MAJORITY = unsafe if majority flags it
$result = $checker->check(
    url: 'https://example.com',
    consensus: UltimateLinkChecker::CONSENSUS_ANY
);

if ($result->isSafe()) {
    echo "The URL is considered safe by the selected consensus method";
} else {
    echo "The URL is unsafe" . PHP_EOL;

    foreach ($result->getThreats() as $providerName => $threats) {
        foreach ($threats as $threat) {
            echo "  [{$providerName}] " . $threat->getDescription() . PHP_EOL;
        }
    }
}
```

Asynchronous Checking
---------------------

[](#asynchronous-checking)

```
use Qdenka\UltimateLinkChecker\UltimateLinkChecker;
use Qdenka\UltimateLinkChecker\Provider\GoogleSafeBrowsingProvider;
use Qdenka\UltimateLinkChecker\Provider\YandexSafeBrowsingProvider;

$checker = new UltimateLinkChecker();
$checker->addProvider(new GoogleSafeBrowsingProvider('google-api-key'));
$checker->addProvider(new YandexSafeBrowsingProvider('yandex-api-key'));

// Get promises for multiple URLs
$promises = $checker->checkBatchAsync([
    'https://example1.com',
    'https://example2.com',
    'https://example3.com',
]);

// Process results as they come in
foreach ($promises as $url => $promise) {
    $promise->then(
        function ($result) use ($url) {
            echo "$url is " . ($result->isSafe() ? "safe" : "unsafe") . PHP_EOL;
        },
        function ($error) use ($url) {
            echo "Error checking $url: " . $error->getMessage() . PHP_EOL;
        }
    );
}
```

Available Providers
-------------------

[](#available-providers)

ProviderClassDescriptionGoogle Safe Browsing`GoogleSafeBrowsingProvider`Google's threat databaseYandex Safe Browsing`YandexSafeBrowsingProvider`Yandex's threat databaseVirusTotal`VirusTotalProvider`Multi-engine antivirus aggregatorFacebook URL Security`FacebookProvider`Facebook URL sharing safetyPhishTank`PhishTankProvider`Community phishing databaseOPSWAT MetaDefender`OPSWATProvider`Multi-scanning URL reputationCisco Talos`CiscoTalosProvider`Cisco threat intelligenceIPQualityScore`IPQualityScoreProvider`URL reputation scoringUsing the Provider Factory
--------------------------

[](#using-the-provider-factory)

```
use Qdenka\UltimateLinkChecker\Factory\ProviderFactory;
use Qdenka\UltimateLinkChecker\UltimateLinkChecker;

$checker = new UltimateLinkChecker();

// Create providers by name with optional timeout and retries
$checker->addProvider(ProviderFactory::createProvider('google_safebrowsing', 'api-key', timeout: 10.0, retries: 2));
$checker->addProvider(ProviderFactory::createProvider('virustotal', 'api-key'));
$checker->addProvider(ProviderFactory::createProvider('facebook', 'app_id|app_secret'));

// List all available providers
$available = ProviderFactory::getAvailableProviders();
```

Creating Your Own Provider
--------------------------

[](#creating-your-own-provider)

```
use Qdenka\UltimateLinkChecker\Contract\ProviderInterface;
use Qdenka\UltimateLinkChecker\Result\CheckResult;
use Qdenka\UltimateLinkChecker\Result\Threat;

class MyCustomProvider implements ProviderInterface
{
    public function getName(): string
    {
        return 'my_custom_provider';
    }

    public function check(string $url): CheckResult
    {
        $result = new CheckResult($url);

        // Your implementation to check the URL
        $isSafe = true; // Your logic here

        if (!$isSafe) {
            $threat = new Threat(
                type: 'MALWARE',
                platform: 'ANY_PLATFORM',
                description: 'This URL contains malware'
            );
            $result->addThreat($this->getName(), $threat);
        }

        return $result;
    }

    public function checkBatch(array $urls): array
    {
        $results = [];
        foreach ($urls as $url) {
            $results[$url] = $this->check($url);
        }
        return $results;
    }
}
```

Advanced Configuration
----------------------

[](#advanced-configuration)

```
use Qdenka\UltimateLinkChecker\UltimateLinkChecker;
use Qdenka\UltimateLinkChecker\Provider\GoogleSafeBrowsingProvider;
use Qdenka\UltimateLinkChecker\Cache\RedisCacheAdapter;
use Qdenka\UltimateLinkChecker\Config\CheckerConfig;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// Create a PSR-3 logger
$logger = new Logger('link-checker');
$logger->pushHandler(new StreamHandler('path/to/your.log'));

// Create a configuration
$config = new CheckerConfig();
$config->setCacheAdapter(new RedisCacheAdapter($redisClient));
$config->setCacheTtl(3600); // Cache results for 1 hour
$config->setTimeout(5.0); // 5 second timeout for API calls
$config->setRetries(2); // Retry failed API calls twice
$config->setLogger($logger); // PSR-3 logger

// Create checker with config
$checker = new UltimateLinkChecker($config);

// Create providers with timeout/retries from config
$checker->addProvider(new GoogleSafeBrowsingProvider(
    apiKey: 'api-key',
    timeout: $config->getTimeout(),
    retries: $config->getRetries()
));

// Now all checks will use the configured cache, timeout, and logging settings
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

License
-------

[](#license)

This project is licensed under the MIT License - see the LICENSE file for details.

Credits
-------

[](#credits)

Created with ❤️ by [qdenka](https://github.com/qdenka)

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance82

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 91.7% 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 ~269 days

Total

2

Last Release

98d ago

Major Versions

1.0 → 2.02026-02-08

### Community

Maintainers

![](https://www.gravatar.com/avatar/3339fb58d7742b5f4ce6a647b09c74739d28b9ecfc85ffb5de6d2f04b6985b82?d=identicon)[qdenka](/maintainers/qdenka)

---

Top Contributors

[![QDenka](https://avatars.githubusercontent.com/u/77678360?v=4)](https://github.com/QDenka "QDenka (11 commits)")[![denkaq](https://avatars.githubusercontent.com/u/125537746?v=4)](https://github.com/denkaq "denkaq (1 commits)")

---

Tags

urlchecklinksecurityvirustotalmalwarephishingsafebrowsing

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/qdenka-ultimatelinkchecker/health.svg)

```
[![Health](https://phpackages.com/badges/qdenka-ultimatelinkchecker/health.svg)](https://phpackages.com/packages/qdenka-ultimatelinkchecker)
```

###  Alternatives

[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[sylius/sylius

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

8.4k5.6M651](/packages/sylius-sylius)[kreait/firebase-php

Firebase Admin SDK

2.4k39.7M72](/packages/kreait-firebase-php)[aporat/store-receipt-validator

PHP receipt validator for Apple App Store and Amazon Appstore

6503.9M9](/packages/aporat-store-receipt-validator)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6939.5M343](/packages/drupal-core-recommended)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k20](/packages/civicrm-civicrm-core)

PHPackages © 2026

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