views:

260

answers:

3

I saw some existing code in the PHP scripts doing a

system('hostname');

how big can the performance impact on the server be if using this method?

+11  A: 

Running external processes can be a real performance hit when you have thousands of clients trying to connect to your web server. That's why people ended up ditching CGI (common gateway interface, the act of web servers calling external processes to dynamically create content) and incorporating code directly into their web servers, such as mod_perl.

You won't notice it when you're testing your little web application at home but, when the hordes that make up the Internet swarm down to your site, it will collapse under the load.

You'd be far better trying to figure out a way to cache this information within PHP itself (how often does it change, really?). For your particular example, you could use the "php_uname('n')" call to retrieve the full name (e.g., "localhost.example.com" and (optionally) strip off the domain part, but I've assumed you want the question answered in a more general sense.


Update:

Since someone has requested benchmarks, here's a C program that does three loops of 1,000 iterations each. The first does nothing within the loop, the second gets an environment variable (one other possibility for having PHP get its hostname), the third runs a system() command to execute hostname:

#include <stdio.h>
#include <time.h>
#define LOOP1 1000
int main (int c, char *v[]) {
    time_t t1, t2, t3, t4;
    int i;

    t1 = time(NULL);
    for (i = 0; i < LOOP1; i++) {
    }

    t2 = time(NULL);
    for (i = 0; i < LOOP1; i++) {
        getenv ("xxhostname");
    }

    t3 = time(NULL);
    for (i = 0; i < LOOP1; i++) {
        system ("hostname >/dev/null");
    }

    t4 = time(NULL);

    printf ("Loop 1 took %d seconds\n", t2-t1);
    printf ("Loop 2 took %d seconds\n", t3-t2);
    printf ("Loop 3 took %d seconds\n", t4-t3);
    return 0;
}

The results are:

Cygwin (gcc):
    Loop 1 took 0 seconds
    Loop 2 took 0 seconds
    Loop 3 took 103 seconds
Linux on System z (gcc):
    Loop 1 took 0 seconds
    Loop 2 took 0 seconds
    Loop 3 took 5 seconds
Linux on Intel (gcc):
    Loop 1 took 0 seconds
    Loop 2 took 0 seconds
    Loop 3 took 5 seconds
Linux on Power (gcc):
    Loop 1 took 0 seconds
    Loop 2 took 0 seconds
    Loop 3 took 4 seconds
Windows on Intel (VS2008, and using "ver >nul:", not "hostname"):
    Loop 1 took 0 seconds
    Loop 2 took 0 seconds
    Loop 3 took 45 seconds

However you slice'n'dice it, that's quite a discrepancy on loop number 3. It probably won't cause any problems if you're getting one hit a week on your site but, if you hold any hope of surviving in the real world under load, you'd be best to avoid system() calls as much as possible.

paxdiablo
Got any benchmarks to back up the claims?
Gerry
++ kudos - point well made
Gerry
+3  A: 

Errm, you are aware of php_uname and posix_uname, right?

<?php
    echo "php_uname: " . php_uname('n') . "\n";

    $ar = posix_uname();
    echo "posix_uname: $ar[nodename]\n";
?>

should both work. In PHP 5.3, there is also a gethostname.

derobert
+1 $_SERVER["HTTP_HOST"] doesn't always equal system('hostname')... but php_uname() and posix_uname() do.
動靜能量
+1  A: 

I used to have a site that was using exec, system and passthru in PHP to execute grep, sed and other tools on text files.

This made it so that each page view would result in not just one process, but two at once. I ran into problems with the process limit on my shared hosting - more than 6 processes at once, and people got 503 errors.

This wasn't a problem until the site became popular. I had to rewrite the page to use PHP functions instead of calling external programs, and it was faster, and fixed the 503 errors. This might not be a problem if you have a less busy site, or a dedicated/virtual server.

Alex JL