Installation:
composer require zipavlin/phony
No additional configuration is required—just autoload the package.
First Use Case: Parse a Slovene phone number and validate its format:
use Phony\Phony;
$phony = new Phony();
$result = $phony->parse('+386 41 123 456');
if ($result->isValid()) {
echo "Valid Slovene number: " . $result->getNumber();
} else {
echo "Invalid format: " . $result->getError();
}
Key Classes:
Phony: Main class for parsing and validation.ParsedNumber: Result object containing parsed data (e.g., country code, area code, number).Where to Look First:
src/Phony.php for core logic and available methods.Parsing and Validation:
$phony = new Phony();
$parsed = $phony->parse($rawNumber);
if ($parsed->isValid()) {
// Proceed with valid number (e.g., store in DB, format for display)
$formatted = $parsed->format(); // e.g., "+386 41 123 456"
}
Extracting Components:
$countryCode = $parsed->getCountryCode(); // e.g., "386"
$areaCode = $parsed->getAreaCode(); // e.g., "41"
$localNumber = $parsed->getLocalNumber(); // e.g., "123456"
Integration with Forms:
use Phony\Phony;
$validator = Validator::make($request->all(), [
'phone' => ['required', function ($attribute, $value, $fail) {
$phony = new Phony();
if (!$phony->parse($value)->isValid()) {
$fail('Invalid Slovene phone number.');
}
}],
]);
Batch Processing:
$numbers = ['+386 31 123 456', '01 123 4567'];
$results = collect($numbers)->map(fn($num) => $phony->parse($num));
$validNumbers = $results->filter(fn($r) => $r->isValid());
Localization:
$formatted = $parsed->format('+386 XXX XXX XXX'); // e.g., "+386 411 234 567"
Laravel Service Provider:
Bind Phony as a singleton for dependency injection:
$this->app->singleton(Phony::class, fn() => new Phony());
Then inject Phony into controllers/services.
API Responses: Return parsed data in API responses:
return response()->json([
'phone' => $parsed->getNumber(),
'is_valid' => $parsed->isValid(),
'components' => [
'country_code' => $parsed->getCountryCode(),
'area_code' => $parsed->getAreaCode(),
],
]);
Database Storage:
Store normalized numbers (e.g., +38641123456) and use Phony for validation on input.
False Positives/Negatives:
00386 41 123 456 vs. +386 41 123 456).$phony->parse('041123456'); // Valid (local format)
$phony->parse('+38641123456'); // Valid (international)
$phony->parse('386 41 123 456'); // Invalid (missing '+')
Area Code Coverage:
src/Phony.php for hardcoded rules.Performance:
Phony per request in high-traffic apps. Use a singleton.Deprecation Risk:
var_dump($parsed->getData()); // Raw parsed components
$phony = new Phony();
$phony->parse('+386 41 123 456'); // Check logs for parsing logic
Custom Rules:
Override validation logic by extending Phony:
class CustomPhony extends Phony {
protected function validate($number) {
// Add custom rules (e.g., block toll-free numbers)
return parent::validate($number);
}
}
Add Area Codes:
Modify the getAreaCode() logic in Phony.php to include missing codes:
protected function getAreaCode($number) {
// Extend the existing switch-case or regex
}
Format Templates: Add custom formatting patterns:
$parsed->format('(XXX) XXX-XXX'); // e.g., "(411) 234-567"
Extend the format() method to support new templates.
No Config File:
The package is stateless; all rules are hardcoded. For dynamic behavior, subclass Phony or use dependency injection to pass rules.
Locale-Specific: Assumes Slovene numbers by default. For multilingual apps, validate country codes explicitly:
if ($parsed->getCountryCode() !== '386') {
throw new \InvalidArgumentException('Only Slovene numbers supported.');
}
Normalize Input: Strip whitespace/dashes before parsing:
$cleanNumber = preg_replace('/[^\d+]/', '', $rawInput);
$parsed = $phony->parse($cleanNumber);
Combine with Libraries:
Use with libphonenumber for broader coverage:
if (!$phony->parse($number)->isValid()) {
$parsed = libphonenumber\PhoneNumberUtil::getInstance()->parse($number, 'SI');
}
Unit Testing: Test with a fixture of Slovene numbers:
$testNumbers = [
'+386 41 123 456' => true,
'01 123 4567' => true,
'invalid' => false,
];
How can I help you explore Laravel packages today?