Parse, build, query, optimize, sanitize and morph SVG, in pure PHP.
An SVG document as typed PHP objects rather than a string you edit with regular expressions. Load a file, query it with CSS selectors, change it, and write it back. Or build one from nothing.
echo Svg::create(120, 120)->circle(60, 60, 50)->fill('#5a8dee')->toString();Every element is a class, every attribute is validated, and nothing depends on an extension or an external binary. Backed by an extensive test suite and PHPStan at its highest level.
Parse and build · Query · Elements · Paths · Sanitize · Optimize · Accessibility · Morph · Documentation
composer require atelier/svgRequires PHP 8.3 or later. No extensions, no image library, no external binary.
use Atelier\Svg\Svg;
$svg = Svg::load('logo.svg')
->sanitize()
->optimizeWeb();
$svg->save('logo.min.svg');Loading from markup instead of a path is Svg::fromString($markup), and toString() returns
the document without writing a file. See Quick start.
Svg is the fluent facade. It loads an existing document, creates an empty one, and hands back
markup, a pretty-printed string, a file, or a data URI.
$svg = Svg::create(200, 100)
->rect(10, 10, 80, 80)
->circle(150, 50, 40)
->fill('#5a8dee');
$svg->toDataUri(); // data:image/svg+xml;... ready for a CSS backgroundParsing has profiles: the default accepts what a browser accepts, the strict one refuses what is merely loadable. See Document.
The whole tree is objects, and CSS selectors find your way through it.
$document = Svg::load('chart.svg')->getDocument();
foreach ($document->querySelectorAll('g[id^="series-"] path') as $path) {
$path->setAttribute('stroke-width', '2');
}Collections are typed and chainable rather than plain arrays. See Selectors and Collections.
Shapes, text, gradients, filters, clipping and masking, structure, animation: each SVG element is a class with its own attributes rather than a generic node. See Elements.
The d attribute becomes a list of typed segments, which is what makes measuring and rewriting
a curve possible at all.
use Atelier\Svg\Path\Path;
$path = Path::parse('M20,80 C 80,20 220,20 280,80');
$path->getLength();
$path->getPointAtLength(120); // a Point, for placing a marker along the curve
$path->getBoundingBox();Building, analysis, geometry, simplification, and baking transforms into coordinates all live in Paths.
Inline styles, presentation attributes, transform matrices, and the bounding boxes that layout depends on. See Styling.
Accepting an SVG upload means accepting arbitrary markup. One call strips what makes it
dangerous: <script>, on* handlers, javascript: URLs, <foreignObject>, and external
references.
$safe = Svg::fromString($upload)->sanitize()->toString();Profiles range from permissive to strict, and validation is separate for when you need to know what is wrong rather than remove it. See Sanitization.
Fifty passes, grouped into cleanup, conversion, removal, and restructuring. Four presets choose
for you, and optimizeWith() takes a pipeline you assembled yourself.
Svg::load('icon.svg')->optimizeWeb()->save('icon.min.svg');optimizeSafe() preserves ids and metadata, optimizeAggressive() goes for the smallest file.
Writing your own pass is a documented interface, not a fork. See
Optimization.
A generated SVG is invisible to a screen reader until it is told what it shows.
use Atelier\Svg\Element\Accessibility\Accessibility;
Accessibility::setTitle($document, 'Quarterly revenue');
Accessibility::setDescription($document, 'Bar chart comparing Q1 to Q4');Titles, descriptions, ARIA roles and labels, focus order, and an audit that reports what is missing. See Accessibility.
Interpolate between two shapes, whatever their segment counts, and export the result as SMIL, CSS keyframes, JavaScript, or a sprite sheet.
use Atelier\Svg\Morphing\Morph;
use Atelier\Svg\Path\PathParser;
$parser = new PathParser();
$frames = Morph::frames(
$parser->parse('M 0 0 L 100 0 L 100 100 L 0 100 Z'),
$parser->parse('M 50 0 L 100 50 L 50 100 L 0 50 Z'),
60,
'ease-in-out',
);See Morphing.
- Installation: requirements and setup.
- Quick start: load, create, and manipulate a document.
- Document: parse, create, validate, sanitize, export.
- Elements: every element as a typed object.
- Paths: build, measure, simplify, transform.
- Styling: styles, transforms, layout boxes.
- Optimization: the passes, the presets, writing your own.
- Morphing: interpolation and animation export.
- Guides: sanitizing uploads, icon sprites, charts, batch processing.
The full documentation is published at ateliersvg.com/svg.
Contributions are welcome. Visit the project on GitHub to report a bug, suggest a feature, or open a pull request.
Before submitting code, run:
composer qa # PHP-CS-Fixer, PHPStan at level max, and PHPUnitChanges to public behaviour need a test and a documentation update.
Bug reports, security disclosures, and contribution guidelines are collected at ateliersvg.com/support.
Sharing the package or starring it on GitHub helps more than you would think.
Atelier SVG is released under the MIT License.