How SunSitemap Handles Relative vs. Absolute Paths for Output
SunSitemap accepts an optional relative directory in its constructor, converts it to an absolute filesystem path using $_SERVER['DOCUMENT_ROOT'], and prefixes all generated URLs with that same relative segment to ensure files and their public addresses remain synchronized.
The msbatal/php-sitemap-generator repository provides SunSitemap, a PHP class that generates XML sitemaps and robots.txt files. Understanding how SunSitemap handles relative vs. absolute paths for output is essential for controlling where sitemap files are stored on disk versus how they are referenced in public URLs.
Path Resolution in the Constructor
The constructor performs distinct logic depending on whether you supply the second parameter, $relPath.
Validating and Sanitizing the Relative Path
When you provide a non-empty $relPath, SunSitemap validates the directory with file_exists() and sanitizes the string by removing any ../ or ./ components. It then appends a trailing slash and constructs the absolute filesystem path by prepending $_SERVER['DOCUMENT_ROOT'].
In SunSitemap.php (lines 121–127), the code executes:
if (!empty($relPath)) {
// Validation and sanitization occurs here
$this->relPath = /* sanitized path with trailing slash */;
$this->absPath = $_SERVER['DOCUMENT_ROOT'] . '/' . $this->relPath;
}
This ensures that $this->absPath always points to a physical location under the web root, regardless of how the relative path was originally formatted.
Defaulting to Document Root
If you omit $relPath or pass an empty value, the class falls back to the document root. According to lines 128–130 of SunSitemap.php, the constructor sets:
else {
$this->relPath = null;
$this->absPath = $_SERVER['DOCUMENT_ROOT'] . '/';
}
This fallback guarantees that $this->absPath remains a valid, writable directory for sitemap output.
URL Construction for Sitemap Entries
SunSitemap keeps the public URL structure synchronized with the filesystem location. When building the <loc> element for each URL entry, the class concatenates the base URL, the relative path, and the specific page identifier.
As implemented in SunSitemap.php at line 166:
$urlArray['loc'] = rtrim($this->baseUrl, '/') . '/' . ltrim($this->relPath . $urls, '/');
If $this->relPath is null, the URL contains only the base URL and the page path. If a relative directory was specified, that segment appears between the domain and the page path, matching the directory structure under DOCUMENT_ROOT.
File Writing Operations
All disk writes use the pre-computed $this->absPath property, ensuring files land exactly where the relative path indicates. The generator creates sitemap indexes, individual sitemap files, compressed .gz variants, and robots.txt by concatenating $this->absPath with the target filename.
In SunSitemap.php (lines 240–258 and 279–302), you will find operations such as:
fopen($this->absPath . $this->sitemapIndex[0], 'w');
// Similar calls for $this->sitemaps[0][0], gzipped files, and robots.txt
This approach cleanly separates the filesystem location (absPath) from the public URL base (baseUrl), while maintaining consistency through the shared relative segment (relPath).
Configuration Examples
The following examples demonstrate both relative and absolute path handling in practice.
Default Document Root Location
When you omit the relative path, files are written directly to DOCUMENT_ROOT and URLs contain no subdirectory:
$sitemap = new SunSitemap('https://example.com');
$sitemap->addUrl('about');
$sitemap->createSitemap()->updateRobots();
Result: sitemap.xml and robots.txt are stored in $_SERVER['DOCUMENT_ROOT']/. The sitemap entry becomes https://example.com/about.
Subdirectory Output
Passing a relative path creates a nested directory structure on disk and in URLs:
$sitemap = new SunSitemap('https://example.com', 'sitemaps');
$sitemap->addUrl('contact');
$sitemap->createSitemap()->updateRobots();
Result: Files are written to $_SERVER['DOCUMENT_ROOT']/sitemaps/. The URL inside the sitemap becomes https://example.com/sitemaps/contact.
Advanced Configuration with Compression
You can combine path configuration with performance options:
$sitemap = new SunSitemap(
'https://example.com',
'sitemaps',
1000, // max URLs per file
true // generate .gz files
);
$sitemap->addUrl(['page1', 'page2']);
$sitemap->createSitemap()->updateRobots();
Result: Both sitemap.xml and sitemap.xml.gz reside under DOCUMENT_ROOT/sitemaps/, with corresponding URLs prefixed by /sitemaps/.
Summary
- Constructor sanitization: SunSitemap validates the relative path, strips traversal sequences, and builds an absolute filesystem path using
$_SERVER['DOCUMENT_ROOT']. - Dual path storage: The class stores both
relPath(for URL generation) andabsPath(for file operations) to keep web addresses and disk locations synchronized. - Fallback behavior: Omitting the relative path defaults output to the document root with no URL prefix.
- Secure file writing: All
fopen()calls use the pre-resolved$this->absPathto prevent path injection and ensure predictable file placement.
Frequently Asked Questions
What happens if I omit the relative path parameter?
SunSitemap defaults to the document root. The constructor sets $this->relPath to null and $this->absPath to $_SERVER['DOCUMENT_ROOT'] . '/', causing all files to be written directly to the web root and URLs to contain only the base domain.
How does SunSitemap sanitize the relative path input?
The constructor checks file_exists() on the provided directory and removes any ../ or ./ components to prevent directory traversal. It also normalizes the string to include a trailing slash before appending it to DOCUMENT_ROOT.
Where are the sitemap files physically stored when using a subdirectory?
When you specify a relative path like 'sitemaps', the class stores files at $_SERVER['DOCUMENT_ROOT'] . '/sitemaps/'. All file operations, including the sitemap index, individual sitemaps, and optional .gz archives, use this absolute path.
How does the class keep filesystem paths and public URLs synchronized?
SunSitemap uses the same $relPath value in two places: it appends the segment to $_SERVER['DOCUMENT_ROOT'] for disk operations (absPath) and to the base URL for web addresses (loc). This ensures that if files live in /sitemaps/ on disk, the corresponding URLs automatically include /sitemaps/ in the path.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →