1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Updating an old script to detect 404 errors

Discussion in 'PHP' started by outrefranc, Aug 5, 2020.

  1. #1
    I used to run this script in my 404 page.
    It was sending me an email with each 404 error. Sadly, it's not working any more, it's very old code. Can anyone help me to update it? Thanks in advance.
    <?php
        $to = "email@domain.com";
    # Gather visitor information
        $ip = getenv ("REMOTE_ADDR");                // IP Address
        $server_name = getenv ("SERVER_NAME");       // Server Name
        $request_uri = getenv ("REQUEST_URI");       // Requested URI
        $http_ref = getenv ("HTTP_REFERER");         // HTTP Referer
        $http_agent = getenv ("HTTP_USER_AGENT");    // User Agent
        $error_date = date("D M j Y g:i:s a T");     // Error Date
    
    $msg = "There was a ".$error_code." error on the ".$server_name." domain<br>".
        "\n\nDetails\n----------------------------------------------------------------------<br>".
        "\n<br>When: ".$error_date.
        "\n<br>(Who) IP Address: ".$ip.
        "\n<br>(What) Tried to Access: http://".$server_name.$request_uri.
        "\n<br>(From where) HTTP Referer: ".$http_ref.
        "\n\n<br>User Agent: ".$http_agent;   
    $headers = "MIME-Version: 1.0" . "\r\n";
    $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
    $headers .= 'From: <email@domain.com>' . "\r\n";
    // send email
    mail($to,"404 error report",$msg,$headers);
    
    ?>
    Code (markup):

     
    outrefranc, Aug 5, 2020 IP
  2. SpacePhoenix

    SpacePhoenix Well-Known Member

    Messages:
    196
    Likes Received:
    28
    Best Answers:
    2
    Trophy Points:
    155
    #2
    Have you tried having a test script attempt to send you an email to test if there's any problem with sending emails?
     
    SpacePhoenix, Aug 5, 2020 IP
  3. outrefranc

    outrefranc Active Member

    Messages:
    94
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    93
    #3
    Yes, it's sending emails, no problem with that.
    The problem is that it's no longer telling which page leads the user to the 404 error page.
     
    outrefranc, Aug 5, 2020 IP
  4. Efetobor Agbontaen

    Efetobor Agbontaen Active Member

    Messages:
    136
    Likes Received:
    41
    Best Answers:
    5
    Trophy Points:
    85
    #4
    What version of PHP are you using?
     
    Efetobor Agbontaen, Aug 5, 2020 IP
  5. outrefranc

    outrefranc Active Member

    Messages:
    94
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    93
    #5
    7.21
    I believe this script was good up to 5.4.
    I shall upgrade to 7.4 someday.
     
    outrefranc, Aug 5, 2020 IP
  6. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #6
    A number of those values are not reported in the environment if you're using PHP-FPM instead of fastCGI. Try replacing most of those getenv() with $_SERVER[].

    I'd probably also kill off all those "variables for nothing" just for efficiency sake, and since you're building a HTML e-mail build it as a HTML e-mail, making sure to htmlspecialchars any values that could be generated client-side.

    Also it seems to call a variable -- $error_code -- that is not actually defined anywhere.

    Hence:

    <?php
    
    $to = 'email@domain.com';
    		
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-type:text/html;charset=UTF-8\r\n";
    $headers .= 'From: <email@domain.com>\r\n";
    
    $message = '
    <p>
    	There was a 404 error on the ' .
    		$_SERVER['SERVER_NAME'] . ' domain
    </p>
    Details
    <hr>
    When: ' .
    	date('D M j Y g:i:s a T') . '<br>
    (Who) IP Address: ' .
    	$_SERVER['REMOTE_ADDR'] . '<br>
    (What) Tried to Access: ' . 
    	$_SERVER['REQUEST_SCHEME'] . '://' .
    	$_SERVER['SERVER_NAME'] . '/' . 
    	htmlspecialchars($_SERVER['REQUEST_URI']) . '<br>
    (From where) HTTP Referer: ' .
    	htmlspecialchars($_SERVER['HTTP_REFERER']) . '<br>
    User Agent: ' .
    	htmlspecialchars($_SERVER['HTTP_USER_AGENT']);
    	
    // end message
    		
    // send email
    mail($to, '404 error report' , $message, $headers);
    Code (markup):
    Is how I'd probably go about that. Untested, might have typo's, but should give you the general gist of it.

    Dimes to dollars though the real problem is that getenv isn't being fed those values anymore. That happens when you switch between PHP interfaces which is part and parcel of switching between servers. Hence $_SERVER is more reliable than getEnv for these values.

    If that's not it, no clue. Could be the host OS is blocking or not reporting those outright, which I know some "cheaper" shared hosts have started doing; just part of why I abandoned that type of hosting 15 years ago.
     
    deathshadow, Aug 5, 2020 IP
    Efetobor Agbontaen and malky66 like this.
  7. outrefranc

    outrefranc Active Member

    Messages:
    94
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    93
    #7
    Thanks, but it's not working either.
    Actually, my script is still working. This is the email I'm getting:

    
    There was a error on the ... domain
    Details ----------------------------------------------------------------------
    
    When: Thu Aug 6 2020 3:07:29 pm CEST
    (Who) IP Address: 66.249.64.16
    (What) Tried to Access: ...404.php
    (From where) HTTP Referer:
    User Agent: Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.92 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
    
    Code (markup):
    They're all like this.
    I've received 13 emails today.
    The problem is that it isn't giving the URL of the missing page so it's useless...
    It's "request_uri" which isn't working. I can't understand why.
     
    outrefranc, Aug 6, 2020 IP
  8. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #8
    It's probably simply not being passed from the OS or server. What server is it running? Apache? NgNix? Something else?

    A lot of fancier "optimized" server software doesn't provide that information as part of their "let's make it faster" approach, that often just makes it slower. Similarly I remember that if you try running Microsoft IIS as your hosting, a LOT of values just don't get passed to PHP. (one of the many reasons I'd never use Windows as a server OS, it's as horrible and crippled at it as Linux is for desktops.)

    Sometimes they also chain the 404 response in a way that deletes said info.

    What's the OS/Server software stack? Who's your hosting? Could it be something they turned off or disabled? How are you handling this 404, did you use a redirect that might erase that data?
     
    deathshadow, Aug 6, 2020 IP
  9. outrefranc

    outrefranc Active Member

    Messages:
    94
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    93
    #9
    Thanks, you're helping me!
    I have an Apache server running PHP Version 7.2.31.

    When I request:
    <?php
    phpinfo();
    phpinfo(INFO_MODULES);
    ?>
    Code (markup):
    I get plenty of data, it works.
    But when I ask:
    <?php
    print_r(apache_get_modules());
    ?>
    Code (markup):
    I'm getting a blank. The server doesn't understand it.
    I've also tried this:

    <?php
    function apache_module_exists($module_name)
    {
        $modules = apache_get_modules();
        foreach ($modules as $module)
        {
            if ($module == $module_name)
                return true;
        }
        return false;
    }
    var_dump(apache_module_exists('mod_headers'));
    ?>
    Code (markup):
    But it's not working any better.

    The script I'm talking since is beginning as been added to my 404 page. People gets redirected to that page if they type a wrong URI, and I'm afraid I'll have to find another way to find out where they're coming from. I have no plan to change my server soon.
     
    outrefranc, Aug 6, 2020 IP
  10. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #10
    So I assume a simple:

    <?php echo '<pre>', print_r($_SERVER), '</pre>';

    Run as a normal everyday .php (no redirects or such involved) Is missing the values we're talking about? If so it's almost certainly a server configuration "problem".
     
    deathshadow, Aug 7, 2020 IP
  11. JEET

    JEET Notable Member

    Messages:
    3,825
    Likes Received:
    502
    Best Answers:
    19
    Trophy Points:
    265
    #11
    There is a good chance that its a HTTP to HTTPS issue.

    Your htaccess file is redirecting non-https URLS to https versions.

    So when people are going to:
    
    http://domain.com/no-page-here/
    
    Code (markup):
    they are getting redirected to:
    
    http://domain.com/404.php
    
    Code (markup):
    which then redirects to
    
    https://domain.com/404.php
    
    Code (markup):
    This is setting the REQUEST_URI to be "404.php", instead of the original URL they visited.

    Show the contents of your htaccess file please.

    Is it something like this:

    .htaccess
    ErrorDocument 404 /404.php
    redirect to https here
    other rules here

    Try changing the order of those lines, move he redirect code above 404 code:
    .htaccess
    redirect to https here
    ErrorDocument 404 /404.php
    other rules here
     
    JEET, Aug 7, 2020 IP
  12. outrefranc

    outrefranc Active Member

    Messages:
    94
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    93
    #12
    No. My 404 redirect in my .htaccess goes to an https file.
    Besides, I've tried an error from https://www.domain.com/vghkvghkvbhkb and it makes no difference. Thanks for the idea, though.

    
    <?php
    echo "<pre>\n";
    print_r( $_SERVER );
    echo "</pre>\n";
    ?>
    
    Code (markup):
    gets me a list of parameters. HTTP_REFERER is not in it.

    I've added this to my 404 page:
    <?php
    echo $_SERVER['PHP_SELF'];
    echo "<br>";
    echo $_SERVER['SERVER_NAME'];
    echo "<br>";
    echo $_SERVER['HTTP_HOST'];
    echo "<br>";
    echo $_SERVER['HTTP_REFERER'];
    echo "<br>";
    echo $_SERVER['HTTP_USER_AGENT'];
    echo "<br>";
    echo $_SERVER['SCRIPT_NAME'];
    ?>
    Code (markup):
    Then I type an URI which doesn't exist, I'm redirected to my 404, everything works but the "HTTP_REFERER" which is missing.
    I've contacted support from my hosting company.
    I hope to get a quick answer.
     
    Last edited: Aug 8, 2020
    outrefranc, Aug 8, 2020 IP
  13. outrefranc

    outrefranc Active Member

    Messages:
    94
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    93
    #13
    I've found the "HTTP_REFERER" which is missing in my server configuration.
    It's a bit tricky.
    I've added the php script to get the server config on a web page, and the "HTTP_REFERER" value isn't there when I type the page's URL in my browser, because there's no referer, but I can get it if I write this URL on another web page, with a link, and the referer then shows as there's one.
    ...
     
    outrefranc, Aug 9, 2020 IP