PHPackages                             coyotito/ipp - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. coyotito/ipp

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

coyotito/ipp
============

A clean, standards-compliant IPP (Internet Printing Protocol — RFC 8011/8010) client for PHP: discover network printers, read their capabilities, and submit print jobs — vendor and model agnostic.

v1.0.0(1mo ago)0109MITPHPPHP ^8.4CI passing

Since Jun 6Pushed 1mo agoCompare

[ Source](https://github.com/coyotito-mx/ipp)[ Packagist](https://packagist.org/packages/coyotito/ipp)[ RSS](/packages/coyotito-ipp/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (5)Versions (3)Used By (0)

coyotito/ipp
============

[](#coyotitoipp)

A clean, standards-compliant **IPP (Internet Printing Protocol)** client for PHP. Discover network printers, read their capabilities, and submit print jobs — vendor and model agnostic, conformant to **RFC 8011** (model/semantics) and **RFC 8010** (encoding/transport).

No CUPS required: it speaks IPP directly over HTTP(S) to port 631.

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

[](#requirements)

- PHP **8.4+**
- [`guzzlehttp/guzzle`](https://github.com/guzzle/guzzle) — HTTP transport (swappable; any PSR-18 client works)
- [`symfony/process`](https://github.com/symfony/process) — running `ippfind` for discovery
- [`clue/socket-raw`](https://github.com/clue/socket-raw) — pure-PHP mDNS discovery (needs `ext-sockets`)

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

[](#installation)

```
composer require coyotito/ipp
```

Quick start
-----------

[](#quick-start)

```
use Coyotito\Ipp\Printer;

$printer = Printer::connect('ipps://192.168.1.50:631/ipp/print');

// What can it do? (Get-Printer-Attributes → typed view)
$caps = $printer->capabilities();
$caps->makeAndModel();        // "Office Printer"
$caps->isOnline();            // true
$caps->hasMediaReady('na_legal_8.5x14in');
$caps->supportsColor();
$caps->supportsDuplex();

// Print, fluently. Nothing is sent until ->send().
$job = $printer->print($bytes, 'image/jpeg')
    ->copies(2)
    ->color()
    ->media('na_letter_8.5x11in')
    ->duplex()
    ->pages('1-5')
    ->send();

$job->id;            // 14
$job->status();      // JobState::Processing → Completed (re-fetched live)
$job->isCompleted();
$job->cancel();
```

Discovery
---------

[](#discovery)

```
use Coyotito\Ipp\Discovery\Discovery;

foreach (Discovery::mdns()->discover(timeout: 5) as $printer) {
    echo $printer->uri;   // ipp://office-printer.local:631/ipp/print
    echo $printer->name;  // "Office Printer"
}

// Always-available fallback: register by IP/host.
$printer = Discovery::mdns()->manual('192.168.1.50', secure: true);
```

### Platform support

[](#platform-support)

Discovery has two interchangeable strategies; pick what fits the host OS:

StrategyHowmacOSLinuxWindows`Discovery::ippfind()`CUPS' `ippfind` (wraps Bonjour/`dns-sd` &amp; Avahi)✅ built-in✅ via CUPS❌ no CUPS by default`Discovery::mdns()`pure-PHP multicast DNS (`clue/socket-raw`)✅✅✅`…->manual(host)`known IP/host, no discovery✅✅✅**On Windows**, use `Discovery::mdns()` — there is no `ippfind`. Make sure `ext-sockets` is enabled and allow the app inbound UDP in Windows Firewall, or fall back to `manual()`. (In an Electron/NativePHP app you can also discover with a Node mDNS library and feed the URI straight into `Printer::connect()`.)

Both strategies, and the underlying command/socket runners, are interfaces — swap or fake them freely.

Transport
---------

[](#transport)

The default transport is Guzzle, but it only depends on the PSR-18 `ClientInterface`, so you can inject any client (or a Guzzle `MockHandler` in tests):

```
use Coyotito\Ipp\Transport\GuzzleTransport;

$printer = Printer::connect($uri, new GuzzleTransport(
    client: $myPsr18Client,   // optional; defaults to a configured Guzzle client
    username: 'admin',        // optional Basic auth
    password: 'secret',
    verifyTls: false,         // printers ship self-signed certs (default)
));
```

Notes for real network printers:

- `ipp://` maps to http, `ipps://` to https (port 631 by default).
- TLS verification is **off by default** (self-signed certs are the norm).
- On a `426 Upgrade Required` over cleartext, the transport retries once over TLS. Still, **prefer the `ipps://` URI for large jobs** — some printers reject large cleartext uploads outright instead of asking to upgrade.

Printers don't always accept PDF
--------------------------------

[](#printers-dont-always-accept-pdf)

Many printers (most inkjets) do **not** list `application/pdf` in `document-format-supported` — they expect raster. Decide per printer:

```
$caps = $printer->capabilities();

$format = $caps->preferredFormat([
    'application/pdf',     // send as-is if supported
    'image/pwg-raster',    // else rasterize to PWG Raster (IPP Everywhere)
    'image/urf',           // or Apple Raster (AirPrint)
    'image/jpeg',          // last resort
]);

$caps->pwgRasterResolutions();   // resolutions valid for raster output
$caps->printQualitiesSupported();
```

Rasterizing PDF → PWG Raster/URF is your application's job (e.g. Ghostscript / `mutool` / CUPS filters); this package reports what the printer accepts and ships the bytes you give it with the right `document-format`.

Supported operations
--------------------

[](#supported-operations)

`Get-Printer-Attributes`, `Print-Job`, `Validate-Job`, `Create-Job`, `Send-Document`, `Get-Job-Attributes`, `Get-Jobs`, `Cancel-Job`. The wire format supports every IPP value syntax, including 1setOf values and nested collections (`media-col`).

Conformance &amp; testing
-------------------------

[](#conformance--testing)

- Strict to **RFC 8011** and **RFC 8010**: `version 2.0`; operation-attributes first, with `attributes-charset` (utf-8) and `attributes-natural-language` as the first two attributes; correct `printer-uri` / `requesting-user-name` / `document-format`; full status-code handling.
- Encoder/decoder round-trip tests, a binary response fixture, and cross-checked against `ipptool` and a real printer.

```
composer test
```

License
-------

[](#license)

MIT.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance90

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 83.3% 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

Unknown

Total

1

Last Release

49d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e73661fd63054eddd1a16249f4d6a30a78531dd4f282a914a793b5980c66c023?d=identicon)[coyotito](/maintainers/coyotito)

---

Top Contributors

[![asciito](https://avatars.githubusercontent.com/u/63119899?v=4)](https://github.com/asciito "asciito (5 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

printerprintingCUPSipprfc8011rfc8010ipp-everywhereairprint

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/coyotito-ipp/health.svg)

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

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k16](/packages/tempest-framework)[civicrm/civicrm-core

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

751291.4k46](/packages/civicrm-civicrm-core)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[shlinkio/shlink

A self-hosted and PHP-based URL shortener application with CLI and REST interfaces

5.1k5.2k](/packages/shlinkio-shlink)[lion/bundle

Lion-framework configuration and initialization package

122.4k4](/packages/lion-bundle)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

293.1k](/packages/eslazarev-wildberries-sdk)

PHPackages © 2026

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