2

I get a PHP string from the frontend and I just want to execute it and get the stdout and stderr.

This is what I tried:

const runner = require('child_process');
runner.exec('php ' + phpString, (err, stdout, stderr) => {
  // ...
});

but this requires the PHP code to be in a file because it needs the path as an argument which leads to a PHP file. But writing the phpString to a file and then executing it seems unnecessary so is there a way I can directly execute the string?

5
  • 1
    why do you want do this or allow this? Allowing the client to send arbitrary code which you then execute without validation seems like a good way to invite security problems. Commented May 12, 2020 at 9:58
  • @ADyson I'm just creating an app where users can execute programs in different languages. Kind of a personal project. Commented May 12, 2020 at 10:00
  • ok but still if you let other people use it, then it puts your server at risk. Commented May 12, 2020 at 11:06
  • @ADyson - Okay, If I want to validate the string so that it doesn't contain anything risky I'm guessing that would be hard. Commented May 12, 2020 at 11:10
  • 1
    Yes, it would be. Which is why the whole scheme is a very bad idea, unless the only person who's ever going to use it is you (and you add some security to make sure of that), or you create a heavily sandboxed environment where only certain commands can be executed which cannot possibly cause damage to the server - something like in the sandbox sites you see online (such as this one) where a lot of commands are disabled. Commented May 12, 2020 at 11:14

2 Answers 2

2

You can use -r flag of PHP cli for that.

const runner = require('child_process');
const phpString = `'echo "hi";'`
runner.exec('php -r ' + phpString, (err, stdout, stderr) => {
     console.log(stdout) // hi
});

Although I would use execFile/spawn instead, to avoid scaping the arguments

const runner = require('child_process');
const phpString = `echo "hi";` // without <?php
runner.execFile('php', ['-r', phpString], (err, stdout, stderr) => {
   console.log(stdout) // hi
});

If you want to use <?php tags, you should use spawn and write to stdin. This is the best approach in my opinion.

const php = runner.spawn('php');
const phpString = `<?php echo "hi";?>` // you can use <?php

// You can remove this if you want output as Buffer
php.stdout.setEncoding('utf8') 
php.stdout.on('data', console.log)
php.stderr.on('data', console.error)

php.stdin.write(phpString)
php.stdin.end()

Have in mind that allowing users to execute code on your server is not recommended.

Sign up to request clarification or add additional context in comments.

7 Comments

Yes, the php -r flag only works without <?php tags. But it isn't hard to remove them.
Okay I'll first remove them using javascript and then pass it.
Check updated answer, you can use <?php tags using .spawn
Hi, Marcos, the updated answer works fine but If there are any syntax errors in the program I see that they are being logged because of php.stdout.on('data', console.log) so if I want to separate the stdout and stderr using the last approach what can I do?
yeah, I didn't show error handling, I left that to you, but I'll update my answer
|
2

Marcos already gave a valid and correct answer, I would just like to add that you can also pipe the php-code to the php-executable:

const { exec } = require('child_process');

const phpString = '<?php echo 1; ?>';

exec(`echo "${phpString}" | php`, (error, stdout, stderr) => {
  console.log(stdout); // prints "1"
});

3 Comments

Actually this is only working if I try this on a string like this echo 1; but if I use a string that has <?php echo 1; ?> it's giving me an error. This is the error PHP Parse error: syntax error, unexpected '<', expecting end of file in Command line code on line 1.
You need to make sure that the php opening/closing tags are only set once. Your error message seems like they are set twice.
No, I verified it as Marcos said below I think we can't use those tags in this way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.