PHPackages                             noccylabs/sdl - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. noccylabs/sdl

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

noccylabs/sdl
=============

Simple Declarative Language (SDL)

2.0.5(5y ago)81461GPL-2.0+PHP

Since Jan 12Pushed 5y ago1 watchersCompare

[ Source](https://github.com/noccylabs/php-sdl)[ Packagist](https://packagist.org/packages/noccylabs/sdl)[ RSS](/packages/noccylabs-sdl/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependencies (2)Versions (9)Used By (0)

[![Build Status](https://camo.githubusercontent.com/99b8686315776b64bd631ca8a242391965aff7c9458bfb96620e0dae9059d605/68747470733a2f2f7472617669732d63692e6f72672f6e6f6363796c6162732f7068702d73646c2e7376673f6272616e63683d73646c32)](https://travis-ci.org/noccylabs/php-sdl)

php-sdl 2.0
===========

[](#php-sdl-20)

This is an implementation of the Simple Declarative Language (SDL) serialization language for PHP. It has not thing to do with Simple Directmedia Layer. Think of it like XML with less typing:

```
    greetings {
        greeting "Aloha" where="Hawaii"
        greeting "Hej" where="Sweden"
    }

```

This is the v2.0 rewrite of php-sdl, and as such some things are not quite working yet. If you are looking for a working but not too extensible parser, install the v1.x branch with composer, `composer require noccylabs/sdl:1.*`. The current quirks are:

- Not all `LiteralType`s are implemented. This is easily done now however, as each type is in its own folder.
- The parser is broken still.
- Not all unit tests have been created.
- Comments can be generated, but not necessarily always parsed.
- Numeric types may lose precision.

Usage
-----

[](#usage)

You shouldn't really use this right now. Here is a brief summary of what is working, and what is not. Contributions and improvements are welcome.

### Components

[](#components)

**Component****Description****Status**`Sdl\SdlTag`Creating tag treesWORKING`Sdl\SdlTag`Encoding tags and childrenWORKING`Sdl\SdlTag`Encoding tags with commentsWORKING`Sdl\SdlTag`Tree traversalWORKING`Sdl\SdlTag`Tests implementedPARTIAL`Sdl\Parser\SdlParser`Parsing tags and nested tagsWORKING`Sdl\Parser\SdlParser`Parsing tags with comments`Sdl\Parser\SdlParser`Tests implementedPARTIAL`Sdl\LiteralType\TypeFactory`LiteralType registeringPARTIAL`Sdl\LiteralType\TypeFactory`Tests implementedPARTIAL`Sdl\LiteralType\*Type`All types implementedPARTIAL`Sdl\LiteralType\*Type`Tests implementedPARTIAL`Sdl\Selector\SdlSelector`Selecting with expressionsPARTIAL`Sdl\Selector\SdlSelector`Tests implemented### Functionality

[](#functionality)

**Function****Status**Creating tag treesWORKINGEncoding tag trees into SDLWORKINGParsing SDL into tag treesPARTIALNavigating the tag treeWORKINGSelecting tags with expressionsPARTIALCreate LiteralTypes from native PHP variable typesWORKINGCreate LiteralTypes from SDL tokensPARTIALAccess LiteralTypes as native PHP valuesPARTIALEncode LiteralTypes into SDL tokensPARTIALPerformance
-----------

[](#performance)

The parser is currently a little slow at reading, but this can probably be optimized somewhat. Either way it offers a tidy alternative to the established serialization formats (XML, JSON and YAML). It is important to remember that the parsers for XML, JSON and YAML are running as native code, while the SDL parser is written in PHP.

That being said, it should be noted that php-sdl is best used with configuration files that are not being requested at an excessive frequency (such as blog posts, routing tables etc.) but rather for f.ex. job configurations, or immediate files (like dumping blogposts into sdl for easy editing and import).

Caching is implemented as it was in the 1.x version of the parser, i.e. the cache file with the parsed tags is placed in the same directory as the SDL-fil being parsed, with an identical filename except prefixed with a dot (.) and suffixed with ".cache". For example "foo.sdl" would be cached as ".foo.sdl.cache". This behaviour might change in the future.

**Format****Parser****10000x****Calls/s**SDLSdlParser::parseString8.83s1132.50XMLDomDocument::loadXml0.43s23469.17JSONjson\_decode0.26s38640.62YAMLyaml\_parse\_file0.44s22738.22Some possible improvements and optimizations include:

- Improvements to the pre-parser optimization routines.
- Rewrite the parser using regular expressions (could be faster, could be slower)

Examples
--------

[](#examples)

### Generating tag trees

[](#generating-tag-trees)

Generating is simple. Get a new root tag with `createRoot()` and start adding your children. You can use the same fluid programming as you are used to from Symfony2, where all the `setX()` methods return the current tag, and a call to `end()` returns the parent node. `createChild()` is available to create a tag, add it as a child to the current node, and return the newly created child tag.

```
    use Sdl\SdlTag;
    $tag = SdlTag::createRoot()
        ->createChild("people")
            ->createChild("person")
                ->setValue("John Doe")
                ->setAttribute("sex","male")
                ->end()
            ->end();
    echo $tag->encode();

```

Values and attributes can be assigned from PHP values, or directly via any of the `LiteralType` descendants.

```
    use Sdl\SdlTag;
    use Sdl\LiteralType\SdlBinary;
    $tag = SdlTag::createRoot()
        ->createChild("image")
            ->setValue(new SdlBinary($file))
            ->setAttribute("type","image/jpeg")
            ->end();

```

Remember to match your calls to `end()` to make sure you return the root element when you are using the fluid method calls on a new root or non-variable:

```
    use Sdl\SdlTag;
    $tag = SdlTag::createRoot();
    $tag->createChild("foo")->createChild("bar");
    // $tag will still point to the root even though end() wasn't called.
    $bad = SdlTag::createRoot()->createChild("foo")->createChild("bar");
    // $bad will be pointing to "bar" here, not the root.

```

You should however be able to get back to the root using `getParent()` if you ever needed to:

```
    function root($tag) {
        while(($parent = $tag->getParent())
            $tag = $parent;
        return $tag;
    }

```

### Parsing a file

[](#parsing-a-file)

To parse a file, use the `Sdl\Parser\SdlParser` class. It offers a few different methods to parse content and return `Sdl\SdlTag` objects.

```
    use Sdl\Parser\SdlParser;
    // Parse a file
    $tag = SdlParser::parseFile("basic.sdl");
    // Parse a string
    $tag = SdlParser::parseString($sdl_string);

```

### Encoding tags to SDL

[](#encoding-tags-to-sdl)

Tags are encoded into SDL using the `encode()` method. If you need to write it out to a file, use `file_put_contents()` or any other appropriate method to write out the output from `encode()`.

```
    use Sdl\SdlTag;
    // Create a new root
    $tag = SdlTag::createRoot();
    // Add two children
    $tag->addChild("foo")->setValuesFromArray([0, 1, 2 ]);
    $tag->addChild("bar")->setValuesFromArray([2, 3, 4 ]);
    // Output the final SDL
    echo $tag->encode();

```

### Navigating children

[](#navigating-children)

You can use `getAllChildren()`, `getChildrenByTagName(..)` to navigate the tree.

The `SdlSelector` will provide a more convenient approach to querying the tree with logical expressions.

```
    use Sdl\Parser\SdlParser;
    $tag = SdlTag::createRoot();
    $tag->createChild("people")
        ->createChild("person")
            ->setValue("John Doe")
            ->setAttribute("sex","male");
    $people = $tag->getChildrenByTagName("people")[0]->getAllChildren();
    echo "Person name: ".$people[0]->getValue()."\n";

    // Enumerate children
    foreach($tag->getAllChildren() as $ctag) {
        printf("Tag: %s\n", $ctag->getTagName());
    }

```

### Queries

[](#queries)

Queries make use of Symfony's ExpressionLanguage component to allow complex queries:

```
    use Sdl\Parser\SdlParser;
    use Sdl\Selector\SdlSelector;

    // Load the data
    $tag = SdlParser::parseFile(__DIR__."/sdl/products.sdl");
    // Create a new selector for the tag
    $tag_sel = new SdlSelector($tag);

    // Execute the query
    $expr = "/productcatalog/product[tag.attr('itemno')=='101-NAIL']";
    $item = $tag_sel->query($expr);

```

Development
-----------

[](#development)

You can run the unit tests using **phpunit**:

```
  $ phpunit --bootstrap tests/bootstrap.php tests/src/

```

Just remember to create the autoloaders etc first using **composer**:

```
  $ composer dump-autoload

```

When contributing code, follow the conventions used elsewhere and send a pull request with your masterpiece. If you're too lazy to fix something yourself, or more likely busy saving the world elsewhere, create an issue so someone else can take care of it.

###  Health Score

31

—

LowBetter than 66% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity17

Limited adoption so far

Community5

Small or concentrated contributor base

Maturity68

Established project with proven stability

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~398 days

Recently: every ~383 days

Total

7

Last Release

2161d ago

Major Versions

1.0.0 → 2.0.02014-11-15

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1434055?v=4)[Christopher Vagnetoft](/maintainers/noccy80)[@noccy80](https://github.com/noccy80)

### Embed Badge

![Health badge](/badges/noccylabs-sdl/health.svg)

```
[![Health](https://phpackages.com/badges/noccylabs-sdl/health.svg)](https://phpackages.com/packages/noccylabs-sdl)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.8M712](/packages/sylius-sylius)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M196](/packages/sulu-sulu)[tempest/framework

The PHP framework that gets out of your way.

2.2k31.1k12](/packages/tempest-framework)[fisharebest/webtrees

webtrees online genealogy

77416.0k20](/packages/fisharebest-webtrees)[rcsofttech/audit-trail-bundle

Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.

1175.2k](/packages/rcsofttech-audit-trail-bundle)[verbb/formie

The most user-friendly forms plugin for Craft.

100387.6k58](/packages/verbb-formie)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
