PEAR

ID

pear

Home page

https://pear.php.net

Version requirement

>= 1.10

Platforms

🅱️ BSD · 🐧 Linux · 🍎 macOS · ⨂ Unix · 🪟 Windows

Operations

installed · outdated · install · upgrade · upgrade_all · remove · sync · cleanup

purl types

pkg:pear

CLI name

pear

Issues and PRs

📦 manager: pear

Source

meta_package_manager/managers/pear.py

The PHP Extension and Application Repository.

PEAR ships with PHP itself and installs libraries into the interpreter’s php_dir, against its own registry at pear.php.net.

Important

Whether that needs root is a property of the PHP install, not of PEAR: a distribution’s php_dir is /usr/share/php and refuses an ordinary user with Cannot install, php_dir for channel "pear.php.net" is not writeable by the current user. So the mutating operations carry privileged markers but leave them dormant, exactly as the other language managers do: mpm --sudo, or a [mpm.managers.pear] sudo = true entry, escalates them.

The better fix is to own the prefix instead. PEAR is fully relocatable, and every role directory has to move together: repointing php_dir alone fails late, on failed to mkdir /usr/share/php/tests/..., because test_dir is a separate setting. With php_dir, bin_dir, data_dir, test_dir, doc_dir, cfg_dir, www_dir, man_dir, temp_dir, download_dir and cache_dir all under one writable prefix, an install needs no privilege at all.

Caution

Every network operation costs one REST round-trip per package, and pear.php.net answers slowly: outdated measured 63 seconds warm and 105 seconds cold against a host carrying only six packages, so it approaches mpm’s 120-second read-only cap on an inventory barely larger. Raise mpm --timeout on a host with more. installed is unaffected, reading the local registry with no network at all.

Note

search is not implemented. pear search resolves through the same per-package REST walk (PEAR_REST_10::listAll() with its $basic parameter false, one p/<name>/info.xml fetch apiece), and no run of it here ever returned: two attempts were abandoned after 15 and 30 minutes, the second having reached “50%”. remote-list is no way around it either, costing 524 seconds on a cold cache. Both are far past the read-only cap, so mpm skips the operation and install falls through to installing the named package directly.

Note

A package is reported under its bare name, the spelling pear install takes. PEAR identities are really channel-qualified ([channel/]package), so two channels shipping the same name would collapse onto one entry; in practice pear.php.net is the only populated one.

Documentation: PEAR manual.

What mpm adds to pear

mpm reaches across every manager at once, not pear alone: mpm installed and mpm outdated cover pear alongside every other manager you run in one table, mpm upgrade --all updates them together, and mpm sbom exports the whole machine as one bill of materials.

Every mpm command also gains --dry-run and --plan previews, cross-scheme version comparison and purl identifiers. See manager augmentations for how each one is built.

Your pear commands, in mpm

You already know pear: each operation maps one-to-one onto mpm, in an interface shared by every manager.

To…

With pear

With mpm

List what’s installed

pear list --allchannels

mpm --pear installed

List outdated packages

pear list-upgrades

mpm --pear outdated

Install a package

pear install Text_Password

mpm install pkg:pear/Text_Password

Upgrade one package

pear upgrade Text_Password

mpm --pear upgrade Text_Password

Upgrade everything

pear upgrade

mpm --pear upgrade --all

Remove a package

pear uninstall Text_Password

mpm remove pkg:pear/Text_Password

Clear caches

pear clear-cache

mpm --pear cleanup --cache

Prefix any command above with --dry-run to simulate the underlying manager calls without touching the system: the safe way to watch what mpm would do before trusting it.

Operations

Operation

Supported

installed

outdated

orphans

search

install

upgrade

upgrade_all

remove

sync

cleanup

doctor

Selecting and configuring pear

Deselect pear for a single run with --no-pear, or persist the choice in your configuration:

[mpm]
pear = false

Keep it enabled but tune how mpm drives it with a per-manager override:

[mpm.managers.pear]
timeout = 900

mpm config-template pear prints every overridable attribute as a ready-to-paste block.

Recipes

A few jobs you would otherwise script around pear, one mpm command each:

  • Snapshot and clone a machine: mpm --pear dump pear.toml, then mpm restore pear.toml on the next one.

  • Export a compliance SBOM: mpm --pear sbom (CycloneDX by default, --spdx for SPDX).

Privilege escalation

mpm runs this manager as the current user and never prepends sudo by default. Flip the policy for its privileged operations with --sudo or the per-manager sudo override.

See privilege escalation for the full policy.

Cooldown

State of PEAR’s release-age gating, from the cooldown support table:

Status: ❌ None

A cooldown only pays off where a compromised release can be withdrawn while the clock runs, and can only be emulated where the registry dates its releases. From the retraction table:

  • Registry: PEAR (pkg:pear)

  • Publish date: ✅ per-release <da> in the REST release document (example), which no pear command surfaces

With --cooldown set, mpm skips this manager’s install and upgrade operations rather than run them unguarded (fail-closed); --cooldown best-effort opts back in.

Version probe

The version is probed by running:

$ pear version
PEAR Version: 1.10.16
PHP Version: 8.4.24
Zend Engine Version: 4.4.24
Running on: Linux debian 6.12.94+deb13-arm64 #1 SMP Debian 6.12.94-1 (2026-06-20) aarch64

and extracted with:

r"PEAR Version:\s+(?P<version>\S+)"

Reference traces

Raw native outputs captured in the manager source: the reference mpm’s parsers were written against. If you know PEAR well and a transcript below looks wrong, or a newer release changed its output format, report it.

$ pear list --allchannels
INSTALLED PACKAGES, CHANNEL __URI:
==================================
(no packages installed)

INSTALLED PACKAGES, CHANNEL DOC.PHP.NET:
========================================
(no packages installed)

INSTALLED PACKAGES, CHANNEL PEAR.PHP.NET:
=========================================
PACKAGE          VERSION STATE
Archive_Tar      1.5.0   stable
Console_Getopt   1.4.3   stable
PEAR             1.10.16 stable
PEAR_Manpages    1.10.0  stable
Structures_Graph 1.2.0   stable
XML_Util         1.4.5   stable

INSTALLED PACKAGES, CHANNEL PECL.PHP.NET:
=========================================
(no packages installed)
$ pear list-upgrades
PEAR.PHP.NET AVAILABLE UPGRADES (STABLE):
=========================================
CHANNEL      PACKAGE     LOCAL            REMOTE           SIZE
pear.php.net Archive_Tar 1.5.0 (stable)   1.6.0 (stable)   22kB
pear.php.net PEAR        1.10.16 (stable) 1.10.18 (stable) 288kB

Feed any of these through mpm and the raw output becomes one uniform table, the same shape for every manager: filter it, project columns, or export it (mpm --pear installed --output json, or csv, toml, yaml), each package carrying a purl and a version comparable across managers.

Changelog

  • 8.0.0.dev0 (unreleased)

    • Add PEAR package manager, with inventory, outdated, install, remove, upgrade, channel sync and cache cleanup.