Detect and Redact PII in Laravel with Privacy Filter
Handling user data responsibly is a core requirement for modern web applications. The Privacy Filter package for Laravel makes it straightforward to detect personally identifiable information (PII) — such as names and email addresses — directly within your PHP application, without sending data to a third-party API.
Under the hood, the package wraps privacy-filter.cpp, a GGML inference engine for OpenAI's privacy-filter token-classification models, and exposes the results through a clean Laravel facade.
Classifying Text into Entities
The primary entry point is the entities() method. Pass it a string and it returns a collection of Entity instances, each carrying the entity type, matched text, UTF-8 byte offsets, and a confidence score.
use DirectoryTree\PrivacyFilter\Facades\PrivacyFilter;
$entities = PrivacyFilter::entities('Contact John Doe at jdoe@example.com.');
foreach ($entities as $entity) {
echo $entity->type; // private_email
echo $entity->text; // jdoe@example.com
}
Because offsets are exact UTF-8 byte positions, you can map each detected entity back to its precise location in the original string — no fragile string-matching required.
Tuning Confidence Thresholds
Classifications default to a 0.5 confidence threshold. You can raise or lower it per call to trade recall for precision. A higher threshold returns fewer but more certain results.
$entities = PrivacyFilter::entities(
text: 'Contact John Doe at jdoe@example.com.',
threshold: 0.75,
);
Redacting Detected Text
Privacy Filter focuses on detection; redaction is left to you. A simple reduce over the returned entities handles the substitution:
$redacted = collect($entities)->reduce(function (string $text, $entity) {
return str_replace($entity->text, '[redacted]', $text);
}, $text);
This keeps the package's responsibilities narrow and your redaction logic fully under your control.
Faking Classifications in Tests
Loading a GGML model in a test suite is slow. Privacy Filter ships a fake() method that returns predetermined entities without invoking the binary at all:
use DirectoryTree\PrivacyFilter\Entity;
use DirectoryTree\PrivacyFilter\Facades\PrivacyFilter;
PrivacyFilter::fake([
new Entity(type: 'private_email', start: 20, end: 36, score: 0.98),
]);
Your application code under test receives those entities exactly as if the model had produced them, keeping your test suite fast and deterministic.
Installation and Setup
Install via Composer, then run the built-in installer to fetch the compiled binary and download the required GGUF model:
composer require directorytree/privacy-filter
php artisan privacy-filter:install
Prebuilt binaries are available for Linux, macOS (including ARM64), and Windows. Pass --force to overwrite existing files. To customize the binary path, model path, process timeout, model URL, or release source, publish the config file:
php artisan vendor:publish --tag=privacy-filter-config
Production Considerations
Every classification loads the model into memory. The package recommends running classifications on dedicated queue workers in production to keep memory usage predictable and avoid impacting your web processes.
Key Takeaways
- Detects PII (names, emails, and more) locally using a GGML model — no external API calls.
- Returns
Entityobjects with type, text, UTF-8 byte offsets, and confidence score. - Adjustable confidence threshold per call for precision vs. recall trade-offs.
- Redaction is intentionally left to the developer for maximum flexibility.
fake()method enables fast, deterministic unit tests without loading the model.- Prebuilt binaries support Linux, macOS (ARM64 included), and Windows.
- Run classifications on queue workers in production to manage memory predictably.
Source: Privacy Filter: Detect PII in Text from Laravel — Laravel News