Other languages from within PHP

Discussion in 'PHP' started by Dhingcha, Aug 16, 2008.

  1. #1
    I've wondered before (albeit briefly) about how easy it would be to write PHP applications with code from other languages in them. There's already a wrapper for Perl in PHP, but being the never satisfied type I decided I wanted more . So I knocked up this class:

    <?php
    
    class Execute
    {
        public $output, $input, $command, $extension, $args, $compile = FALSE, $compiler;
        public function __construct($lang)
        {
            /*
            The switch statement basically determines how to execute the files.
            $command is the path to the command for each language
            $extension is the file extension for picky languages like Python ;-)
            */
            switch(strtolower(trim($lang)))
            {
                case 'php':
                    $this->command = 'php';
                    $this->extension = 'php';
                    break;
                case 'perl':
                    $this->command = 'perl';
                    $this->extension = 'pl';
                    break;
                case 'python':
                    $this->command = 'python';
                    $extension = 'py';
                case 'ruby':
                    $this->command = 'ruby';
                    $this->extension = 'rb';
                    break;
                case 'c':
                    $this->compile = TRUE;
                    $this->compiler = 'gcc'; // Use gcc as default for compiling C
                    $this->extension = 'c';
                    $this->args = '-o /tmp/temp -Wall -g';
                    break;
                case 'c++':
                    $this->compile = TRUE;
                    $this->compiler = 'g++'; // Use g++ as default for compiling C++
                    $this->extension = 'cpp';
                    $this->args = '-o /tmp/temp -Wall -g';
                    break;
                default:
                    $this->command = 'php'; // Execute as PHP by default
                    $this->extension = 'php';
                    break;
            }
        }
        
        public function call($code)
        {
            $this->input = $code;
            $temp = '/tmp/' . rand() . '.' . $this->extension;
            $handle = fopen($temp, "x");
            fwrite($handle, $this->input);
            fclose($handle);
            
            if($this->compile === TRUE)
            {
                $this->output = $this->compile_and_run($temp);
            }
            else
            {
                $this->output = passthru($this->command . ' ' . $this->args . ' ' . $temp);
            }
            
            unlink($temp);
            return($this->output);
        }
        
        private function compile_and_run($file)
        {
            if($this->compile === TRUE && empty($this->compiler) !== TRUE)
            {
                $exec = $this->compiler . ' ' . $this->args . ' ' . $file;
                $do = passthru($exec);
                $return = passthru('/tmp/temp');
                unlink('/tmp/temp');
                return($return);
            }
            else
            {
                return(FALSE);
            }
            
        }
    }
    
    ?> 
    Code (markup):
    I know, it's messy, sparsely commented and probably really insecure. But it works! It can currently run Perl, Python and Ruby (if you have them installed, obviously) and it can compile and run C and C++ (predictably this is fairly slow, so it needs some form of caching).

    It's easy to add more interpreted languages, as long as you know the path to the executable. Just use this syntax and put another thing in the switch statement:

    case 'language':
    	$this->command = '/path/to/executable';
    	$this->extension = 'ext';
    	break;
    Code (markup):
    I've tested it on Linux, and it seems to work OK. Shouldn't take much to get it working on Windows (changing the paths should be all it takes).

    Here's a sample snippet to show how to use the class:

    $perl =
    '
    print "This is Perl!\n";
    ';
    
    $pl = New Execute('perl');
    echo($pl->call($perl));
    
    $python =
    '
    print "This is Python!\n"
    
    ';
    
    $py = New Execute('python');
    echo($py->call($python));
    
    $c_code =
    '
    #include <stdio.h>
    
    int main()
    {
    	printf("This is C!\n");
    	return 0;
    }
    ';
    
    $c = New Execute('c');
    echo($c->call($c_code));
    
    $cpp_code =
    '
    #include <iostream>
    
    int main()
    {
        std::cout << "This is C++!\n";
    }
    ';
    
    $cpp = New Execute('c++');
    echo($cpp->call($cpp_code));
    Code (markup):
    Sorry if that's been a bit long winded! Feedback please.
     
    Dhingcha, Aug 16, 2008 IP
  2. Jezz

    Jezz Active Member

    Messages:
    208
    Likes Received:
    9
    Best Answers:
    0
    Trophy Points:
    60
    #2
    This is pretty cool!

    So it's basically a web based compiler?
    Slightly scary, but still... very interesting :D
     
    Jezz, Aug 17, 2008 IP
  3. Kimochi

    Kimochi Peon

    Messages:
    31
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Nice concept. Have you got any working demos?
     
    Kimochi, Aug 17, 2008 IP
  4. blueribbon

    blueribbon Peon

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Be careful if you use web form input to decide which script to execute, this would make it pretty easy to execute any command by passing a filename like "hello.pl | rm *" (for example, depending on the permissions of the user could possibly be used to delete any directory or files). Just a heads up!
     
    blueribbon, Aug 17, 2008 IP
  5. blueribbon

    blueribbon Peon

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #5
    oops, just looked at your code again and realized compile_and_run is a private function so the security issue is not with the filename being used to inject commands but obviously, with the code passed if it were taken from a web form. Its easy to run system-level commands from most programming languages
     
    blueribbon, Aug 17, 2008 IP
  6. EricBruggema

    EricBruggema Well-Known Member

    Messages:
    1,740
    Likes Received:
    28
    Best Answers:
    13
    Trophy Points:
    175
    #6
    I don't get why you want something like this, i don't see any needs for it. Most times, the server can run these scripts (extensions)..
     
    EricBruggema, Aug 18, 2008 IP
  7. gustavorg

    gustavorg Active Member

    Messages:
    37
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    61
    #7
    Its not the same but http://www.codeide.com is a similar system to test and compite programs in a browser. It accept C, pl, basic and pascal. Unfortunately at this momment seems is down, should be they are uploading a new version. When I need to test a quick program in C I use it, as is very fast. Take a look.
     
    gustavorg, Aug 18, 2008 IP
  8. php-lover

    php-lover Active Member

    Messages:
    261
    Likes Received:
    21
    Best Answers:
    0
    Trophy Points:
    58
    #8
    From my point of view, this code is use like a shortcut to your compiler application. You don't need to open your php editor to compile your php code, but you can write your code and run in your browser.

    This code is only work if you install a compiler program in your computer.

    What I like, is the programming concept.
     
    php-lover, Aug 18, 2008 IP