yakeing/php_curl
A simple PHP cURL wrapper for making HTTP requests without low-level cURL boilerplate. Supports GET/POST, custom headers, cookies, proxies, and file uploads, helping you fetch remote content or call APIs quickly from any PHP project.
What the package is. yakeing/php_curl is a thin procedural wrapper around PHP's native cURL extension. Its stated surface area — cookies, TLS transport, HTTP basic/auth, form simulation, file upload — is a subset of what PHP's ext-curl already does, with convenience helpers layered on top. There is no framework integration, no service provider, no configuration contract, and no abstraction layer beyond the wrapper itself.
Architecture fit: poor. Laravel has shipped a first-party HTTP client (Guzzle-backed) since 7.x, and Guzzle is already a transitive dependency of laravel/framework. Adopting this package would introduce a second, parallel HTTP path into the codebase with different semantics, different error handling, and different testing affordances. For a Laravel application the honest framing is that this is a replacement for the framework's HTTP layer, not a complement — and a strictly less capable one.
Integration feasibility: mechanically easy, strategically wrong. Composer install is trivial; the API is simple enough that a developer could wrap it behind an interface in an afternoon. The difficulty is not integration, it is the downstream cost: no Http::fake()-equivalent, no middleware stack, no retry/backoff, no request pooling, no PSR-18 interoperability.
Technical risk: high, and largely unmitigable.
curl_init() returning a CurlHandle object rather than a resource. Whether it breaks or merely emits deprecations depends on whether the handle is type-checked, serialized, or stored in typed properties — this must be verified, not assumed. PHP 8.2+ dynamic property deprecations are a second landmine in older wrappers.CURLOPT_SSL_VERIFYPEER/VERIFYHOST to permissive values. If this package does, every outbound call is exposed to MITM, and composer audit will not catch it because there is no advisory.Key questions.
is_resource()? (Determines PHP 8.x viability.)CookieJar does not already satisfy?Stack fit: does not fit. Laravel's supported HTTP story is Illuminate\Support\Facades\Http over Guzzle. Anything we build on yakeing/php_curl sits outside that: outside the container, outside the config system, outside Http::fake()-based tests, outside Telescope/HTTP-client instrumentation, and outside the framework's upgrade path. The only defensible use case is a legacy, non-Laravel PHP service where Guzzle is genuinely unavailable — which is not the brief here.
Compatibility posture. Treat the package as unverified on PHP 8.1+ until proven otherwise in a spike. Version constraint will be * or a stale ^1.0; either way there is no upstream to raise a floor against. ext-curl remains the only hard requirement, which is the package's one genuine strength — near-zero dependency weight.
Migration / exit cost. Low, and that is the only argument in its favor: the API is narrow, so a wrapper interface (HttpTransport) around it can be swapped to Guzzle later without touching call sites. If — and only if — a team insists on a trial, mandate that it be adopted behind an internal interface and never referenced directly from domain code. Budget the swap as a known future cost, not a hypothetical.
Sequencing.
Http::withOptions() / Guzzle directly. Expected outcome: full coverage.Maintenance: unbounded and unfunded. An archived repo means every future PHP minor is our problem. The realistic internal cost is a fork-and-own commitment: someone must patch, tag, and test it against each PHP release, forever, for a component that duplicates a first-party dependency. That is a permanent tax on a solved problem.
Support. No upstream issues, no PRs, no maintainer. Internal support burden falls on whichever team adopts it, with no escalation path and no vendor. On-call documentation would have to describe bespoke behavior for a component that behaves differently from every other HTTP call in the fleet — a cognitive-load multiplier during incidents.
Scaling: weak. Synchronous, blocking, one-handle-per-request by default. No connection reuse, no concurrency pool (curl_multi), no built-in retry or circuit breaking. Under load, outbound HTTP becomes a latency amplifier, and there is no middleware seam to insert backoff. Laravel's client offers pool(), retry(), and middleware; this offers none of them without us writing them.
Failure modes.
ConnectionException, making retry/alerting logic guesswork.Ramp-up. Superficially fast (small API, familiar cURL concepts), which is precisely the trap: developers will reach for it because it feels lighter than Guzzle, and each such choice adds an unmonitored, unmockable, unmaintained egress path. Onboarding cost is low; the cost of containing adoption across a growing team is high, because there is no framework convention to point at when saying no.
Recommendation: do not adopt. Score 0.15, archived status, and a 2019 release are individually sufficient grounds; together with a first-party Laravel alternative that is already in the dependency tree, there is no case to make. If a narrower cURL-level control is genuinely required, use Guzzle directly — it exposes the same underlying options with a maintained, testable, instrumented surface.
How can I help you explore Laravel packages today?