garethp/php-ews
A PHP library for Microsoft Exchange Web Services (EWS). Manage mail, calendars, contacts, tasks, and folders on Exchange Server and Office 365 through a clean, object-oriented wrapper over the EWS SOAP API, with support for Exchange 2007 through 2019 and Exchange Online.
Architecture fit. garethp/php-ews is a framework-agnostic PHP library, not a Laravel package. In a Laravel codebase it belongs in the infrastructure/integration layer, behind an application-owned port (e.g., MailGateway, CalendarGateway) rather than called directly from controllers or models. Its typed request/response objects are a genuine asset: they reduce hand-rolled SOAP/XML construction and give us something close to DTOs for mapping into domain objects. The library owns transport concerns (SOAP envelope, Autodiscover, Exchange version negotiation), which is the right boundary — but it also means the SOAP client and XML layer are effectively part of our runtime surface.
Integration feasibility. Mechanically straightforward: Composer install, ext-soap and/or ext-curl available, a config block for host/credentials/version, and a thin Laravel service provider plus facade. The hard part is not code, it is authentication and platform posture. Exchange Online has been closed to new EWS applications since 2022 and Microsoft has signposted EWS retirement for Exchange Online; Basic auth is gone and OAuth2 bearer tokens are mandatory. On-premises Exchange 2016/2019 remains a viable, well-supported target. So feasibility is bimodal: high for on-prem/legacy estates, materially constrained for new Office 365 work.
Technical risk.
ServerBusy/ErrorServerBusy failures.Key questions.
Stack fit. Works with any modern PHP 8.x application; Laravel 10/11 are natural hosts. Recommended shape: a config/exchange.php file, a singleton service provider binding a client factory, a small adapter implementing our own gateway interface, queued jobs for anything that writes or fans out, and a RateLimiter/backoff policy in front of every call. Keep the library's objects out of the domain layer — map to and from our own value objects at the adapter boundary.
Migration path. Treat EWS as one implementation of a protocol-agnostic gateway interface from day one. Concretely: (1) define MailGateway/CalendarGateway ports; (2) implement EwsMailGateway using this package; (3) keep the adapter free of EWS-specific types in its public signature so a future GraphMailGateway is a drop-in. This costs perhaps 10–15% extra effort up front and converts a rewrite into a swap. If Office 365 is the destination, plan the Graph evaluation as a scheduled decision gate, not a hypothetical.
Compatibility. Verify explicitly: supported PHP versions against our runtime, ext-soap availability in our container images, Laravel version support for the service provider wiring, and OAuth token acquisition (Entra ID app registration, client credentials or delegated flow). Autodiscover is convenient but should be disabled in production in favour of an explicit endpoint — it adds latency, network egress, and a failure mode. Validate against the specific Exchange version in each environment, since typed classes and schema support vary by version.
Sequencing.
Maintenance. Budget for dependency pinning (exact versions, lockfile committed), a documented fork-and-patch procedure, and a standing review of upstream releases. The library is the kind of dependency that is invisible until it breaks; assign a named owner. Add contract tests against a sandbox mailbox in CI to catch schema drift early. Treat the license as fine, but note there is no vendor indemnity.
Support. Internal expertise on EWS is scarce and getting scarcer — this is a skills-risk item, not just a code-risk item. Microsoft support posture for EWS on Exchange Online is unfavourable for new applications, so escalation paths are limited. Expect tickets in three buckets: authentication failures, throttling, and calendar/timezone correctness. Prepare runbooks for each before go-live, including credential rotation and mailbox permission troubleshooting.
Scaling. The library is synchronous and per-request; scale comes from queueing, not concurrency. Design for worker pools with per-mailbox rate limits, batch operations where EWS supports them, and capped attachment sizes with streaming to object storage rather than in-memory handling. Watch memory on large attachment and folder-traversal operations. Autodiscover should be resolved once and cached, not per call.
Failure modes to instrument for. ServerBusy/throttling responses, token expiry and refresh failures, Autodiscover timeouts, TLS/certificate changes, mailbox-not-found or permission-denied errors, attachment size rejections, and calendar recurrence/timezone misinterpretation. Every one of these should map to a distinct exception type with a defined retry policy (retry-with-jitter for transient, fail-fast for permission and validation errors) and an alert. Silent partial success on batch writes is the failure mode most likely to cause a customer-visible incident.
Ramp-up. A competent Laravel developer reaches productive read-only capability in roughly one sprint; write operations, throttling behaviour, and calendar edge cases add another one to two sprints of genuine learning. The ramp-up cost is less about the library API and more about Exchange semantics and OAuth plumbing. Recommend pairing the implementation with someone who has Exchange administration experience, or budgeting for an external specialist review before the write-path release.
How can I help you explore Laravel packages today?