├── PHPNodeJS.php ├── PHPNodeJSExample.php └── README.md /PHPNodeJS.php: -------------------------------------------------------------------------------- 1 | 9 | * @access public 10 | * @license http://creativecommons.org/licenses/by-sa/3.0/ Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) 11 | * @copyright (c) 2013, Dean Gostiša 12 | * @version 1.0 13 | * @example PHPNodeJSExample.php Examples for using this class 14 | */ 15 | class PHPNodeJS { 16 | 17 | private $NodePath; 18 | private $PHPNodeJSWrapper; 19 | private $debug = false; 20 | private $timeZone; 21 | 22 | /** 23 | * Initialize PHPNodeJS 24 | * 25 | * @param boolean $debug Enable or disable debug messages 26 | */ 27 | public function __construct($debug = false, $timeZone = 'Europe/Ljubljana') { 28 | $this->debug = $debug; 29 | $this->timeZone = $timeZone; 30 | date_default_timezone_set($this->timeZone); 31 | if ($this->debug) { 32 | self::DebugMsg('Searching for path of executable Node.JS ("node")...'); 33 | } 34 | $this->NodePath = trim(shell_exec('which node')); 35 | if (!file_exists($this->NodePath)) { 36 | self::DebugMsg('Node.JS is not installed on server. Please fix that.'); 37 | die(); 38 | } 39 | if ($this->debug) { 40 | self::DebugMsg('Path of Node.JS: ' . $this->NodePath); 41 | self::DebugMsg('Current Execution Path: ' . dirname(__FILE__) . '/'); 42 | self::DebugMsg(); 43 | } 44 | } 45 | 46 | /** 47 | * Run JavaScript 48 | * 49 | * @param string $javascript_code JavaScript Code To Run 50 | * @param string $function_name JavaScript Function To Call [optional] 51 | * @param array $args JavaScript Function Arguments [optional] 52 | * @param boolean $jQuery Load jQuery library [defailt: false] 53 | * 54 | * @return string Result of executing JavaScript 55 | */ 56 | public function run($javascript_code, $function_name = '', $args = array(), $jQuery = false) { 57 | $tmpFile = tempnam(dirname(__FILE__), 'PHPNodeJSWrapper'); 58 | $this->PHPNodeJSWrapper = $tmpFile . '.js'; 59 | $this->SetJSWrapper($jQuery); 60 | for ($i = 0; $i < count($args); $i++) { 61 | $args[$i] = escapeshellarg($args[$i]); 62 | } 63 | if ($this->debug) { 64 | self::DebugMsg('Running Javascript with parameters:'); 65 | self::DebugMsg('Javascript Code: ' . $javascript_code); 66 | if ($function_name != '') { 67 | self::DebugMsg('Calling JavaScript Function with Parameters: ' . $function_name . '(' . implode(', ', $args) . ')'); 68 | } 69 | self::DebugMsg('Enabled special libs: jQuery(' . ($jQuery ? 'TRUE' : 'FALSE').')'); 70 | self::DebugMsg(); 71 | } 72 | $command = 'cd ' . dirname(__FILE__) . '/ && ' . $this->NodePath . ' ' . $this->PHPNodeJSWrapper . ' '; 73 | $command .= escapeshellarg($javascript_code); 74 | if ($function_name != '') { 75 | $command .= ' ' . escapeshellarg($function_name) . ' ' . escapeshellarg('[' . implode(', ', $args) . ']'); 76 | } 77 | if ($this->debug) { 78 | self::DebugMsg('Executing shell command:'); 79 | self::DebugMsg($command); 80 | } 81 | $result = shell_exec($command); 82 | if ($this->debug) { 83 | self::DebugMsg('Result:'); 84 | self::DebugMsg($result); 85 | self::DebugMsg(); 86 | } 87 | $this->CleanJSWrapper(); 88 | return $result; 89 | } 90 | 91 | /** 92 | * Create JS Wrapper for executing JavaScript Code 93 | * 94 | * @param boolean $jQuery Load jQuery library [defailt: false] 95 | */ 96 | private function SetJSWrapper($jQuery = false) { 97 | if ($this->debug) { 98 | self::DebugMsg('Setting JS Wrapper for executing custom JavaScript function...'); 99 | self::DebugMsg('JS Wrapper Path: ' . $this->PHPNodeJSWrapper); 100 | } 101 | ob_start(); 102 | ?> 103 | 148 | ' => '', '' => '')); 150 | file_put_contents($this->PHPNodeJSWrapper, $data); 151 | if ($this->debug) { 152 | self::DebugMsg('JS Wrapper prepared successfully.'); 153 | self::DebugMsg(); 154 | } 155 | } 156 | 157 | /** 158 | * Cleanup JS Wrapper 159 | */ 160 | private function CleanJSWrapper() { 161 | if ($this->debug) { 162 | self::DebugMsg('Cleanup JS Wrapper...'); 163 | } 164 | unlink($this->PHPNodeJSWrapper); 165 | unlink(mb_substr($this->PHPNodeJSWrapper, 0, -3, 'UTF-8')); 166 | $this->PHPNodeJSWrapper = null; 167 | if ($this->debug) { 168 | self::DebugMsg('Cleanup JS Wrapper is finished.'); 169 | self::DebugMsg(); 170 | } 171 | } 172 | 173 | /** 174 | * Output Debug Message based on user interface (CLI, Apache) 175 | * 176 | * @param string $msg Debug Message 177 | */ 178 | private static function DebugMsg($msg = '') { 179 | if ($msg == '') { 180 | echo PHP_SAPI == 'cli' ? '' : '
', "\n"; 181 | } else { 182 | echo date('Y-m-d H:i:s'), ' :: ', $msg, PHP_SAPI == 'cli' ? '' : '
', "\n"; 183 | } 184 | } 185 | 186 | } 187 | ?> 188 | -------------------------------------------------------------------------------- /PHPNodeJSExample.php: -------------------------------------------------------------------------------- 1 | run(' 10 | var var1 = 10; 11 | var var2 = 20; 12 | console.log(var1+var2);'); 13 | 14 | // example 2 (run simple script, supply multiple arguments to function you want to call) 15 | $PHPNodeJS->run(' 16 | function test(var1, var2) { 17 | if (var1 == "3" && var2 == "20") { 18 | return true; 19 | } else { 20 | return false; 21 | } 22 | }', 'test', array('3', '20')); 23 | 24 | // example 3 (run script that uses jQuery as dependcy) 25 | echo $PHPNodeJS->run('function test(url) { 26 | jQuery.get(url, function(data) { 27 | console.log(data); 28 | }); 29 | return ""; 30 | }', 'test', array('http://www.videodeck.net'), true); 31 | ?> 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PHPNodeJS 2 | ========= 3 | 4 | PHP Node JS wrapper - PHP class that brings JavaScript executing inside PHP - wrapper for NodeJS CLI. 5 | 6 | This class was made that we can use JavaScript based validators of tasks (interacitve tasks) for competition system Bober (programming competition). 7 | JavaScript server execution enables us to protect to correct solution for tasks. 8 | 9 | We think that this solution could be used for many other things so we published this wrapper online, so you can review it, test it and make it better. 10 | 11 | Requirements 12 | ------------ 13 | - [NodeJS]("http://nodejs.org/", "NodeJS") (>= v0.10.10, maybe it works with older version (never tested, you are welcome to test and report if it works or not), there must be binary file "node" on server / computer where you execute script) 14 | - If you want to use JavaScript function that uses jQuery you need to install jquery for NodeJS via NPM (in directory where 15 | PHPNodeJS.php is located in your project, you need to run command in CLI: `npm install jquery` 16 | 17 | Initialize 18 | ---------- 19 | ``` 20 | include_once dirname(__FILE__) . '/PHPNodeJS.php'; 21 | // if $debug = true all of debug messages will be shown, otherwise not 22 | $debug = true; 23 | $PHPNodeJS = new PHPNodeJS($debug); 24 | ``` 25 | 26 | Example 1 27 | -------- 28 | Run simple script without function 29 | ``` 30 | echo $PHPNodeJS->run(' 31 | var var1 = 10; 32 | var var2 = 20; 33 | console.log(var1+var2); 34 | '); 35 | ``` 36 | 37 | Example 2 38 | --------- 39 | Run simple script, supply multiple arguments to function you want to call 40 | ``` 41 | echo $PHPNodeJS->run(' 42 | function test(var1, var2) { 43 | if (var1 == "3" && var2 == "20") { 44 | return true; 45 | } else { 46 | return false; 47 | } 48 | }', 49 | 'test', array('3', '20')); 50 | ``` 51 | 52 | Example 3 53 | --------- 54 | Run script that uses jQuery as dependcy 55 | ``` 56 | echo $PHPNodeJS->run(' 57 | function test(url) { 58 | jQuery.get(url, function(data) { 59 | console.log(data); 60 | }); 61 | return ""; 62 | }', 63 | 'test', array('http://www.videodeck.net'), true); 64 | ``` 65 | License 66 | ------- 67 | This project is licensed under [Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)]("http://creativecommons.org/licenses/by-sa/3.0/", "CC BY-SA 3.0"). You are welcome to contribute to this project or 68 | fork this product but we would be very happy that you keep reference to this original project. 69 | --------------------------------------------------------------------------------