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