1. Go to this page and download the library: Download dynamik-dev/cloak-php library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
dynamik-dev / cloak-php example snippets
$cloaked = cloak('Email me at [email protected]');
// "Email me at {{EMAIL_x7k2m9_1}}"
$original = uncloak($cloaked);
// "Email me at [email protected]"
use DynamikDev\Cloak\Cloak;
use DynamikDev\Cloak\Detector;
use DynamikDev\Cloak\Encryptors\OpenSslEncryptor;
$cloak = Cloak::make()
->withDetectors([Detector::email()])
->encrypt(OpenSslEncryptor::generateKey());
$cloaked = $cloak->cloak('Sensitive: [email protected]');
use DynamikDev\Cloak\Detector;
Detector::email(); // Email addresses
Detector::phone('US'); // Phone numbers (specify region code)
Detector::ssn(); // Social Security Numbers (XXX-XX-XXXX)
Detector::creditCard(); // Credit card numbers
Detector::all(); // All built-in detectors (uses US for phone)
// US numbers
Detector::phone('US')->detect('Call 212-456-7890');
// UK numbers
Detector::phone('GB')->detect('Ring 0117 496 0123');
// International format
Detector::phone()->detect('Call +44 117 496 0123');
// Filters false positives
Detector::phone('US')->detect('Order #123456789012'); // Not detected
use DynamikDev\Cloak\Detector;
use DynamikDev\Cloak\Detectors\Pattern;
// Factory method (concise)
$detector = Detector::pattern('/\b[A-Z]{2}\d{6}\b/', 'passport');
// Direct instantiation (explicit)
$detector = new Pattern('/\b[A-Z]{2}\d{6}\b/', 'passport');
$cloaked = $cloak->cloak('Passport: AB123456', [$detector]);
// "Passport: {{PASSPORT_x7k2m9_1}}"
use DynamikDev\Cloak\Detector;
use DynamikDev\Cloak\Detectors\Words;
// Factory method
$detector = Detector::words(['password', 'secret'], 'sensitive');
// Direct instantiation
$detector = new Words(['password', 'secret'], 'sensitive');
$cloaked = $cloak->cloak('The password is secret123', [$detector]);
// "The {{SENSITIVE_x7k2m9_1}} is {{SENSITIVE_x7k2m9_2}}123"
use DynamikDev\Cloak\Detector;
use DynamikDev\Cloak\Detectors\Callback;
// Factory method
$detector = Detector::using(function (string $text): array {
$matches = [];
if (preg_match_all('/\bAPI_KEY_\w+\b/', $text, $found)) {
foreach ($found[0] as $match) {
$matches[] = ['match' => $match, 'type' => 'api_key'];
}
}
return $matches;
});
// Direct instantiation
$detector = new Callback(function (string $text): array {
// ... same logic
});
use DynamikDev\Cloak\Detector;
use DynamikDev\Cloak\Detectors\{Email, Pattern, Words};
$cloak->cloak($text, [
new Email(), // Direct
Detector::phone('US'), // Factory
new Pattern('/\b[A-Z]{2}\d{6}\b/', 'passport'), // Direct
Detector::words(['secret'], 'sensitive'), // Factory
]);
use DynamikDev\Cloak\Contracts\DetectorInterface;
class IpAddressDetector implements DetectorInterface
{
public function detect(string $text): array
{
$matches = [];
$pattern = '/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/';
if (preg_match_all($pattern, $text, $found)) {
foreach ($found[0] as $match) {
$matches[] = ['match' => $match, 'type' => 'ip_address'];
}
}
return $matches;
}
}
$cloaked = $cloak->cloak('Server: 192.168.1.1', [new IpAddressDetector()]);
// "Server: {{IP_ADDRESS_x7k2m9_1}}"
// Exclude test emails
$cloak = Cloak::make()
->filter(fn ($detection) => !str_ends_with($detection['match'], '@test.local'));
$text = '[email protected] and [email protected]';
$cloaked = $cloak->cloak($text, [Detector::email()]);
// "{{EMAIL_x7k2m9_1}} and [email protected]"
use DynamikDev\Cloak\Encryptors\OpenSslEncryptor;
$cloak = Cloak::make()
->encrypt(OpenSslEncryptor::generateKey());
$cloaked = $cloak->cloak('Secret: [email protected]', [Detector::email()]);
// Values are encrypted in storage, but placeholders remain the same
// Reads from CLOAK_PRIVATE_KEY environment variable
$cloak = Cloak::make()->encrypt();
// Or specify a custom environment variable
$encryptor = new OpenSslEncryptor(null, 'MY_ENCRYPTION_KEY');
$cloak = Cloak::make()->withEncryptor($encryptor);
$customEncryptor = new MyEncryptor($key);
$cloak = Cloak::make()->withEncryptor($customEncryptor);
use DynamikDev\Cloak\Stores\ArrayStore;
$store = new ArrayStore();
$cloak = Cloak::using($store);
use DynamikDev\Cloak\Contracts\StoreInterface;
class RedisStore implements StoreInterface
{
public function __construct(
private Redis $redis,
private int $ttl = 3600
) {}
public function put(string $key, array $map): void
{
$this->redis->setex($key, $this->ttl, json_encode($map));
}
public function get(string $key): ?array
{
$data = $this->redis->get($key);
return $data ? json_decode($data, true) : null;
}
public function forget(string $key): void
{
$this->redis->del($key);
}
}
// Configure TTL via constructor
$cloak = Cloak::using(new RedisStore($redis, ttl: 7200));
use DynamikDev\Cloak\Contracts\StoreInterface;
use Illuminate\Support\Facades\Cache;
class LaravelCacheStore implements StoreInterface
{
public function __construct(private int $ttl = 3600) {}
public function put(string $key, array $map): void
{
Cache::put($key, $map, $this->ttl);
}
public function get(string $key): ?array
{
return Cache::get($key);
}
public function forget(string $key): void
{
Cache::forget($key);
}
}
use DynamikDev\Cloak\Cloak;
// Set a custom resolver (typically in a service provider)
Cloak::resolveUsing(fn() => app(Cloak::class));
// Now Cloak::make() resolves from your container
$cloak = Cloak::make(); // Uses your container binding
use DynamikDev\Cloak\Cloak;
use Illuminate\Support\ServiceProvider;
class CloakServiceProvider extends ServiceProvider
{
public function register()
{
// Bind Cloak to the container with your configuration
$this->app->bind(Cloak::class, function ($app) {
return Cloak::using($app->make(CacheStore::class))
->withDetectors(config('cloak.detectors', Detector::all()));
});
// Make helpers use container resolution
Cloak::resolveUsing(fn() => app(Cloak::class));
}
}
// In AppServiceProvider
$this->app->bind(Cloak::class, function ($app) {
return CustomCloak::using($app->make(CacheStore::class));
});
Cloak::clearResolver(); // Reverts to default behavior
use DynamikDev\Cloak\Contracts\PlaceholderGeneratorInterface;
use Ramsey\Uuid\Uuid;
class UuidPlaceholderGenerator implements PlaceholderGeneratorInterface
{
public function generate(array $detections): array
{
$key = Uuid::uuid4()->toString();
$map = [];
foreach ($detections as $detection) {
$uuid = Uuid::uuid4()->toString();
$placeholder = "[{$detection['type']}:{$uuid}]";
$map[$placeholder] = $detection['match'];
}
return ['key' => $key, 'map' => $map];
}
public function replace(string $text, array $map): string
{
foreach ($map as $placeholder => $original) {
$text = str_replace($original, $placeholder, $text);
}
return $text;
}
public function parse(string $text): array
{
// Extract [TYPE:UUID] placeholders and group by key
// Implementation details...
return [];
}
}
$cloak = Cloak::make()
->withPlaceholderGenerator(new UuidPlaceholderGenerator());
use DynamikDev\Cloak\Contracts\EncryptorInterface;
class SodiumEncryptor implements EncryptorInterface
{
public function __construct(private string $key) {}
public function encrypt(string $value): string
{
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encrypted = sodium_crypto_secretbox($value, $nonce, $this->key);
return base64_encode($nonce . $encrypted);
}
public function decrypt(string $encrypted): string
{
$decoded = base64_decode($encrypted);
$nonce = substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $this->key);
if ($decrypted === false) {
throw new \RuntimeException('Decryption failed');
}
return $decrypted;
}
}
$cloak = Cloak::make()
->withEncryptor(new SodiumEncryptor($key));