noccylabs/sdl 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

noccylabs/sdl

Composer 安装命令:

composer require noccylabs/sdl

包简介

Simple Declarative Language (SDL)

README 文档

README

Build Status

php-sdl 2.0

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 LiteralTypes 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

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

Component Description Status
Sdl\SdlTag Creating tag trees WORKING
Sdl\SdlTag Encoding tags and children WORKING
Sdl\SdlTag Encoding tags with comments WORKING
Sdl\SdlTag Tree traversal WORKING
Sdl\SdlTag Tests implemented PARTIAL
Sdl\Parser\SdlParser Parsing tags and nested tags WORKING
Sdl\Parser\SdlParser Parsing tags with comments
Sdl\Parser\SdlParser Tests implemented PARTIAL
Sdl\LiteralType\TypeFactory LiteralType registering PARTIAL
Sdl\LiteralType\TypeFactory Tests implemented PARTIAL
Sdl\LiteralType\*Type All types implemented PARTIAL
Sdl\LiteralType\*Type Tests implemented PARTIAL
Sdl\Selector\SdlSelector Selecting with expressions PARTIAL
Sdl\Selector\SdlSelector Tests implemented

Functionality

Function Status
Creating tag trees WORKING
Encoding tag trees into SDL WORKING
Parsing SDL into tag trees PARTIAL
Navigating the tag tree WORKING
Selecting tags with expressions PARTIAL
Create LiteralTypes from native PHP variable types WORKING
Create LiteralTypes from SDL tokens PARTIAL
Access LiteralTypes as native PHP values PARTIAL
Encode LiteralTypes into SDL tokens PARTIAL

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
SDL SdlParser::parseString 8.83s 1132.50
XML DomDocument::loadXml 0.43s 23469.17
JSON json_decode 0.26s 38640.62
YAML yaml_parse_file 0.44s 22738.22

Some 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

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

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

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

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 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

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.

noccylabs/sdl 适用场景与选型建议

noccylabs/sdl 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 146 次下载、GitHub Stars 达 8, 最近一次更新时间为 2014 年 01 月 08 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 noccylabs/sdl 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 noccylabs/sdl 我们能提供哪些服务?
定制开发 / 二次开发

基于 noccylabs/sdl 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 146
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 8
  • 点击次数: 10
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 8
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: GPL-2.0
  • 更新时间: 2014-01-08