How to Use C++ Binaries from PHP

Is it possible to use C++ binaries from php

PHP is modular in design -- it consists of the "engine" and many extensions, some of which are essential (e.g. the "standard" extension) and some are optional. They can be compiled-in or loaded dynamically (via php.ini settings or the dl() function).

You can easily write your own PHP extension in C/C++, if you are willing to learn the API. Start with the documentation on how to "hack the Zend Engine".

Compile C++ to binary using PHP

Since you're in effect allowing the user to enter arbitrary code onto your server, this seems like a serious security risk. Why is customization of the executable needed? Could it be a configuration file?

If you want to go ahead with this, it can be done pretty easily. Perhaps use a templating engine like Mustache (not the C++ language feature templates). Write your source files to include this mustache templates.

When the user has posted the info, you just need to run the command to apply the template to get the finished source, then run your makefile to generate the finished executable. Then you can give it like anything else.

If you want to make sure the users can't get the same binary, an easy way would be to delete the finished executable after each run. There's better ways of doing this, but this is easy.

Reading Binary Files in PHP

I'm not really sure what you are trying to achieve here. If you have a binary file generated from the above c code then you could read and upack its content like this:

// get size of the binary file
$filesize = filesize('filename.bin');
// open file for reading in binary mode
$fp = fopen('filename.bin', 'rb');
// read the entire file into a binary string
$binary = fread($fp, $filesize);
// finally close the file
fclose($fp);

// unpack the data - notice that we create a format code using 'C%d'
// that will unpack the size of the file in unsigned chars
$unpacked = unpack(sprintf('C%d', $filesize), $binary);

// reset array keys
$unpacked = array_values($unpacked);

// this variable holds the size of *one* structure in the file
$block_size = 3;
// figure out the number of blocks in the file
$block_count = $file_size/$block_size;

// you now should have an array where each element represents a
// unsigned char from the binary file, so to display Day, Month and Year
for ($i = 0, $j = 0; $i < $block_count; $i++, $j+=$block_size) {
print 'Day: ' . $unpacked[$j] . '<br />';
print 'Month: ' . $unpacked[$j+1] . '<br />';
print 'Year: ' . $unpacked[$j+2] . '<br /><br />';
}

Of course you could also create an object to hold the data:

class DATE_OF_BIRTH {
public $Day;
public $Month;
public $Year;

public function __construct($Day, $Month, $Year) {
$this->Day = $Day;
$this->Month = $Month;
$this->Year = $Year;
}
}

$Birth = [];

for ($i = 0, $j = 0; $i < $block_count; $i++, $j+=$block_size) {
$Birth[] = new DATE_OF_BIRTH(
$unpacked[$j],
$unpacked[$j+1],
$unpacked[$j+2]
);
}

Another approach would be to slice it at each third element:

$Birth = [];    

for ($i = 0; $i < $block_count; $i++) {
// slice one read structure from the array
$slice = array_slice($unpacked, $i * $block_size, $block_size);

// combine the extracted array containing Day, Month and Year
// with the appropriate keys
$slice = array_combine(array('Day', 'Month', 'Year'), $slice);

$Birth[] = $slice;
}

You should also be aware that this could become much more complicated depending on what data your structure contains, consider this small c program:

#include <stdio.h>
#include <stdlib.h>

// pack structure members with a 1 byte aligment
struct __attribute__((__packed__)) person_t {
char name[5];
unsigned int age;
};

struct person_t persons[2] = {
{
{
'l', 'i', 's', 'a', 0
},
16
},
{
{
'c', 'o', 'r', 'n', 0
},
52
}
};

int main(int argc, char** argv) {
FILE* fp = fopen("binary.bin", "wb");
fwrite(persons, sizeof(persons), 1, fp);
fclose(fp);
return 0;
}

The above will write each packed structure into the file binary.bin, the size will be exactly 18 bytes. To get a better grasp on alignment/packing you can check out this so post: Structure padding and packing

Then in you php code you could read each block in a loop like so:

$filesize = filesize("binary.bin");
$fp = fopen("binary.bin", "rb");
$binary = fread($fp, $filesize);
fclose($fp);

// this variable holds the size of *one* structure
$block_size = 9;
$num_blocks = $filesize/$block_size;

// extract each block in a loop from the binary string
for ($i = 0, $offset = 0; $i < $num_blocks; $i++, $offset += $block_size) {
$unpacked_block = unpack("C5char/Iint", substr($binary, $offset));
$unpacked_block = array_values($unpacked_block);

// walk over the 'name' part and get the ascii value
array_walk($unpacked_block, function(&$item, $key) {
if($key < 5) {
$item = chr($item);
}
});
$name = implode('', array_slice($unpacked_block, 0, 5));
$age = implode('', array_slice($unpacked_block, 5, 1));
print 'name: ' . $name . '<br />';
print 'age: ' . $age . '<br />';
}

Can I use a dll written in C with PHP?

yes, you can use it as a php extension (which are written in C), but you might need some modifications .. etc

http://devzone.zend.com/node/view/id/1021

I think this question is related to yours.

How do I run a C++ binary on OpenShift via PHP?

Change the permission of the file so all can execute.

chmod a+rwx file

I prefer to use this instead of using 0777. That depends on your preference though.

Convert PHP file to binary

Since PHP is a (relatively)portable language, compiling PHP source to bytecode instead of binary code is more preferable. For this purpose there is an experimental project called bcompiler.

How do I invoke my C++ binaries via the CGI interface?

Three basic options:

  • do the whole thing in C++, making your program a standalone web server (possibly proxying through apache to provide things like ssl, static media, authentication etc.)
  • run C++ in a cgi-bin, through apache
  • make a PHP wrapper that shells out to the C++ part (this is a nice option if the performance-critical part is small, as you can still use the comfort that PHP's garbage collection and string manipulation gives you)


Related Topics



Leave a reply



Submit