zdenekgebauer / sitemap-writer
Sitemap XML Writer
1.0.0
2026-10-29 18:35 UTC
Requires
- php: >=8.5
- ext-xmlwriter: *
- ext-zlib: *
Requires (Dev)
- ext-simplexml: *
- codeception/codeception: ^5.3
- codeception/module-asserts: ^3.3
- infection/codeception-adapter: ^0.4
- infection/infection: ^0.35
- phpstan/phpstan: ^2.3
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-strict-rules: ^2.1
- rector/rector: ^2.8
- shipmonk/composer-dependency-analyser: ^1.8
- symplify/easy-coding-standard: ^13.3
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-29 17:51:44 UTC
README
PHP library for generating sitemap XML files compliant with sitemaps.org.
Features
- Automatic file splitting at 50,000 URLs per file
- Automatic
sitemap_index.xmlgeneration when multiple files are produced - Optional gzip compression (
.xml.gzinstead of.xml) - Configurable filename pattern
- Input validation per sitemaps.org specification (URL max 2048 chars, priority 0.0–1.0)
Requirements
PHP 8.5 or newer with the xmlwriter and zlib extensions. No runtime dependencies.
Installation
composer require zdenekgebauer/sitemap-writer
Usage
use ZdenekGebauer\SitemapWriter\ChangeFrequency;
use ZdenekGebauer\SitemapWriter\SitemapItem;
use ZdenekGebauer\SitemapWriter\SitemapWriter;
$writer = new SitemapWriter('/path/to/output/', 'https://example.com/');
$writer->addItem(new SitemapItem(
url: 'https://example.com/page',
lastMod: new DateTime(),
changeFreq: ChangeFrequency::WEEKLY,
priority: 0.8,
));
$writer->close(); // MUST be called after the last item
Note:
close()must always be called explicitly. If omitted,__destruct()throwsLogicException.
API
SitemapWriter
new SitemapWriter(
string $directory, // existing writable output directory
string $baseUrl, // URL of $directory, used in sitemap_index.xml
bool $createGzip = false, // write .xml.gz files instead of .xml
string $sitemapFileName = 'sitemap%d.xml', // filename pattern (see below)
)
Filename pattern:
- The first file omits the number:
sitemap%d.xml→sitemap.xml - Subsequent files use the number:
sitemap2.xml,sitemap3.xml, … - If
%dis absent (e.g.sitemap.xml), the number is inserted before the extension
| Pattern | File 1 | File 2 | File 3 |
|---|---|---|---|
sitemap%d.xml | sitemap.xml | sitemap2.xml | sitemap3.xml |
sitemap.xml | sitemap.xml | sitemap2.xml | sitemap3.xml |
custom%d-map.xml | custom-map.xml | custom2-map.xml | custom3-map.xml |
Methods:
addItem(SitemapItem $item): void— adds a URL entryclose(): void— finalizes all files; generatessitemap_index.xmlif >1 file was produced
Output:
- Each file holds at most 50,000 URLs, the next URL starts a new file.
sitemap_index.xmlis always named so, whatever the filename pattern, and it is never compressed. Each entry is$baseUrlfollowed by the file name (e.g.https://example.com/sitemap2.xml.gz), so$baseUrlends with/.lastmodof an entry is the modification time of the file.close()without any added item writes no file.- Files are overwritten, but files of an earlier run are not deleted. When the earlier run produced more files,
remove the old sitemap files and
sitemap_index.xmlfirst, otherwise a stale index keeps pointing to them. - A missing or read-only
$directorythrows no exception; PHP emits warnings and no sitemap is written.
SitemapItem
new SitemapItem(
string $url,
DateTimeInterface $lastMod,
ChangeFrequency $changeFreq = ChangeFrequency::MONTHLY,
float $priority = 0.5, // range 0.0–1.0
)
Throws InvalidArgumentException if:
$urlexceeds 2048 characters$priorityis outside the range 0.0–1.0
ChangeFrequency
String-backed enum with values: ALWAYS, HOURLY, DAILY, WEEKLY, MONTHLY, YEARLY, NEVER.
Development
Local environment runs on Lando (Docker, PHP 8.5 + xdebug):
lando start # start the environment
lando install # install dependencies
lando tests # run the test suite
lando coverage # test suite with code coverage
lando dependency-analyser # composer.json dependencies against their usage
lando ecs # coding standards (lando ecs-fix to apply)
lando infection # mutation testing, requires 100 % MSI
lando phpstan # static analysis, level max
lando rector # modernization dry-run (lando rector-fix to apply)
License
MIT — see LICENSE.