maatify / cloudflare-turnstile
Unofficial PHP library for validating Cloudflare Turnstile CAPTCHA responses.
Requires
- php: >=8.4.27 <8.5.0 || >=8.5.12 <8.6.0
- ext-curl: *
- maatify/functions: ^5
- maatify/json: ^5.0.4
- maatify/logger: ^5.1 || ^7.0
- psr/log: ^3
Requires (Dev)
- composer/semver: ^3.4
- phpstan/phpstan: ^2
- phpunit/phpunit: ^11 || ^12
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 6.0.0
- 5.x-dev
- 5.0.2
- 5.0.1
- 1.0.8
- 1.0.0007
- 1.0.0006
- 1.0.0005
- 1.0.0004
- 1.0.0003
- dev-claude/verify-published
- dev-claude/post-publish-sync
- dev-claude/release-qualification
- dev-claude/strict-psr
- dev-claude/release-docs-502
- dev-claude/readme
- dev-claude/gitattributes
- dev-claude/llms-txt
- dev-claude/usage-guide
- dev-claude/examples
- dev-claude/namespace-rename
- dev-claude/move-to-src
- dev-claude/security-5.0.2
- dev-claude/redact-sensitive-logging
- dev-claude/package-reference
- dev-claude/changelog
- dev-claude/code-of-conduct
- dev-claude/composer-support-security
- dev-claude/contributing
- dev-claude/security-md
- dev-claude/license
- dev-claude/consumer-harness
- dev-claude/provider-contract
- dev-claude/phpunit-suites
- dev-claude/gitignore
- dev-claude/phpstan
- dev-claude/ci-workflow
- dev-claude/composer-metadata
- dev-claude/cloudflare-turnstile-issue-5189b5
This package is auto-updated.
Last update: 2026-11-01 13:09:50 UTC
README
Cloudflare Turnstile
PHP library that validates a Cloudflare Turnstile token on the server and reports the result, failing closed when a request cannot be sent or answered.
Package status
The latest published release is 6.0.0. It is a breaking release: the namespace and the PHP, maatify/logger and maatify/json requirements changed. The 5.x line, which uses the previous namespace, remains available for security maintenance only; see Upgrade notes.
Key Features
- Validates the
cf-turnstile-responsetoken against the Cloudflaresiteverifyendpoint with one JSONPOST. - Fails closed: a transport error, an empty or non-object response, or an unencodable request is reported as an unsuccessful validation, never as a success.
- Returns a plain boolean (
isSuccess()), the decoded Cloudflare response (getResponse()), or ends the request with a JSON error (jsonErrors()). - Logs each request through
maatify/loggerwithout writing the secret key, the token or other request values. - One documented extension point,
endpoint(), for running against a local stand-in.
Requirements
- PHP
>=8.4.27 <8.5.0 || >=8.5.12 <8.6.0with thecurlextension. maatify/functions ^5,maatify/json ^5.0.4,maatify/logger ^5.1 || ^7.0andpsr/log ^3.- A Turnstile secret key and network access to
challenges.cloudflare.com.
The authoritative constraints are in composer.json.
Installation
composer require maatify/cloudflare-turnstile
With the constraint ^5.0 an existing project stays on 5.x, so to move an existing project to 6.x use composer require 'maatify/cloudflare-turnstile:^6.0' --with-all-dependencies.
Quick Usage
<?php use Maatify\CloudflareTurnstile\Service\TurnstileValidation; require 'vendor/autoload.php'; // The widget posts the token in $_POST['cf-turnstile-response']. $secretKey = (string)getenv('TURNSTILE_SECRET_KEY'); $validation = TurnstileValidation::getInstance($secretKey); if ($validation->isSuccess()) { // the token is valid: process the request } else { // reject the request }
The Usage Guide walks through each call as Input → Public Call → Result → Boundary.
Public Runtime API
| Class | Role |
|---|---|
Maatify\CloudflareTurnstile\Service\TurnstileValidation |
Entry point: getInstance(), isSuccess(), getResponse(), jsonErrors(), and the public $success and $response properties. |
Maatify\CloudflareTurnstile\Adapter\TurnstileRequestCall |
Abstract base that owns the HTTP call: curlPost(), curlGet() and the protected endpoint() extension point. |
The complete inventory, signatures and guarantees are in the Package Reference.
Critical Runtime Behavior
- A failed validation does not throw; it is reported as
success = false. getInstance()keeps the secret key of its first call, and the firstisSuccess()orgetResponse()sends the request; later calls on the same instance reuse the result.jsonErrors()ends the request when the token is missing or the validation fails.
Exception and Error Propagation
RuntimeException is thrown only if cURL cannot be initialized when the object is created. Using the secret key before one was supplied raises an Error. Everything else, including network failures, is returned as an unsuccessful result.
Security and Trust Boundaries
- The secret key belongs to your application: keep it in your own secret storage and never commit it. The library does not store or rotate it.
- Log entries contain the endpoint URL and the request parameter names, never the secret key, the token or other parameter values.
- Report a vulnerability privately, as described in SECURITY.md; do not use public issues.
Examples
Runnable and Host-dependent examples are in examples/: validating a form token, answering a failure with a JSON error, and running against a local stand-in for Cloudflare.
Documentation
- Usage Guide: integration workflows and boundaries.
- Package Reference: the stable public, runtime and behavioral contract.
- Changelog: release history and the upgrade path from
5.x. - Security Policy and Contributing Guide.
Quality Status
Verified in CI on PHP 8.4 and 8.5, and on the lowest supported dependencies:
- PHPStan at level
max. - Regression and system test suites, with deterministic provider-contract tests driven by fixtures. They never contact Cloudflare.
- A consumer harness that installs the package from the committed tree into a clean Composer project and exercises its public API.
- Smoke execution of the standalone examples, and an inspection of the distribution archive.
composer auditwith abandoned packages treated as failures.
These checks prove the implemented contract against deterministic fixtures. They do not prove current live Cloudflare behavior.
Development and Testing
composer update
composer analyse
composer test
scripts/ci/verify.sh latest
scripts/ci/verify.sh runs the same checks as CI. See CONTRIBUTING.md.
Upgrade Notes
6.0.0 moves the classes to the canonical namespace and raises the PHP and dependency requirements:
// 5.x use Maatify\Turnstile\TurnstileValidation; // 6.0.0 use Maatify\CloudflareTurnstile\Service\TurnstileValidation;
The complete upgrade steps are in the Changelog.
License
Proprietary. See LICENSE.
Author
Engineered by Mohamed Abdulalim (@megyptm)
Backend Lead & Technical Architect
https://www.maatify.dev
Built with ❤️ by Maatify.dev — Unified Ecosystem for Modern PHP Libraries