Introducing the attachmentAV SDK for PHP: Virus and Malware Scans for Your Web Application
PHP still powers a huge share of the web, and a lot of those applications accept files from users: profile pictures, invoices, contracts, support attachments. Every upload is a potential entry point for malware. That’s why I’m happy to announce the attachmentAV SDK for PHP. It joins our SDKs for Java, Python, and JavaScript/TypeScript and makes it easy to add virus and malware scans to your PHP application.

The SDK is open source (MIT license). Find the source code on GitHub and the package on Packagist.
Highlights
- Supports the attachmentAV API (SaaS) and the attachmentAV API (self-hosted on AWS).
- Requires PHP 8.0 or newer.
- Works with any PSR-18 HTTP client. Guzzle, Symfony HttpClient, and others are detected automatically.
- Integrates with Laravel: auto-discovered service provider, facade, config file, and a
VirusFreevalidation rule. - Works with Symfony, Slim, Laminas/Mezzio, CodeIgniter, Yii, CakePHP, and plain PHP.
- Retries throttled requests with exponential backoff.
- Verifies the signatures of callbacks sent by attachmentAV.
Getting started
Install the package with Composer.
composer require attachmentav/virus-scan-sdk
Get an API key by subscribing to the attachmentAV API (SaaS). Then, send your first scan request.
use AttachmentAV\AttachmentAVApi;
use AttachmentAV\Configuration;
use AttachmentAV\Region;
$api = new AttachmentAVApi(Configuration::saas('<API_KEY_PLACEHOLDER>', Region::EU));
$result = $api->scanSyncFile('/path/to/file');
if ($result->isInfected()) {
echo 'Malware detected: ' . $result->getFinding();
}
The scan result tells you whether the file is clean or infected, the name of the detected malware, the file size, and the real file type.
Scan a file by URL
Is the file already stored somewhere else, for example on a web server or behind a pre-signed URL? Use scanSyncDownload() to let attachmentAV download the file and return the scan result right away. Sync download scans support files up to 200 MB.
$result = $api->scanSyncDownload('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf');
echo $result->getStatus(); // 'clean'
If the download requires authentication, pass the headers that attachmentAV should send when downloading the file.
$result = $api->scanSyncDownload('https://example.com/private.pdf', ['Authorization' => 'Bearer ...']);
Scan large files asynchronously
Sync scans have to finish within 60 seconds. For large files of up to 5 GB, use scanAsyncDownload() instead. attachmentAV downloads and scans the file in the background. There are two ways to get the scan result: callback or polling.
With a callback, attachmentAV sends the scan result to your callback URL with an HTTPS POST request. Use customData to pass through your own identifiers.
$api->scanAsyncDownload(
'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
callbackUrl: 'https://api.yourcompany.com/attachmentav/callback',
customData: json_encode(['documentId' => 42])
);
attachmentAV signs every callback. The SDK verifies the signature for you. You need your tenant ID, which you can get once with $api->whoami()->getTenantId().
use AttachmentAV\Callback\CallbackVerifier;
use AttachmentAV\Region;
$verifier = CallbackVerifier::forRegion(Region::EU, '<TENANT_ID_PLACEHOLDER>');
$payload = $verifier->verifyAndParse(
file_get_contents('php://input'),
$_SERVER['HTTP_X_SIGNATURE'] ?? null,
$_SERVER['HTTP_X_TIMESTAMP'] ?? null,
'https://api.yourcompany.com/attachmentav/callback'
); // throws InvalidSignatureException if the signature is invalid
if ($payload->getStatus() === 'infected') {
// quarantine the document referenced in $payload->getCustomData()
}
No public endpoint to receive callbacks? Use polling instead. Pass a trace ID when submitting the scan job and call getAsyncResult() until the result is available.
$traceId = bin2hex(random_bytes(16));
$api->scanAsyncDownload('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf', traceId: $traceId);
do {
sleep(10);
$result = $api->getAsyncResult($traceId); // null until the scan has finished
} while ($result === null);
echo $result->getStatus();
Async scans are available for the attachmentAV API (SaaS). Besides downloading files from a URL, the SDK also scans S3 objects with scanSyncS3() and scanAsyncS3().
About attachmentAV
The attachmentAV Virus and Malware Scan API is the foundation of every attachmentAV solution, from Salesforce and Jira to WordPress and n8n. It is open to every developer who wants to scan files from their own application, with synchronous and asynchronous scan modes. Run it as SaaS, or self-hosted in your own AWS account.
Every file is scanned by the Sophos engine. The threat database is refreshed hourly, and signatures plus advanced detection algorithms catch viruses, worms, trojans, and ransomware, including zero-day threats. There is no antivirus agent to install on your servers, no signature files to distribute, and no scanner to patch.
attachmentAV is made in the EU and available globally. Scanning happens in the jurisdiction you select: Europe (default), United States, Canada, India, or Australia. Files are encrypted in transit and at rest, and deleted immediately after processing. attachmentAV is ISO 27001 certified, GDPR compliant, and an official Sophos OEM partner.
SaaS or self-hosted on AWS
The attachmentAV API comes in two variants: as a fully managed SaaS, or self-hosted in your own AWS account. Both use the same Sophos engine and work with the same SDK. Switching between them only requires a different configuration: Configuration::saas() or Configuration::selfHosted().
| SaaS | Self-hosted on AWS | |
|---|---|---|
| Setup | Get an API key and start scanning within minutes | Deploy to your AWS account in about 15 minutes |
| Operations | Fully managed | Production-ready Infrastructure as Code templates |
| API endpoint | Highly available public endpoint | Public or private endpoint (VPC) |
| Regions | Europe, US, Canada, India, and Australia | 32 AWS regions |
| Data processing | GDPR compliant & ISO 27001 certified | No sub-processor: files stay in your AWS account |
| Scan modes | Sync and async | Sync |
Get started
- Subscribe to the attachmentAV Virus and Malware Scan API to get an API key.
- Install the SDK with
composer require attachmentav/virus-scan-sdk. - Read the documentation on GitHub for more examples.
Your feedback is very welcome. Please open an issue on GitHub or send us an email.
Published on October 16, 2026 | Written by Andreas