scriptbox

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

README.md (5022B)


      1 # Script Sandbox for PHP
      2 
      3 ## Overview
      4 
      5 This is a script interpreter for PHP. Custom code is parsed and interpreted in a sandbox.
      6 
      7 The code syntax is similar to [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript). More precisely, it is a subset of Javascript.
      8 
      9 ## History 
     10 
     11 It was written for the [OpenRat CMS](http://www.openrat.de) and is maintained there.
     12 
     13 
     14 ## Details
     15 
     16 Scriptbox is an in-memory script interpreter written in PHP. The scripts are interpreted directly in the syntax tree and are **not** transpiled to PHP code.
     17 
     18 A script is running in its sandbox, but it may call functions in your PHP code if you provide appropriate classes (see below).
     19 
     20 It consists of a lexer, a syntax parser and an interpreter.
     21 
     22 The scripts may be used as a [domain specific language (DSL)](https://en.wikipedia.org/wiki/Domain-specific_language) in your PHP application.
     23 
     24 
     25 ## Usage
     26 
     27 There is the `dsl\executor\DslInterpreter` class to run your code:
     28 
     29     $interpreter = new DslInterpreter();
     30     $interpreter->runCode( $code );
     31 
     32 ### get output
     33 
     34 For getting the standard output, simply call `getOutput()`:
     35 
     36     $interpreter = new DslInterpreter();
     37     $interpreter->runCode( $code );
     38     $output = $interpreter->getOutput() ); // get the output
     39 
     40 ### add context
     41 
     42 you may add custom objects to the calling context
     43 
     44     $interpreter = new DslInterpreter();
     45     $interpreter->addContext( [ 'mycontext'=> new MyContextObject() ]  );
     46     $interpreter->runCode( $code );
     47 
     48 Your class `MyContextObject` must implement `dsl\context\DslObject`,then your code may contain
     49 
     50     mycontext.method();
     51 
     52 ### get return value
     53 
     54     $interpreter = new DslInterpreter();
     55     $returnValue = $interpreter->runCode( $code );
     56 
     57 ## Syntax
     58 
     59 The language syntax is a subset of javascript.
     60 
     61 ## Features
     62 
     63 ### comments
     64 
     65 single line comments like
     66 
     67     // this is a comment
     68 
     69 and multiline commens like
     70 
     71     /**
     72      * this is a comment
     73      */
     74 
     75 are supported
     76 
     77 
     78 ### text
     79 
     80     write( "this is a 'string'" );  // writes to standard out
     81     write( 'this is a "string"' );  // writes to standard out 
     82     
     83 
     84 ### variables
     85 
     86 variables and string concatenation:
     87 
     88     age = 18;
     89     write("my age is " + age );
     90 
     91 variables *may* be initialized with `let`,`var` or `const` but this is optional:
     92 
     93     let age = 18; // "let" is optional and completely ignored
     94     write("my age is " + age );
     95 
     96 every variable is "block scoped".
     97 
     98 
     99 ### function scope
    100 
    101 variables are valid for the current block.
    102 
    103     age = 18;
    104 
    105     function add() {
    106         age = age + 1;
    107         write( "next year, you are " + age ); // 19
    108     }
    109     add();
    110 
    111     write( "but this year you are " + age ); // 18
    112 
    113 
    114 ### function calls
    115 
    116 Example
    117 
    118     write( "powered by " + name() );
    119 
    120     function name() {
    121         return "script sandbox";
    122     {
    123 
    124 
    125 ### if / else
    126 
    127     age = 17;
    128     if   ( age < 18 )
    129         write( "you are under 18" );
    130     else {
    131         write( "you are already 18" );
    132         write( "you are allowed to enter" );
    133     }
    134 
    135 ### full arithmetic calculations
    136    
    137     write( 1 + 2 * 3 ); // this resolves to 7 because of the operator priority
    138 
    139 ### arrays and for loops
    140 
    141     animals = Array.of('lion', 'ape', 'fish');
    142 
    143     for( animal of animals )
    144         write( animal + " is an animal." );
    145 
    146 
    147 ### object properties
    148 
    149     write( "PI is " + Math.PI );
    150 
    151 ### throw
    152 
    153     throw "this is an error";
    154 
    155 The message is thrown as a DslRuntimeException and is able to be catched from the calling PHP code.
    156 
    157 Hint: try/catch blocks in scripts are not supported.
    158 
    159 ## Template script
    160 
    161 Remember Smarty and Twig? Yes, but both have their strange syntax. Check out this template parser with a JSP-like syntax:
    162 
    163     <html>
    164     <body>
    165     <% age = 12; %>
    166     Next year your age is <%= (age+1) %></br>
    167 
    168 
    169 ### Usage
    170 
    171     // Parse the template, this will create a plain script
    172     $templateParser = new DslTemplate();
    173     $templateParser->parseTemplate($src);
    174 
    175     // That's all. Lets start the interpreter
    176     $executor = new DslInterpreter();
    177     $executor->runCode($templateParser->script);
    178     echo( $executor->getOutput() ); // get the output
    179 
    180 
    181 ## Unsupported
    182 
    183 - There is NO support for creating classes or objects.
    184 - Due to the request-based operation of the PHP interpreter there is no possibility for asynchronous methods like `async` or `await`.
    185 - No try/catch
    186 - No `window`, `document` or `navigator` objects
    187 
    188 ## FAQ
    189 
    190 _Does it generate PHP code?_
    191 
    192 No. The Interpreter works in memory. There is no way to create PHP code, even if it would be possible to implement.
    193 
    194 _Is it slow?_
    195 
    196 Yes, maybe, because there is no cache and no compilation to native PHP code. But this scriptbox targets content management systems which have their own caching.
    197 
    198 _Is it safe?_
    199 
    200 Yes, because the code is sandboxed. No PHP functions are available for the script. The default objects (Math, Number, Array) are safe. But please be careful if you are exposing your internal PHP functions oder objects into the context.
    201 
    202 _Why did you do this?_
    203 
    204 Because it was possible ;) And I needed a sandboxed DSL (domain specific language) for my CMS.