PHPackages                             fain182/ext-imap-polyfill - 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. [Mail &amp; Notifications](/categories/mail)
4. /
5. fain182/ext-imap-polyfill

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

fain182/ext-imap-polyfill
=========================

Drop-in polyfill for the imap\_\* functions removed from PHP core in 8.4, built on webklex/php-imap

0.2.0(2d ago)017↓35%MITPHP ^8.1

Since Jul 7Compare

[ Source](https://github.com/fain182/ext-imap-polyfill)[ Packagist](https://packagist.org/packages/fain182/ext-imap-polyfill)[ RSS](/packages/fain182-ext-imap-polyfill/feed)WikiDiscussions Synced today

READMEChangelog (2)Dependencies (3)Versions (3)Used By (0)

ext-imap-polyfill
=================

[](#ext-imap-polyfill)

[![Tests](https://github.com/fain182/ext-imap-polyfill/actions/workflows/tests.yml/badge.svg)](https://github.com/fain182/ext-imap-polyfill/actions/workflows/tests.yml)[![Latest Version](https://camo.githubusercontent.com/481bed2cc7397ce63cce5d86f028c3e145d2ba1871bec0a5136d8a6ba90cdad1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6661696e3138322f6578742d696d61702d706f6c7966696c6c)](https://packagist.org/packages/fain182/ext-imap-polyfill)[![PHP Version](https://camo.githubusercontent.com/4dfbf5cb73a6f2e43ca54b1e29f7881b2075006445db9f175a5a6ac6b83139b3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f6661696e3138322f6578742d696d61702d706f6c7966696c6c2f7068703f6c6162656c3d706870)](https://packagist.org/packages/fain182/ext-imap-polyfill)[![License](https://camo.githubusercontent.com/ef0ec50cdf15f9cb159baaee47351542799a47fe1b9a912575557161802195de/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6661696e3138322f6578742d696d61702d706f6c7966696c6c)](LICENSE)

A drop-in polyfill for the `imap_*` functions removed from PHP core in 8.4.

PHP 8.4 moved `ext-imap` out of core and onto PECL ([RFC](https://wiki.php.net/rfc/unbundle_imap_pspell_oci8)). The C library it wraps (c-client) has been unmaintained since 2007 and is disappearing from Linux distributions, so installing the PECL package is getting harder every release. Codebases built on the `imap_*` functions are usually rewritten against an OOP library like [webklex/php-imap](https://github.com/Webklex/php-imap) instead — a real migration effort, not a version bump.

This package lets you skip that rewrite for the common cases: it defines the same global `imap_*` functions, backed by webklex/php-imap for IMAP and a small raw client for POP3, and only activates if `ext-imap` isn't already loaded. **IMAP and POP3** — unlike the real extension, it doesn't speak NNTP.

Install
-------

[](#install)

```
composer require fain182/ext-imap-polyfill
```

No code changes. If `ext-imap` is present (e.g. you're still on PHP 8.3), the polyfill is a no-op — safe to add before you upgrade, not just after.

Requires PHP 8.1+. The webklex/php-imap dependency declares a handful of extension requirements (`ext-mbstring`, `ext-iconv`, `ext-openssl`, `ext-libxml`, `ext-json`, `ext-fileinfo`, `ext-zip`); all but `ext-zip` are enabled in virtually every PHP build. `ext-zip` is only used by webklex code paths this polyfill never calls, so if you can't (or don't want to) install it:

```
composer require fain182/ext-imap-polyfill --ignore-platform-req=ext-zip
```

The package declares `provide: ext-imap`, so other dependencies that require `ext-imap` install cleanly alongside it.

Usage
-----

[](#usage)

Your existing `imap_*` code runs unchanged:

```
$imap = imap_open('{imap.example.com:993/imap/ssl}INBOX', 'user@example.com', $password);

foreach (imap_search($imap, 'UNSEEN') ?: [] as $msgno) {
    $overview = imap_fetch_overview($imap, (string) $msgno)[0];
    echo "{$overview->from}: {$overview->subject}\n";
}

imap_close($imap);
```

### Connection string flags

[](#connection-string-flags)

In the `{host[:port][/flag...]}folder` mailbox spec, the flags that change behavior are:

- `/ssl` — implicit TLS
- `/tls` — STARTTLS
- `/novalidate-cert` — skip TLS certificate validation
- `/pop3` — connect over POP3 instead of IMAP
- `/readonly` — open the mailbox read-only, same as passing `OP_READONLY`

When no port is given, the default follows the service and encryption, like c-client: IMAP 143 (993 with `/ssl`), POP3 110 (995 with `/ssl`).

Any other flag (`/imap`, `/norsh`, `/secure`, `/debug`, …) is accepted and ignored, so existing connection strings parse fine.

Coverage
--------

[](#coverage)

This is not a reimplementation of all `imap_*` functions — **65 of 75 (87%)** are implemented, chosen to cover the common path of connecting, reading, and moderating a mailbox. The missing ten are ACL and quota management (`imap_getacl`, `imap_setacl`, `imap_get_quota`, `imap_get_quotaroot`, `imap_set_quota`), scanning mailboxes by text content (`imap_scan`, `imap_scanmailbox`, `imap_listscan`), and outbound mail (`imap_mail`, `imap_mail_compose`). Calling any of them will simply hit PHP's "undefined function" error, same as before this package existed.

Every implemented function's object/array shape (property names, casing, flag semantics) is checked against the real extension — see [Verifying against real ext-imap](#verifying-against-real-ext-imap) below. Known, deliberate divergences are called out in the notes column; anything not noted is expected to match exactly.

FunctionImplementedNotes`imap_8bit`✅`imap_alerts`✅never populated — this polyfill doesn't surface server `* OK [ALERT]` responses`imap_append`✅`imap_base64`✅`imap_binary`✅wraps output at 60 chars/line like c-client's `rfc822_binary``imap_body`✅`imap_bodystruct`✅msgno-only, never uid — c-client's `mail_body()` has no UID equivalent, unlike `imap_fetchbody()``imap_check`✅`Mailbox` property echoes the input spec rather than the c-client-normalized form`imap_clearflag_full`✅`imap_close`✅`imap_create`✅`imap_createmailbox`✅`imap_delete`✅`imap_deletemailbox`✅`imap_errors`✅`imap_expunge`✅`imap_fetchbody`✅`imap_fetchheader`✅`imap_fetchmime`✅`imap_fetch_overview`✅`imap_fetchstructure`✅`imap_fetchtext`✅alias of `imap_body``imap_gc`✅this polyfill keeps no cache, so once the flags bitmask is validated it's a no-op that always returns `true`, like the real extension`imap_getacl`❌`imap_getmailboxes`✅`imap_get_quota`❌`imap_get_quotaroot`❌`imap_getsubscribed`✅`imap_headerinfo`✅`fetchfrom`/`fetchsubject` (nonzero `$from_length`/`$subject_length`) not implemented`imap_headers`✅custom user-defined flags (the `{flag}` segment) are never populated, since this polyfill doesn't track them`imap_is_open`✅`imap_last_error`✅`imap_list`✅`imap_listmailbox`✅alias of `imap_list``imap_listscan`❌`imap_listsubscribed`✅alias of `imap_lsub``imap_lsub`✅`imap_mail`❌`imap_mailboxmsginfo`✅`Mailbox` property echoes the input spec rather than the c-client-normalized form`imap_mail_compose`❌`imap_mail_copy`✅`imap_mail_move`✅copies and marks the source `\Deleted` without expunging, like c-client; target is a bare folder name`imap_mime_header_decode`✅`imap_msgno`✅`imap_mutf7_to_utf8`✅`imap_num_msg`✅`imap_num_recent`✅cached client-side read, like `imap_num_msg``imap_open`✅of the `$flags` bitmask, only `OP_READONLY` and `CL_EXPUNGE` change behavior — the other `OP_*` flags are validated, then ignored; the `$options` argument (e.g. `DISABLE_AUTHENTICATOR`) is ignored`imap_ping`✅`imap_qprint`✅`imap_rename`✅`imap_renamemailbox`✅`imap_reopen`✅only switches folders on the same connection — can't reconnect to a different host, since credentials aren't retained after `imap_open``imap_rfc822_parse_adrlist`✅`imap_rfc822_parse_headers`✅`imap_rfc822_write_address`✅`imap_savebody`✅accepts a file path or an open stream resource; like the real extension, returns `true` regardless of whether the section fetch itself found anything, as long as the destination could be opened`imap_scan`❌`imap_scanmailbox`❌`imap_search`✅`imap_setacl`❌`imap_setflag_full`✅`imap_set_quota`❌`imap_sort`✅`SORTSUBJECT` strips a leading `Re:`/`Fwd:` for comparison, not the full RFC5256 base-subject algorithm`imap_status`✅`imap_subscribe`✅`imap_thread`✅duplicate Message-IDs aren't given synthetic unique IDs`imap_timeout`✅`imap_uid`✅`imap_undelete`✅`imap_unsubscribe`✅`imap_utf7_decode`✅`imap_utf7_encode`✅`imap_utf8`✅`imap_utf8_to_mutf7`✅Limitations
-----------

[](#limitations)

Cross-cutting divergences from the real extension (per-function ones are in the coverage table's notes column):

- **No NNTP**: `{host/nntp}` is parsed but ignored — the connection silently falls back to IMAP instead of talking NNTP.
- **POP3** support mirrors real ext-imap's own treatment of POP3: a single mailbox always named `INBOX`, `SEARCH`/`STATUS`/`BODYSTRUCTURE` synthesized client-side, flags lasting only for the lifetime of the connection, and copy/move/append/mailbox-management failing outright. The one divergence: `imap_search()`'s criteria grammar over POP3 is a practical subset (`ALL`, the `SEEN`/`ANSWERED`/`DELETED`/`FLAGGED` pairs, `FROM`/`TO`/`SUBJECT`/`BODY`/`TEXT` substring match, `SINCE`/`BEFORE`/`ON`), not the full RFC3501 grammar.
- **Warnings** are raised as `E_USER_WARNING`, not `E_WARNING` — userland code can't raise the exact error level the C extension uses.

Development
-----------

[](#development)

```
make install          # composer install
make test-unit        # pure-PHP tests, no server needed
make test-integration  # spins up a disposable Greenmail IMAP+POP3 server, runs the full suite against it
make test              # both of the above
```

Docker or Podman is required for `test-integration` (a `docker-compose.yml` is included for the equivalent setup with compose tooling).

### Verifying against real ext-imap

[](#verifying-against-real-ext-imap)

`make parity` runs the exact same integration suite a second time, in a PHP 8.3 container with the genuine `ext-imap` extension installed from source, against the same Greenmail fixture. This is the real check that this polyfill's shapes and behavior actually match the extension it's replacing, not just internally-consistent test assertions.

```
make parity
```

This requires building a container image (`Dockerfile.parity`) the first time, which takes a few minutes.

License
-------

[](#license)

MIT

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance99

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

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 ~0 days

Total

2

Last Release

2d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5879?v=4)[Pietro Campagnano](/maintainers/fain182)[@fain182](https://github.com/fain182)

---

Tags

compatibilitypolyfillmailimapext-imap

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/fain182-ext-imap-polyfill/health.svg)

```
[![Health](https://phpackages.com/badges/fain182-ext-imap-polyfill/health.svg)](https://phpackages.com/packages/fain182-ext-imap-polyfill)
```

###  Alternatives

[php-imap/php-imap

Manage mailboxes, filter/get/delete emails in PHP (supports IMAP/POP3/NNTP)

1.7k13.4M52](/packages/php-imap-php-imap)[ddeboer/imap

Object-oriented IMAP for PHP

9364.1M15](/packages/ddeboer-imap)[webklex/php-imap

PHP IMAP client

4466.7M30](/packages/webklex-php-imap)[directorytree/imapengine

A fully-featured IMAP library -- without the PHP extension

551284.6k9](/packages/directorytree-imapengine)[roopz/yii2-imap

yii2 extension to read and process mails from IMAP and PHP

4098.0k](/packages/roopz-yii2-imap)[henrique-borba/php-sieve-manager

A modern (started in 2022) PHP library for the ManageSieve protocol (RFC5804) to create/edit Sieve scripts (RFC5228). Used by Cypht Webmail.

28142.6k4](/packages/henrique-borba-php-sieve-manager)

PHPackages © 2026

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