brunoconte3 / dev-utils
A complete PHP utility library for validating, formatting, comparing data, and more.
Requires
- php: >=8.3
Requires (Dev)
- phpstan/phpstan: 2.1.37
- phpunit/phpunit: 13.1.7
Suggests
- ext-gd: To use the GD implementation
- ext-intl: To use Format with Date
- ext-mbstring: To use Format::lower() etc.
- dev-master
- 2.15.2
- 2.15.1
- 2.15.0
- 2.14.0
- 2.13.0
- 2.12.0
- 2.11.0
- 2.10.0
- 2.9.0
- 2.8.0
- 2.7.0
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.6
- 2.5.5
- 2.5.4
- 2.5.3
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.0
- 2.2.0
- 2.1.0
- 2.0.1
- 2.0.0
- 1.12.1
- 1.12.0
- 1.11.2
- 1.11.1
- 1.11.0
- 1.10.1
- 1.10.0
- 1.9.1
- 1.9.0
- 1.8.0
- 1.7.1
- 1.7.0
- 1.6.4
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.0
- 1.3.0
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.1
- 1.0.0
This package is auto-updated.
Last update: 2026-05-25 19:03:57 UTC
README
dev-utils Pure PHP Data Validation & Formatting Library
Complete pure PHP library for data validation, string formatting, array manipulation, and general utilities. Fully tested with PHPUnit and validated with PHPStan level 10 and SonarQube and PHPCS.
✨ Key Features
- Robust data validation - Email, CPF, CNPJ, dates, time, phone, file uploads and more
- String formatting - Type conversion, currency, date and text formatting
- Array manipulation - Search, filter, sort and transform arrays
- File upload validation - File type, MIME type, image dimensions, size
- General utilities - UUID, comparisons, arrays and string operations
- 100% tested - PHPUnit + PHPStan level 10 + SonarQube + PHPCS
- Code Quality - Validated with industry-standard tools
Quick Navigation
- Quick Start
- Installation
- Common Use Cases
- Data Validation
- File Upload Validation
- Validation Types
- Custom Messages
- String Formatting
- Data Comparison
- Validation Methods
- Generation Utilities
- Array Manipulation
- General Utilities
Quick Start
<?php require 'vendor/autoload.php'; use DevUtils\Validator; $data = ['email' => 'user@example.com']; $rules = ['email' => 'required|email']; $validator = new Validator(); $validator->set($data, $rules); if (!$validator->getErros()) { echo '✓ Validation successful!'; } else { var_dump($validator->getErros()); }
Installation
Install using Composer:
composer require brunoconte3/dev-utils
Or add to your composer.json:
{
"require": {
"brunoconte3/dev-utils": "2.15.1"
}
}
Requirements:
- PHP >= 8.3
- Composer
Why use dev-utils?
- ✓ Pure PHP - Zero external dependencies
- ✓ Fully tested - PHPUnit + PHPStan Level 10 + SonarQube
- ✓ Code Quality - Validated with PHPCS standards
- ✓ Professional Code - Production-ready quality
- ✓ Complete Documentation - Examples for each validator
- ✓ Active Maintenance - Regular updates
🎯 Common Use Cases
Validate registration forms
Validate email, CPF/CNPJ, phone and other data in a single validator.
Process file uploads
Control file size, MIME type, image dimensions and filename.
Format data for display
Format currencies, dates, strings and perform type conversions.
Validate API data
Ensure received data meets your business criteria.
Manipulate complex arrays
Search, sort, filter and transform arrays with ready-to-use methods.
Data Validation Example
Sample Data
$data = [ 'name' => 'Bruno Conte', 'email' => 'bruno@example.com', 'newPassword' => '123456', ];
Validation Rules
$rules = [ 'name' => 'required|alpha|min:7|max:100', 'email' => 'required|email|max:80', 'newPassword' => 'required|email|max:50', ];
Validate the Data
<?php require 'vendor/autoload.php'; use DevUtils\Validator; $validator = new Validator(); $validator->set($data, $rules); if (!$validator->getErros()) { echo '✓ Validation successful!'; } else { var_dump($validator->getErros()); }
Validating File(s) Upload
Validate file uploads with validators: fileName, maxFile, maxUploadSize, mimeType, minFile, minUploadSize, minHeight, minWidth, maxHeight, maxWidth and requiredFile.
Control minimum/maximum file size (bytes), number of files, allowed extensions, image dimensions, filename and field requirements.
HTML Form
<!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <title>Upload de Arquivos</title> </head> <body> <form method="POST" enctype="multipart/form-data"> <!-- Upload a single file --> <input type="file" name="fileUploadSingle" /> <!-- Upload single or multiple files --> <input type="file" name="fileUploadMultiple[]" multiple="multiple" /> <button type="submit">Submit</button> </form> </body> </html>
PHP Validation
<?php /** * Notes: * - maxFile, minFile, minHeight, minWidth, maxUploadSize, maxHeight, maxWidth, minUploadSize: Must be integers * - mimeType: Pass an array with allowed extensions, separated by ';' */ if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') === 'POST') { $fileUploadSingle = $_FILES['fileUploadSingle']; $fileUploadMultiple = $_FILES['fileUploadMultiple']; $datas = [ 'fileUploadSingle' => $fileUploadSingle, 'fileUploadMultiple' => $fileUploadMultiple, ]; $rules = [ 'fileUploadSingle' => 'requiredFile|fileName|mimeType:jpeg;png;jpg;txt;docx;xlsx;pdf|minUploadSize:10|maxUploadSize:100|minWidth:200|maxWidth:200', 'fileUploadMultiple' => 'fileName|mimeType:jpeg|minFile:1|maxFile:3|minUploadSize:10|minWidth:200|maxWidth:200|maxUploadSize:100', ]; $validator = new DevUtils\Validator(); DevUtils\Format::convertTypes($datas, $rules); $validator->set($datas, $rules); if (!$validator->getErros()) { echo '✓ Files validated successfully!'; } else { echo '<pre>'; print_r($validator->getErros()); } } ?>
Validation types (validators)
Complete list of available validators in the library. Use them in your validation rules to ensure data meets your business criteria.
Text Validators
| Validator | Description |
|---|---|
| alpha | Only alphabetic characters |
| alphaNoSpecial | Regular text without accents |
| alphaNum | Alphanumeric characters |
| alphaNumNoSpecial | Letters without accents + numbers |
| lower | All lowercase characters |
| notSpace | Check if contains spaces |
| regex | Custom regular expression validation |
| upper | All uppercase characters |
Brazilian Data Validators
| Validator | Description |
|---|---|
| companyIdentification | Validates CNPJ with or without mask |
| ddd | Validates DDD by state or general (e.g. ddd:pr) |
| identifier | Validates CPF with or without mask |
| identifierOrCompany | Validates CPF or CNPJ |
| phone | Phone with DDD (10 or 11 digits) |
| plate | Vehicle license plate |
Date and Time Validators
| Validator | Description |
|---|---|
| dateAmerican | American date format (MM/DD/YYYY) |
| dateBrazil | Brazilian date format (DD/MM/YYYY) |
| dateIso8601 | ISO 8601 date (2025-11-20T10:30:00Z) |
| dateNotFuture | Validates date is not in the future |
| dateUTCWithoutTimezone | UTC date without Z (2025-11-20T10:30:00) |
| hour | Validates hour format |
| noWeekend | Checks if date is not a weekend |
| numMonth | Validates month (1-12) |
| timestamp | Validates Unix timestamp |
Type Validators
| Validator | Description |
|---|---|
| array | Check if it is an array |
| bool | Boolean values (true/false, 1/0, yes/no) |
| float | Decimal/floating value |
| int | Integer type (attempts parse) |
| integer | Integer with strict type check |
| json | Valid JSON |
| numeric | Only numeric values (accepts leading zeros) |
Constraint Validators
| Validator | Description |
|---|---|
| equals | Field must equal another field |
| max | Maximum size |
| maxWords | Maximum number of words |
| min | Minimum size |
| minWords | Minimum number of words |
| optional | Validates only if not empty |
| required | Required field |
Network and Identifier Validators
| Validator | Description |
|---|---|
| Email validation | |
| ip | Valid IP address |
| mac | Valid MAC address |
| rgbColor | Valid RGB color |
Numeric Comparison Validators
| Validator | Description |
|---|---|
| numMax | Maximum value (minimum = 0) |
| numMin | Minimum value (minimum = 0) |
File Upload Validators
| Validator | Description |
|---|---|
| fileName | Validates and formats filename |
| maxFile | Maximum number of files |
| maxHeight | Maximum image height (pixels) |
| maxUploadSize | Maximum file size (bytes) |
| maxWidth | Maximum image width (pixels) |
| minFile | Minimum number of files |
| minHeight | Minimum image height (pixels) |
| minUploadSize | Minimum file size (bytes) |
| minWidth | Minimum image width (pixels) |
| mimeType | Defines allowed extensions (separated by ;) |
| requiredFile | Required file field |
Defining custom message
After defining some of our rules to the data you can also add a custom message using the ',' delimiter in some specific rule or using the default message.
Example:
<?php $validator->set($datas, [ 'name' => 'required, The name field cannot be empty', 'email' => 'email, The email field is incorrect|max:50', 'password' => 'min:8, nat least 8 characters|max:12, no máximo 12 caracteres.', ]);
Formatting Examples
<?php require 'vendor/autoload.php'; use DevUtils\Format; Format::companyIdentification('A1B2C3D45E6F59'); //CNPJ ==> A1.B2C.3D4/5E6F-59 Format::convertTimestampBrazilToAmerican('15/04/2021 19:50:25'); //Convert Timestamp Brazil to American format Format::currency('113', 'R$ '); //Default currency BR ==> 123.00 - the 2nd parameter chooses the Currency label Format::currencyUsd('1123.45'); //Default currency USD ==> 1,123.45 - the 2nd parameter chooses the Currency label Format::dateAmerican('12-05-2020'); //return date ==> 2020-05-12 Format::dateBrazil('2020-05-12'); //return date ==> 12/05/2020 Format::identifier('73381209000'); //CPF ==> 733.812.090-00 Format::identifierOrCompany('30720870089'); //CPF/CNPJ Brazil ==> 307.208.700-89 Format::falseToNull(false); //Return ==> null Format::lower('CArrO'); //lowercase text ==> carro - the 2nd parameter chooses the charset, UTF-8 default //[Apply any type of Mask, accepts space, points and others] Format::mask('#### #### #### ####', '1234567890123456'); //Mask ==> 1234 5678 9012 3456 Format::maskStringHidden('065.775.009.96', 3, 4, '*'); //Mask of string ==> 065.***.009.96 Format::onlyNumbers('548Abc87@'); //Returns only numbers ==> 54887; Format::onlyLettersNumbers('548Abc87@'); //Returns only letters and numbers ==> 548Abc87; Format::pointOnlyValue('1.350,45'); //Currency for recording on the BD ==> 1350.45 Format::removeAccent('Açafrão'); //Remove accents and character 'ç' ==> Acafrao //Removes all special characters ==> "Acafrao com Espaco", 2nd parameter chooses whether to allow space, default true Format::removeSpecialCharacters('Açafrão com Espaco %$#@!', true); Format::returnPhoneOrAreaCode('44999998888', false); //Returns only the phone number ==> 999998888 Format::returnPhoneOrAreaCode('44999998888', true); //Returns only the phone's area code ==> 44 Format::reverse('Abacaxi'); //Returns inverted string ==> ixacabA Format::telephone('44999998888'); //Return phone format brazil ==> (44) 99999-8888 Format::ucwordsCharset('aÇafrÃo maCaRRão'); //Return first capital letter ==> Açafrão Macarrão Format::upper('Moto'); //lowercase text ==> MOTO - the 2nd parameter chooses the charset, UTF-8 default Format::zipCode('87030585'); //CEP format brazil ==> 87030-585 Format::writeDateExtensive('06/11/2020'); //Date by Long Brazilian format ==> sexta-feira, 06 de novembro de 2020 Format::writeCurrencyExtensive(1.97); //Coin by Extensive Brazilian format ==> um real e noventa e sete centavos Format::convertStringToBinary('amor'); //String to binary ==> 1100001 1101101 1101111 1110010 Format::slugfy('Polenta frita e Parmesão'); //Returns a slug from a string ==> polenta-frita-e-parmesao $data = [ 'treatingIntType' => '12', 'handlingFloatType' => '9.63', 'treatingBooleanType' => 'true', 'handlingNumericType' => '11', ]; $rules = [ 'treatingIntType' => 'convert|int', 'handlingFloatType' => 'convert|float', 'treatingBooleanType' => 'convert|bool', 'handlingNumericType' => 'convert|numeric', ]; Format::convertTypes($data, $rules); //Convert the value to its correct type ['bool', 'float', 'int', 'numeric',] /*** Return [ 'treatingIntType' => int 12 'handlingFloatType' => float 9.63 'treatingBooleanType' => boolean true 'handlingNumericType' => float 11 ] ***/ $array = [ 0 => '1', 1 => '123', 'a' => '222', 'b' => 333, 'c' => '', ]; $newArray = Format::emptyToNull($array); //Convert empty to null, - the 2nd parameter is optional, passing the desired exception /*** Return [ 0 => 1, 1 => 123, 'a' => 222, 'b' => 333, 'c' => null, ]; **/ //$value = Format::arrayToInt($array); ==> Option for other than by Reference Format::arrayToIntReference($array); //Formats array values in integer ==> [ 0 => 1, 1 => 123, 'a' => 222, 'b' => 333, 'c' => 0, ];
Formatting Upload File(s)
Example: Uploading a single file
<?php $fileUploadSingle = [ 'name' => 'JPG - Upload Validation v.1.jpg', 'type' => 'image/jpeg', 'tmp_name' => '/tmp/phpODnLGo', 'error' => 0, 'size' => 8488, ]; Format::restructFileArray($fileUploadSingle); // Call of the method responsible for normalizing the array [ 0 => [ 'name' => 'jpg___upload_validation_v_1.jpg', 'type' => 'image/jpeg', 'tmp_name' => '/tmp/phpBmqX1i', 'error' => 0, 'size' => 8488, 'name_upload' => '22-01-2021_13_1830117018768373446425980271611322393600ad419619ec_jpg___upload_validation_v_1.jpg', ] ]
Example: Uploading multiple files
<?php $fileUploadMultiple = [ 'name' => [ '0' => 'JPG - Upload Validation v.1.jpg', '1' => 'PDF - Upload Validation v.1.pdf', '2' => 'PNG - Upload Validation v.1.png', ], 'type' => [ '0' => 'image/jpeg', '1' => 'application/pdf', '2' => 'image/png', ], 'tmp_name' => [ '0' => '/tmp/phpODnLGo', '1' => '/tmp/phpfmb0tL', '2' => '/tmp/phpnoejk8', ], 'error' => [ '0' => 0, '1' => 0, '2' => 0, ], 'size' => [ '0' => 8488, '1' => 818465, '2' => 1581312, ], ]; Format::restructFileArray($fileUploadMultiple); // Call of the method responsible for normalizing the array [ 0 => [ 'name' => 'jpg___upload_validation_v_1.jpg', 'type' => 'image/jpeg', 'tmp_name' => '/tmp/phpBmqX1i', 'error' => 0, 'size' => 8488, 'name_upload' => '22-01-2021_13_1830117018768373446425980271611322393600ad419619ec_jpg___upload_validation_v_1.jpg', ], 1 => [ 'name' => 'pdf___upload_validation_v_1.pdf', 'type' => 'application/pdf', 'tmp_name' => '/tmp/phpYo0w7c', 'error' => 0, 'size' => 818465, 'name_upload' => '22-01-2021_13_170624609160164419213582611971611322393600ad41961a5a_pdf___upload_validation_v_1.pdf', ], 2 => [ 'name' => 'png___upload_validation_v_1.png', 'type' => 'image/png', 'tmp_name' => '/tmp/phpme7Yf7', 'error' => 0, 'size' => 1581312, 'name_upload' => '22-01-2021_13_8675237129330338531328755051611322393600ad41961ac8_png___upload_validation_v_1.png', ], ]
Comparisons Examples
<?php require 'vendor/autoload.php'; use DevUtils\Compare; //Returns +30 (+30 days difference) Compare::daysDifferenceBetweenData('31/05/2020', '30/06/2020'); //Accepts American date too //Compares if start date is less than end date => Returns [bool] Compare::startDateLessThanEnd('30/07/2020', '30/06/2020'); //Accepts American date too //Difference between hours ==> 01:36:28 [Hours displays negative and positive difference] Compare::differenceBetweenHours('10:41:55', '12:18:23'); //Compares if the start time is less than the end time (3rd parameter, accept custom message) Compare::startHourLessThanEnd('12:05:01', '10:20:01'); //Compares the date to the current date, and returns the person's age Compare::calculateAgeInYears('20/05/1989'); //Compares fields for equality, returns boolean //optional third parameter, false to not compare caseSensitive, default true Compare::checkDataEquality('AçaFrão', 'Açafrão'); //Compares if desired content exists in String, returns boolean Compare::contains('AçaFrão', 'çaF'); //Compares the corresponding URL with the second parameter, starts with the string entered in the first parameter. Returns boolean. Compare::beginUrlWith('/teste', '/teste/variavel'); //Compares the corresponding URL with the second parameter, ends with the string entered in the first parameter. Returns boolean. Compare::finishUrlWith('/teste', 'sistema/teste'); //Compares if the corresponding string with the first parameter is equal to the substring obtained from the second parameter. Extracting to compare 7 characters from the second parameter starting at position 0. Returns boolean. Compare::compareStringFrom('sistema', 'sistema/teste', 0, 7);
Validations in the form of Methods
<?php require 'vendor/autoload.php'; use DevUtils\ValidateCnpj; ValidateCnpj::validateCnpj('A1.B2C.3D4/5E6F-59'); //Returns boolean, example true [Can pass without mask] use DevUtils\validateCpf; ValidateCpf::validateCpf('257.877.760-89'); //Returns boolean, example true [Can pass without mask] use DevUtils\ValidateDate; //Examples return true ValidateDate::validateDateBrazil('29/04/2021'); //Return boolean [Format dd/mm/yyyy] ValidateDate::validateDateAmerican('2021-04-29'); //Return boolean [Format yyyy-mm-dd] ValidateDate::validateTimeStamp('2021-04-29 11:17:12'); //Return boolean [Format yyyy-mm-dd hh:mm:ss] ValidateDate::validateDateIso8601('2025-11-20T10:30:00Z'); //Return boolean [Format ISO 8601: 2025-11-20T10:30:00Z] ValidateDate::validateDateUTCWithoutTimezone('2025-11-20T10:30:00'); //Return boolean [Format UTC without Z: 2025-11-20T10:30:00] use DevUtils\ValidateHour; ValidateHour::validateHour('08:50'); //Return boolean [Format YY:YY] use DevUtils\ValidatePhone; ValidatePhone::validate('44999999999'); //Return boolean [[You can wear a mask] use DevUtils\ValidateString; ValidateString::minWords('Bruno Conte', 2) //Return boolean ValidateString::maxWords('Bruno Conte', 2) //Return boolean
Generation Utilities
UUID v7 - Generate and Validate
<?php require 'vendor/autoload.php'; use DevUtils\Uuid; // Generate UUID v7 (timestamp-based, sortable, unique) $uuid = Uuid::generate(); // ==> 01890f87-4f0b-7f6b-8b1d-9f4f9d7c3b5a // Validate any UUID version (v1 to v8) Uuid::isValid('550e8400-e29b-41d4-a716-446655440000'); // ==> true // Validate specific version Uuid::isValid('01890f87-4f0b-7f6b-8b1d-9f4f9d7c3b5a', 7); // ==> true
Password Generation
<?php use DevUtils\Utility; /* Generate secure passwords int $size ==> Number of characters (Required) bool $uppercase ==> Include uppercase letters (default: true) bool $lowercase ==> Include lowercase letters (default: true) bool $numbers ==> Include numbers (default: true) bool $symbols ==> Include symbols (default: true) */ Utility::generatePassword(10); // ==> aB3$xY9!zK Utility::generatePassword(16, true, true, true, false); // Without symbols
Manipulate Arrays
<?php require 'vendor/autoload.php'; use DevUtils\Arrays; $array = ['primeiro' => 15, 'segundo' => 25]; var_dump(Arrays::searchKey($array, 'primeiro')); // Search for key in array, and Return position ==> returns 0 var_dump(Arrays::searchKey($array, 'segundo')); // Search for key in array, and Return position ==> returns 1 var_dump(Arrays::searchKey($array, 'nao-existe')); // Search for key in array, and Return position ==> returns null $array = ['primeiro' => 10, 'segundo' => 20]; Arrays::renameKey($array, 'primeiro', 'novoNome'); var_dump($array); //Rename array key ==> ['novoNome' => 10, 'segundo' => 20]; $array = [ 'frutas' => ['fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva'], 'verduras' => ['verdura_1' => 'Rúcula', 'verdura_2' => 'Acelga', 'verdura_3' => 'Alface'], 'legume' => 'Tomate' ]; // Checks in the array, if there is any index with the desired value var_dump(Arrays::checkExistIndexByValue($array, 'Tomate')); // Performs the search in the array, through the key and Return an array with all indexes located var_dump(Arrays::findValueByKey($array, 'verduras')); // Performs the search in the array, through a value and returns an array with all items located var_dump(Arrays::findIndexByValue($array, 'Tomate')); $xml = new SimpleXMLElement('<root/>'); Arrays::convertArrayToXml($array, $xml); // Convert array to Xml var_dump($xml->asXML()); $array = [ 'frutas' => ['fruta_1' => 'Maçã', 'fruta_2' => 'Pêra', 'fruta_3' => 'fruta', 'fruta_4' => 'Uva'], 'verduras' => '{"verdura_1": "Rúcula", "verdura_2": "Acelga", "verdura_3": "Alface"}' ]; // Checks the array, if it has any index with JSON and turns it into an array Arrays::convertJsonIndexToArray($array); var_dump($array); $array = [ 'pessoa' => [ 'pedidos' => ['pedido1', 'pedido2'], 'categorias' => [ 'subcategorias' => [ 'subcategoria1' => 'valor teste' ] ] ] ]; // Checks if a specific index exists in a multilevel array var_dump(Arrays::checkExistIndexArrayRecursive($array, 'subcategoria1')); // Return true
Utilities
<?php require 'vendor/autoload.php'; use DevUtils\Utility; Utility::captureClientIp(); // Return user IP, capture per layer available, eg 201.200.25.40 /* * @return string -> Full URL string * @param string $host -> system domain * @param string $absolutePath -> absolute path * @param string $https -> 'on' to generate https url, null or other value, generate http url */ Utility::buildUrl('localhost', '/sua-url/complemento', 'on'); // Return to URL
Check the minimum coverage of CI/CD unit tests using PHPUnit
file: .gitlab-ci.yml Add Lines: script: - composer install - ./vendor/bin/phpunit --coverage-xml coverage #Here generates the coverage file - php ./src/CI.php coverage/index.xml 80 #Change the value 80 to your value file: .gitignore Add Line: /coverage/
Will perform pull request, please execute unit tests, and phpstan level 10
./vendor/bin/phpunit --coverage-xml coverage
./vendor/bin/phpstan analyse -c phpstan.neon --level 10
If you don't know how to run phpstan, I execute and adjust whatever is necessary
💬 Support and Documentation
Need Help?
- 📖 Check the complete documentation
- 🐛 Found a bug? Open an issue
- 💡 Have a suggestion? Submit a feature request
Contributing
Contributions are welcome! Please:
- Fork the project
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Make sure:
- All tests pass:
phpunit - Code follows standards:
phpstan analyse -c phpstan.neon --level 10 - PSR-12 compliance:
phpcs
📊 Code Quality
- ✅ PHPUnit - Full test coverage
- ✅ PHPStan Level 10 - Advanced static analysis
- ✅ SonarQube - Code quality and security analysis
- ✅ PHPCS - PHP Code Sniffer for coding standards
- ✅ Zero dependencies - Pure PHP
🔗 Useful Links
GitHub https://github.com/brunoconte3/dev-utils
Packagist https://packagist.org/packages/brunoconte3/dev-utils
Issues https://github.com/brunoconte3/dev-utils/issues
Wiki https://github.com/brunoconte3/dev-utils/wiki
📝 Changelog
See CHANGELOG.md for complete version history and changes.
🌟 If you like this project
If this project was useful to you:
- ⭐ Leave a star on GitHub
- 🍴 Fork and share
- 💬 Give feedback and suggestions
License
The validator is an open-source application licensed under the MIT License.