imliam/php-unique-gmail-address
A small PHP utility for generating unique Gmail addresses from an existing Gmail account. It adds plus-tag aliases so each address looks different but still delivers to the same inbox, handy for testing, signups, and avoiding duplicate-email checks.
composer require imliam/php-unique-gmail-address. It's framework-agnostic plain PHP, so it drops into Laravel fine but doesn't ship a service provider or facade — you call it directly.src/UniqueGmailAddress.php and the README. The package is intentionally tiny: one class exposing a static normalizer. There is no config file to publish.+. So [email protected], [email protected], and [email protected] all resolve to the same inbox.use ImLiam\UniqueGmailAddress\UniqueGmailAddress;
UniqueGmailAddress::getUniqueGmailAddress('[email protected]');
// => '[email protected]'
users table against the canonical form rather than the raw string.Store both forms. Keep the address the user typed (for display, receipts, and password-reset links) and the canonical form for uniqueness and lookups:
Schema::table('users', function (Blueprint $table) {
$table->string('email_normalized')->nullable()->unique()->after('email');
});
Backfill existing rows before adding the unique index, otherwise duplicate Gmail accounts already in the table will make the migration fail.
Normalize on registration and on login. The same helper should feed both paths:
$normalized = UniqueGmailAddress::getUniqueGmailAddress($request->email);
User::create([
'email' => $request->email, // display
'email_normalized' => $normalized, // unique key
'password' => Hash::make($request->password),
]);
$user = User::where('email_normalized', $normalized)->first();
Wrap it once. Create app/Support/EmailNormalizer.php that delegates to the package. That gives you one seam to swap in a multi-provider normalizer later, and insulates you if the package's static method name ever moves:
public static function normalize(string $email): string
{
return UniqueGmailAddress::getUniqueGmailAddress($email);
}
Validation rules. Because Rule::unique compares against raw input, either normalize in prepareForValidation() of a FormRequest, or use a closure rule that compares the normalized column against the normalized input. The latter is less surprising.
Bulk/list deduplication. For imports and invite lists, map over the input and unique() on the normalized value while retaining the original for sending:
$deduped = collect($emails)
->keyBy(fn ($e) => EmailNormalizer::normalize($e))
->values();
Extension point: other providers. The package only knows Gmail semantics. If you also need Outlook aliases, Fastmail + handling, or Proton, compose it — call the package for gmail.com/googlemail.com and fall back to your own logic for everything else inside your EmailNormalizer.
googlemail.com → gmail.com — test it explicitly, since those are the same mailbox at Google.[email protected] and [email protected] are not valid Gmail addresses. Strip dots/plus first, then re-run your standard email validation on the result so you don't persist an empty local part.email_normalized for a handful of variants (dots, plus, dots+plus, uppercase, googlemail.com, not-gmail.com). This doubles as a regression guard if the package's normalization changes between releases — it's on a 0.x-style cadence and the last release was recent.email_normalized without normalizing, or a nullable column where the unique index silently allows repeated NULLs.EmailNormalizer wrapper everywhere else so any rename is a one-line change.How can I help you explore Laravel packages today?