Я хочу дать реквизит @Suroot, а также эту замечательную статью: http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967
Однако весь процесс такой же, как в командной строке Linux:
... first,Вы должны быть в Linux, PHP для командной строки (CLI) должен быть включен, и PHP в командной строке не должен иметь никаких ошибок, когда вы выполняете "php -v" или передаете ему тестовый скрипт, который, как вы знаете, обычно будет работатькомандная строка.
... во-вторых, вам нужно установить GCC для компиляции программ на Си.
... создать рабочий каталог и вставить в него 'cd'.
... создайте файл 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.