tuxonice / pt-zipcode-finder
Portugal zipcode search package with SQLite database
Requires
- php: ^8.1
- ext-mbstring: *
- ext-pdo: *
- ext-pdo_sqlite: *
- doctrine/collections: ^2.3
- symfony/console: ^6.0 || ^7.0
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0
- squizlabs/php_codesniffer: ^3.13
- symfony/var-dumper: ^7.3
This package is auto-updated.
Last update: 2025-08-19 20:06:49 UTC
README
A PHP package for searching Portugal zipcodes using a SQLite database. This package provides tools to import zipcode data from CSV files and perform searches based on zipcode, locality, or street name.
Features
- SQLite database for efficient storage and querying
- Symfony Console commands for easy interaction
- Import data from standard Portugal zipcode CSV files
- Search by zipcode, locality, or street name
- Detailed results with district and municipality information
- Facade implementation for programmatic usage
Installation
Soon...
Usage
Get data to import
The zipcode data can be obtained from the CTT website. You need register and log in to access the data.
The downloaded file is a zip file containing the following files:
File | Description | Rename to |
---|---|---|
concelhos.txt | Municipalities list | municipalities.csv |
distritos.txt | Districs list | districts.csv |
todos_cp.txt | Zipcodes list | zipcodes.csv |
leiame.txt | Readme file |
Extract the files from the zip file and rename them to the expected names.
Importing Data
Before you can search for zipcodes, you need to import the data from the CSV files:
# Import from a CSV directory into a database directory # Syntax: php bin/zipcode-importer import <csv-source-dir> <database-dir> [--dbname=zipcodes] # Example: import CSVs from ./source-dir and create ./data-dir/zipcodes.sqlite php bin/zipcode-importer import source-dir data-dir --dbname=zipcodes # Using absolute paths php bin/zipcode-importer import /abs/path/to/csv /abs/path/to/data --dbname=mydb
Using the ZipcodeFinder Facade
You can use the ZipcodeFinder facade in your PHP code for programmatic access to the zipcode data:
<?php require_once 'vendor/autoload.php'; use Tlab\PtZipcodeFinder\Facade\ZipcodeFinder; // Initialize the facade with the database path created by the import step $finder = new ZipcodeFinder(__DIR__ . '/data/zipcodes.sqlite'); // Search by zipcode $zipcodeResults = $finder->searchByZipcode('1000'); // Search by locality $localityResults = $finder->searchByLocality('porto'); // Search by street name $streetResults = $finder->searchByStreet('liberdade'); // Search across all fields $allResults = $finder->searchAll('lisboa'); // Iterate ArrayCollection of Zipcode models foreach ($zipcodeResults as $zipcode) { echo $zipcode->getFullZipcode() . ' - ' . $zipcode->getPostalDesignation() . PHP_EOL; }
Integration Example
Here's how you might integrate the ZipcodeFinder with a web application:
<?php require_once 'vendor/autoload.php'; use Tlab\PtZipcodeFinder\Facade\ZipcodeFinder; // Handle form submission if (isset($_POST['search'])) { $query = $_POST['query'] ?? ''; $type = $_POST['type'] ?? 'all'; $finder = new ZipcodeFinder(__DIR__ . '/data/zipcodes.sqlite'); // Perform search based on type switch ($type) { case 'zipcode': $results = $finder->searchByZipcode($query); break; case 'locality': $results = $finder->searchByLocality($query); break; case 'street': $results = $finder->searchByStreet($query); break; case 'all': default: $results = $finder->searchAll($query); break; } // Display count echo 'Found ' . $results->count() . ' results'; }
Data Structure
The package uses three main data files:
todos_cp.txt
- Main zipcode data with 17 fields per linedistritos.txt
- District codes and namesconcelhos.txt
- Municipality codes and names
The data format is described in detail in the leiame.txt
file included with the data files.
Database Schema
The package creates three tables in the SQLite database:
districts
- District informationmunicipalities
- Municipality informationzipcodes
- Main zipcode data
Docker Environment
This package includes a Docker environment to make development and testing easier.
Building the Docker Image
docker-compose build
Running the Application
# Run the test service (installs dependencies) docker-compose run test # Run the app service (provides a shell) docker-compose run app
Running Unit Tests
docker-compose run app vendor/bin/phpunit
# Import data
docker-compose run app import
Running Tests
docker-compose run test
License
MIT