Re: Apache handler with Multiple PHP versions
| From: | Tijnema | Date: | Sat, 14 Jul 2007 15:13:03 +0000 |
| Subject: | Re: Apache handler with Multiple PHP versions | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-30929@lists.php.net to get a copy of this message | ||
On 7/14/07, Stanislav Malyshev <stas@zend.com> wrote:
The Apache2handler SAPI should be loaded first, and read the very first line of the PHP script to determine if a version is specified there. If not, the handler needs to load its default PHP version. If it is specified, it should try to load that version, and if it couldn't find or load that version, fall back to the default version and issue a warning. This means the engines would have to init/shutdown on each request, which makes it as bad as CGI. Is that really a big problem?And isn't that what Apache currently does? As I said before, I don't know a lot about PHP core/ Apache2handler SAPI, But I expected Apache to load PHP on each request. And what if I just load and init all PHP versions at once with different handles? (See example code at the bottom of this message)
Why not just go FastCGI? You can use extensions like .php4 and .php5. -- Stanislav Malyshev, Zend Software ArchitectIt's not just for my personal server, I just load different PHP versions by updating a symlink (libphp.so -->libphp4.so, libphp5.so or libphp5-2-1.so), and restarting Apache. I talked to my webmaster of my Shared host, and he said: "I don't see a reason to use FastCGI with different extensions, this will probably lead to problems with unexperienced users on this server. If your idea shows no security issues, performance issues or difficult configuration settings, we will use it to support more versions of PHP." So, that confirms what I was thinking, but other webmasters might think different about it. Tijnema The code for loading and starting up different PHP versions at once: --------------------php4.c-------------------- int *parse_php_code(char *file) { return 4; } int php_startup() { return 1; } --------------------/php4.c-------------------- --------------------php5.c-------------------- int *parse_php_code(char *file) { return 5; } int php_startup() { return 1; } --------------------/php5.c-------------------- --------------------php6.c-------------------- int *parse_php_code(char *file) { return 6; } int php_startup() { return 1; } --------------------/php6.c-------------------- --------------------loader.c-------------------- #include <stdio.h> #include <dlfcn.h> int main(int argc, char *argv[]) { void *handle4, *handle5, *handle6; char *error; int *(*parse_code4)(char *); int *(*startup4); int *(*parse_code5)(char *); int *(*startup5); int *(*parse_code6)(char *); int *(*startup6); FILE * fp; char *ver; char *buffer; if(argc != 2) { fprintf(stderr, "Syntax: %s <php file>\n", argv[0]); exit(1); } handle4 = dlopen("./libphp4.so", RTLD_LAZY); handle5 = dlopen("./libphp5.so", RTLD_LAZY); handle6 = dlopen("./libphp6.so", RTLD_LAZY); if(!handle4) { fprintf(stderr, "%s\n", dlerror()); exit(1); } if(!handle5) { fprintf(stderr, "%s\n", dlerror()); exit(1); } if(!handle6) { fprintf(stderr, "%s\n", dlerror()); exit(1); } startup4 = dlsym(handle4, "php_startup"); if((error = dlerror()) != NULL) { fprintf (stderr, "PHP%d: %s\n", 4, error); exit(1); } startup5 = dlsym(handle5, "php_startup"); if((error = dlerror()) != NULL) { fprintf (stderr, "PHP%d: %s\n", 5, error); exit(1); } startup6 = dlsym(handle6, "php_startup"); if((error = dlerror()) != NULL) { fprintf (stderr, "PHP%d: %s\n", 6, error); exit(1); } if(!(*startup4)) { fprintf(stderr, "Failed to startup PHP %d\n", 4); exit(1); } if(!(*startup5)) { fprintf(stderr, "Failed to startup PHP %d\n", 5); exit(1); } if(!(*startup6)) { fprintf(stderr, "Failed to startup PHP %d\n", 6); exit(1); } parse_code4 = dlsym(handle4, "parse_php_code"); if((error = dlerror()) != NULL) { fprintf (stderr, "PHP%d: %s\n", 4, error); exit(1); } parse_code5 = dlsym(handle5, "parse_php_code"); if((error = dlerror()) != NULL) { fprintf (stderr, "PHP%d: %s\n", 5, error); exit(1); } parse_code6 = dlsym(handle6, "parse_php_code"); if((error = dlerror()) != NULL) { fprintf (stderr, "PHP%d: %s\n", 6, error); exit(1); } fp = fopen(argv[1], "r"); if(fp == NULL) { fprintf (stderr, "Error opening php file %s\n", argv[1]); exit(1); } buffer = (char *) malloc(13); ver = (char *) malloc(2); fread(buffer,1,12,fp); if(strcmp(buffer,"<?php //PHP ") == 0) { fread(ver,1,1,fp); } else { ver = "6"; } if(strcmp(ver,"4") == 0) { printf("%d\n",(*parse_code4)(argv[0])); } else if(strcmp(ver,"5") == 0) { printf("%d\n",(*parse_code5)(argv[0])); } else if(strcmp(ver,"6") == 0) { printf("%d\n",(*parse_code6)(argv[0])); } else { printf("%d\n",(*parse_code5)(argv[0])); } dlclose(handle4); dlclose(handle5); dlclose(handle6); return 0; } --------------------/loader.c-------------------- Test files used: --------------------test4.php-------------------- <?php //PHP 4 ?> --------------------/test4.php-------------------- --------------------test5.php-------------------- <?php //PHP 5 ?> --------------------/test5.php-------------------- --------------------test6.php-------------------- <?php //PHP 6 ?> --------------------/test6.php-------------------- Compiled with: gcc -shared -fPIC php4.c -o libphp4.so gcc -shared -fPIC php5.c -o libphp5.so gcc -shared -fPIC php6.c -o libphp6.so gcc -rdynamic -o loader loader.c -ldl Test results: ./loader ./test4.php (Outputs 4) ./loader ./test5.php (Outputs 5) ./loader ./test6.php (Outputs 6)