Я хочу поддержать @Suroot, а также эту замечательную статью: http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967
Однако весь процесс выглядит так в командной строке Linux:
... во-первых, вы должны быть в Linux, PHP для командной строки (CLI) должен быть включен, и PHP в командной строке не должен иметь никаких ошибок, когда вы выполняете "php -v" или передаете ему тестовый скрипт, который вы знаете, как правило, будет работать в командной строке.
... во-вторых, вам нужно установить GCC для компиляции программ на C.
... создайте рабочий каталог и перейдите в него.
... создайте файл script.php, содержащий этот тестовый код:
<?php
$s1 = @ $argv[1];
$s2 = @ $argv[2];
$s3 = @ $argv[3];
for($i=0;$i<=10;$i++){
echo "($s1) ($s2) ($s3)\n";
}
... обратите внимание, это только наш тест. Вы можете поместить туда свой собственный код PHP позже, как только вы докажете, что тест работает.
...обратите внимание, что имя "script.php" имеет решающее значение, иначе main.c не будет работать, когда попадет в строку _binary_script_php_start
. Сначала это через меня для цикла, потому что я не сделал мысленной связи с тем, что имя переменной вклеивается в этот процесс.
... создайте файл кода C main.c, содержащий этот код внутри:
#include <stdio.h>
#include <stdlib.h>
extern char _binary_script_php_start;
extern char _binary_script_php_end;
int main(int argc, char *argv[]) {
// EXTRACT OUR RESOURCE OBJECT INTO /tmp/test.php
char *p = &_binary_script_php_start;
FILE *fp = fopen("/tmp/test.php","wb");
while ( p != &_binary_script_php_end ) {
fputc(*p++,fp);
}
fclose(fp);
// NOW READ IN OUR STANDARD ARGUMENTS AND LAUNCH OUR COMMAND
int i = 1;
char *cmd = "php /tmp/test.php";
char *s = NULL;
asprintf(&s, "%s",cmd);
for(i = 1; i < argc; i++) {
asprintf(&s, "%s \"%s\"",s,argv[i]);
}
system(s);
free(s);
unlink("/tmp/test.php"); // comment me out for debugging if you want
}
... обратите внимание, я немного заржавел с C (не использовал его с 1980-х годов), и strcpy() не рекомендуется, потому что это небезопасно. Итак, я прочитал о StackOverflow, что мы должны используйте asprintf() в системах GNU Linux. Очевидно, что asprintf() обрабатывает проблемы с переполнением буфера и malloc? Я очень на это надеюсь — я не хочу ввести вас в заблуждение. Пожалуйста, изучите это!
...а теперь начинается волшебство!
... нам нужно встроить script.php в объектный файл "data.o" с помощью этой команды командной строки (таким образом, начиная с приглашения $):
$ objcopy -I binary -O elf32-i386 -B i386 script.php data.o
... теперь мы создаем нашу команду «runme», где мы связываем «data.o» и «main.c» вместе:
$ gcc main.c data.o -o runme
... это затем сделало для нас скомпилированную программу C под названием «runme». Затем мы можем выполнить его, чтобы протестировать:
$ ./runme "test1" "test2 test3" "test4"
... Вы должны увидеть вывод, подобный следующему:
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
(test1) (test2 test3) (test4)
... как вы можете видеть, двойные кавычки на самом деле важны - они говорят C и, следовательно, PHP, что параметры должны быть сгруппированы вместе. Вот почему test3 не появляется в последних скобках. Без двойных кавычек вы увидите совершенно другой результат.
На этом этапе вы видите, как мы можем создать программу на C со встроенным PHP-скриптом внутри, которая работает в Linux. (Mac, Windows — вам, вероятно, потребуется немного изменить этот код.) Программа C расширяет наш PHP-скрипт до /tmp, выполняет его и передает ему параметры, которые мы можем прочитать и использовать. С этого момента вы можете пересмотреть script.php, чтобы он делал то, что вам нужно, и вы можете посмотреть на использование уникального имени файла, чтобы вы не затирали чужой файл /tmp/test.php, на всякий случай.
person
Volomike
schedule
07.07.2011