У меня есть php-скрипт, работающий в качестве сервера fastcgi, который выполняет запрошенные браузером php-файлы (почему бы не использовать php / php-cgi? Из-за проблемы с производительностью , мы тоже использовали APC, но все еще недостаточно хороши):
# cat myphpcgi
#!/usr/local/php5/bin/php
<?php
while (Accept() >= 0) { # simple wrapper of FCGI_Accept from FastCGI dev-kit
$file = GetRequestFile(); # get requested .php file name(like /var/www/htdocs/a.php)
if ($file == FALSE)
continue;
$contents = file_get_contents($file);
if ($contents == FALSE)
continue;
# remove heading <?php and trailing ?>
$contents = ltrim($contents);
$contents = rtrim($contents);
$start = strpos($contents, "<?php");
$start += 5;
$end = strrpos($contents, "?>");
$end -= 2;
$ct = substr($contents, $start, $end);
# execute the requested file
eval($ct);
}
?>
При использовании вышеуказанного скрипта cgi библиотеки функций / классов будут загружены только один раз (с помощью require_once).
Сценарий запускается с помощью:
# /usr/local/lighttpd/bin/spawn-fcgi -f /var/www/cgi-bin/myphpcgi -a 127.0.0.1 -p 8888
И lighttpd настроен так: ...
fastcgi.server = ( ".php" =>
("localhost" =>
( "host" => "127.0.0.1",
"port" => 8888,
)
)
)
...
Нокогда браузер запрашивает a.php, как показано ниже:
<?php
require_once "bigfunction.php"
echo "haha";
printf("hehe");
?>
Сценарий cgi выводит «hahahehe» на системную консоль, а не в браузер.
# hahahehe
Если я обертываю FCGI_printfфункция (из FastCGI devkit тоже) и использовать ее для распечатки строк, результат будет отправлен в браузер, это решение, но существующий код должен будет внести изменения.
Я также протестировал сApache и вывод просто идет в apache error_log.Возможно, dup2 () решит проблему, но я не нашел fd, который использует FastCGI devkit.
PS __autoload не сэкономит наше время, так как большинство включений - это функции и константы.
PS2 dup2 () не решит проблему: из вывода strace скрипта cgi:
write(1, "haha", 4haha) = 4
write(1, "hehe\n", 5hehe) = 5
write(3, "\1\6\0\1\0\0\0\0\1\3\0\1\0\10\0\0\0\0\0\0\0\0\0\0", 24) = 24
shutdown(3, 1 /* send */)
, где fd 3 - соединение с lighttpd, когда я добавил dup2 (3, 1),получил ошибку 500 в браузере, и журнал lighttpd показывает:
2011-05-24 13:09:54: (mod_fastcgi.c.2443) unexpected end-of-file (perhaps the fastcgi process died): pid: 0 socket: tcp:127.0.0.1:8888
2011-05-24 13:09:54: (mod_fastcgi.c.3237) response not received, request sent: 834 on socket: tcp:127.0.0.1:8888 for /large.php , closing connection
PS3: код для Accept ():
PHP_FUNCTION(Accept)
{
int n = FCGI_Accept();
RETVAL_LONG(n);
return;
}
код для GetRequestFile ():
PHP_FUNCTION(GetRequestFile)
{
char buf[1024];
char *p = NULL;
int ret;
// apache and lighttpd has different name
p = getenv("PATH_TRANSLATED");
if (p == NULL) {
p = getenv("SCRIPT_FILENAME");
if (p == NULL) {
RETVAL_BOOL(0);
return;
}
}
memcpy(buf, p, strlen(p));
buf[strlen(p)] = '\0';
RETVAL_STRINGL(buf, strlen(buf), 1);
//dup2(3, 1);
return;
}
PS4 Когда добавляется оболочка для FCGI_printf, как показано ниже:
PHP_FUNCTION(Myprintf)
{
char *str;
int str_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
return;
}
char *p = emalloc(str_len + 1);
memcpy(p, str, str_len);
p[str_len] = '\0';
FCGI_printf("%s", p);
efree(p);
return;
}
Использование Myprintf () для печати строк, когда myphpcgi работает вместе с apache, работает нормально, и строка отображается в браузере.Но при использовании lighttpd строка никуда не денется, интересно ...