Search by

zdenekgebauer / sitemap-writer

zdenekgebauer

Sitemap XML Writer

Package info

gitlab.com/zdenekgebauer/sitemap-writer

Issues

pkg:composer/zdenekgebauer/sitemap-writer

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

1.0.0 2026-10-29 18:35 UTC

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.xml generation when multiple files are produced
  • Optional gzip compression (.xml.gz instead 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() throws LogicException.

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 %d is absent (e.g. sitemap.xml), the number is inserted before the extension
PatternFile 1File 2File 3
sitemap%d.xmlsitemap.xmlsitemap2.xmlsitemap3.xml
sitemap.xmlsitemap.xmlsitemap2.xmlsitemap3.xml
custom%d-map.xmlcustom-map.xmlcustom2-map.xmlcustom3-map.xml

Methods:

  • addItem(SitemapItem $item): void — adds a URL entry
  • close(): void — finalizes all files; generates sitemap_index.xml if >1 file was produced

Output:

  • Each file holds at most 50,000 URLs, the next URL starts a new file.
  • sitemap_index.xml is always named so, whatever the filename pattern, and it is never compressed. Each entry is $baseUrl followed by the file name (e.g. https://example.com/sitemap2.xml.gz), so $baseUrl ends with /. lastmod of 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.xml first, otherwise a stale index keeps pointing to them.
  • A missing or read-only $directory throws 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:

  • $url exceeds 2048 characters
  • $priority is 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.