File README.md
Last commit: Tue Jun 7 23:40:09 2022 +0200 Jan Dankert More documentation.
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.
DownloadREADME.md
History Tue, 7 Jun 2022 23:40:09 +0200 Jan Dankert More documentation. Tue, 7 Jun 2022 23:33:20 +0200 Jan Dankert Fetched from upstream: support for "throw". Tue, 7 Jun 2022 23:12:47 +0200 Jan Dankert Fetched from upstream and enhanced documentation. Mon, 6 Jun 2022 23:11:33 +0200 Jan Dankert More documentation. Mon, 6 Jun 2022 14:06:46 +0200 Jan Dankert First commit after fetching from upstream repo.