zendframework/zendservice-apple-apns
Zend Framework service for Apple Push Notification Service (APNs). Send push notifications to iOS devices from PHP using certificate-based connections, with support for Apple’s feedback service.
Architecture fit — poor. zendframework/zendservice-apple-apns is a Zend Framework 2-era component (Zend\Service\Apple\Apns\*), not a Laravel package. It ships no service provider, no facade, no publishable config, and no package-discovery metadata. Any use requires hand-written container bindings in AppServiceProvider plus manual lifecycle management of a long-lived TLS socket — behavior fundamentally at odds with Laravel's stateless, per-request/queue-worker execution model. It also drags in abandoned zendframework/zend-http, zend-uri, and zend-json dependencies, which will collide with any Laminas packages already present in a modern app.
Integration feasibility — effectively blocked. The package targets Apple's legacy binary provider protocol (gateway.push.apple.com:2195). Apple retired that endpoint; APNs today is HTTP/2 with JWT provider-token authentication (.p8 keys). Certificate-based binary connections are refused at the transport layer. Beyond the protocol, the package's composer constraints are PHP 5.6/7.x era and will not resolve against a Laravel 10/11 application running PHP 8.2+ without --ignore-platform-reqs or a fork. There is no path to "install and it works."
Technical risk — critical / terminal. Archived repository, last release March 2019, zero dependents, no security response process, no PHP 8 compatibility, no HTTP/2, no token auth, 256-byte payload ceiling versus today's 4KB, and dependence on the now-removed feedback service. Any deployment would fail closed at connect time. The only residual value is as a reference implementation: its message/payload object model is a readable spec for constructing APNs JSON, and it is a useful inventory source when auditing what a legacy codebase currently sends.
Key questions for the team:
.pem certs, or .p8 provider tokens?Product read: the composite score (1.87) and low opportunity signal (28.98) are correct. This is a migration liability, not an accelerator. Recommend against adoption and treat it as a decommissioning item.
Stack fit — none out of the box. Do not attempt a direct composer require. The realistic options are:
edamov/pushok (HTTP/2, JWT provider tokens, PHP 8 compatible) or wrap Guzzle's HTTP/2 support directly — APNs is a single POST to api.push.apple.com/3/device/{token} with a JWT in the authorization header. Use laravel-notification-channels/apn if the app already uses Laravel's notification system.app/Support/Apple for shape reference only, and write a new transport. Never ship the binary client.Migration path and sequencing:
ZendService, Apns, gateway hostnames; confirm whether the package is reachable in production at all.PushTransport interface (send(DeviceToken, Payload): Result) in the app and route all call sites through it. This is the only durable design decision here.410 Unregistered, 400 BadDeviceToken).Effort: roughly 1–3 engineer-days for the replacement given payload construction is trivial; add 1–2 days if legacy payloads use custom keys that need behavioral parity. The expensive part is discovery, not code.
Compatibility notes: pin ext-openssl and ext-curl (or ext-mbstring per pushok's requirements); confirm outbound egress to api.push.apple.com:443 from every environment; ensure JWT cache (Apple allows token reuse for ~1 hour) is not regenerated per-send, or you will hit 429 TooManyProviderTokenUpdates.
Maintenance — none available. Archived upstream means zero patches, zero PHP-version bumps, zero response to CVEs in the transitive Zend dependencies. composer audit will flag the abandoned package and break CI gates that enforce it. All maintenance cost transfers to your team from day one, which is precisely the wrong trade for a non-differentiating capability.
Support — effectively zero. The ecosystem answers, Stack Overflow threads, and Apple documentation that the package was written against have all been superseded. Onboarding an engineer to it costs more than onboarding them to a 200-line HTTP/2 client.
Scaling — poor by construction. The binary protocol relied on persistent connections and a separate error-response channel; the well-known failure pattern was a race where a write succeeded, the error channel returned a rejection later, and the sender had already moved on — producing silent notification loss. There is no batching, no backoff, and no per-token observability. HTTP/2 multiplexes tens of thousands of streams per connection with per-request status codes, which is both simpler and strictly more scalable.
Failure modes to expect:
gateway.push.apple.com:2195 — every send fails..p8 rotation story, no team-scoped keys.410 Unregistered.Ramp-up: low code-to-read, high trap density. The API surface is small and legible in an afternoon; the protocol assumptions are what burn people. Budget for one engineer to own the replacement end-to-end, including key custody and a delivery-metrics dashboard.
Recommendation: do not integrate. Fund a 1–3 day replacement behind a PushTransport interface, and use this repo only as a payload reference and a checklist of what the legacy implementation silently did wrong.
How can I help you explore Laravel packages today?