Jump to content

$_SERVER Array Variables


phpsane

Recommended Posts

Php mates,

I am going through this page to learn how to grab the User's browser details:

http://php.net/manual/en/function.get-browser.php

I see the manual showing 2 samples. Which one would you go for to get the User's browser details ?

Seems like the 1st code had some problems and so someone gave us the 2nd code. I just want your opinion on the 2nd code before I note it as valid to learn from.

Here is the 1st code:

Got it from here:

http://php.net/manual/vote-note.php?id=119332&page=function.get-browser&vote=down

	<?php

function get_browser_name($user_agent)
{
    if (strpos($user_agent, 'Opera') || strpos($user_agent, 'OPR/')) return 'Opera';
    elseif (strpos($user_agent, 'Edge')) return 'Edge';
    elseif (strpos($user_agent, 'Chrome')) return 'Chrome';
    elseif (strpos($user_agent, 'Safari')) return 'Safari';
    elseif (strpos($user_agent, 'Firefox')) return 'Firefox';
    elseif (strpos($user_agent, 'MSIE') || strpos($user_agent, 'Trident/7')) return 'Internet Explorer';
    
    return 'Other';
}

// Usage:

echo get_browser_name($_SERVER['HTTP_USER_AGENT']);

?>
	

Here is the 2nd:

Got it from here:

http://php.net/manual/en/function.get-browser.php#101125

	<?php
function getBrowser() 
{ 
    $u_agent = $_SERVER['HTTP_USER_AGENT']; 
    $bname = 'Unknown';
    $platform = 'Unknown';
    $version= "";

    //First get the platform?
    if (preg_match('/linux/i', $u_agent)) {
        $platform = 'linux';
    }
    elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
        $platform = 'mac';
    }
    elseif (preg_match('/windows|win32/i', $u_agent)) {
        $platform = 'windows';
    }
    
    // Next get the name of the useragent yes seperately and for good reason
    if(preg_match('/MSIE/i',$u_agent) && !preg_match('/Opera/i',$u_agent)) 
    { 
        $bname = 'Internet Explorer'; 
        $ub = "MSIE"; 
    } 
    elseif(preg_match('/Firefox/i',$u_agent)) 
    { 
        $bname = 'Mozilla Firefox'; 
        $ub = "Firefox"; 
    } 
    elseif(preg_match('/Chrome/i',$u_agent)) 
    { 
        $bname = 'Google Chrome'; 
        $ub = "Chrome"; 
    } 
    elseif(preg_match('/Safari/i',$u_agent)) 
    { 
        $bname = 'Apple Safari'; 
        $ub = "Safari"; 
    } 
    elseif(preg_match('/Opera/i',$u_agent)) 
    { 
        $bname = 'Opera'; 
        $ub = "Opera"; 
    } 
    elseif(preg_match('/Netscape/i',$u_agent)) 
    { 
        $bname = 'Netscape'; 
        $ub = "Netscape"; 
    } 
    
    // finally get the correct version number
    $known = array('Version', $ub, 'other');
    $pattern = '#(?<browser>' . join('|', $known) .
    ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
    if (!preg_match_all($pattern, $u_agent, $matches)) {
        // we have no matching number just continue
    }
    
    // see how many we have
    $i = count($matches['browser']);
    if ($i != 1) {
        //we will have two since we are not using 'other' argument yet
        //see if version is before or after the name
        if (strripos($u_agent,"Version") < strripos($u_agent,$ub)){
            $version= $matches['version'][0];
        }
        else {
            $version= $matches['version'][1];
        }
    }
    else {
        $version= $matches['version'][0];
    }
    
    // check if we have a number
    if ($version==null || $version=="") {$version="?";}
    
    return array(
        'userAgent' => $u_agent,
        'name'      => $bname,
        'version'   => $version,
        'platform'  => $platform,
        'pattern'    => $pattern
    );
} 

// now try it
$ua=getBrowser();
$yourbrowser= "Your browser: " . $ua['name'] . " " . $ua['version'] . " on " .$ua['platform'] . " reports: <br >" . $ua['userAgent'];
print_r($yourbrowser);
?>
	

 

Do checkout the links before giving your professional opinions.

 

Thanks!

 

 

Link to comment
Share on other sites

I am playing with these:

<?php
echo $_SERVER['GATEWAY_INTERFACE'];?> <br>
<?php
echo $_SERVER['SERVER_NAME'];?> <br>
<?php
echo $_SERVER['SERVER_ADDR'];?> <br>
<?php
echo $_SERVER['SERVER_SOFTWARE'];?> <br>
<?php
echo $_SERVER['SERVER_PROTOCOL'];?> <br>
<?php
echo $_SERVER['REQUEST_METHOD'];?> <br>
<?php
echo $_SERVER['REQUEST_TIME'];?> <br>
<?php
echo $_SERVER['REQUEST_TIME_FLOAT'];?> <br>
<?php
echo $_SERVER['QUERY_STRING'];?> <br>
<?php
echo $_SERVER['DOCUMENT_ROOT'];?> <br>
<?php
echo $_SERVER['HTTP_ACCEPT'];?> <br>
<?php
echo $_SERVER['HTTP_ACCEPT_CHARSET'];?> <br>
<?php
echo $_SERVER['HTTP_ACCEPT_ENCODING'];?> <br>
<?php
echo $_SERVER['HTTP_ACCEPT_LANGUAGE'];?> <br>
<?php
echo $_SERVER['HTTP_CONNECTION'];?> <br>
<?php
echo $_SERVER['HTTP_HOST'];?> <br>
<?php
echo $_SERVER['HTTP_REFERER'];?> <br>
<?php
echo $_SERVER['HTTP_USER_AGENT'];?> <br>
<?php
echo $_SERVER['HTTPS'];?> <br>

Found them here:
http://php.net/manual/en/reserved.variables.server.php

I get error:
Notice: Undefined index: HTTP_ACCEPT_CHARSET in C:\xampp\htdocs\test\user_and_server_details.php on line ..

What is wrong with this line:

<?php
echo $_SERVER['HTTP_ACCEPT_CHARSET'];?>

Link to comment
Share on other sites

2 hours ago, phpsane said:

Q1. Why does not this following php code grab the url and echo it ?

Because you don't know what a query string is.

2 hours ago, phpsane said:

Q2. And why does this only echo "User IP - ::1" instead of the user's ip ?

That's exactly what it's doing. lern2ipv6.

1 hour ago, phpsane said:

Which one would you go for to get the User's browser details ?

I wouldn't. What do you need the browser information for?

1 hour ago, phpsane said:

What is wrong with this line:

The problem is your total lack of understanding about what those values are. All the HTTP_* entries in there are request headers sent by the browser, if they were sent.

Link to comment
Share on other sites

You can save yourself a lot of time using print_r or var_dump in the future for experimentation and debugging:

var_dump($_SERVER);

To reiterate what Requinix just explained, these variables have various sources and reliability. They are dependent on the environment and configuration and don't always exist.    Another very helpful technique for learning more about your environment is to utilize phpinfo().

 

<?php
phpinfo();

For command line php run this from your shell:

php -i

Spend some time going through the output of these commands, and use that to read the manual for clarification and additional information.  

As for browser/client detection, I'm not sure what you want to know about those scripts you cribbed from comments.  Neither one is even attempting to do more than a mediocre job.  There are component libraries out there like https://github.com/sinergi/php-browser-detector or https://github.com/Wolfcast/BrowserDetection you could use.  But again as Requinix warned, variables like these are provided by the client and can be spoofed.  

Link to comment
Share on other sites

20 hours ago, requinix said:

Because you don't know what a query string is.

That's exactly what it's doing. lern2ipv6.

I wouldn't. What do you need the browser information for?

The problem is your total lack of understanding about what those values are. All the HTTP_* entries in there are request headers sent by the browser, if they were sent.

1. Oh! I get it now! This:

$url = $_SERVER['QUERY_STRING'];

only outputs the url if the url is a dynamic url with a query "?". Eg. http://requinix.com/female/?user=01

In this case, that code would only grab and display: "user=01".

Correct, Requinix ?

 

2. 

echo 'User IP - '.$_SERVER['REMOTE_ADDR'];

Look what I found:

http://forums.devshed.com/php-development/968306-real-help-_server-post2953927.html

Re-instate me back on devshed.com. I don't know why you banned me there. If it was you that banned there, that is.

This way, I won't have to depend on this forum where users are much more impatient than the users over there. No offense. But the truth.

By grabbing the User's browser details during reg, I can make sure the login checks if the user is logging in from his same machine that he signed-up with. If it's a different browser then most likely he is logging-in with a different machine.

Unless ofcourse Requinix, you can show me a line of code that checks the user's mach address. Say, can php do that ? Grab the computer's mach address ? And better, change a user's mach address so websites cannot grab the user's real mach address. Yet again, I reckon webservers cannot detect a user's mach address. Right ? :)

 

Thanks!

 

Link to comment
Share on other sites

Folks,

I need to grab the visitor's isp. So, how to do it with php ?
I found this:
https://stackoverflow.com/questions/855967/how-do-i-retrieve-the-visitors-isp-through-php
But the tos forbids us using their resources:
http://whatismyipaddress.com/terms-of-use

Hence, need to fetch the isp details without using the third party whatismyipaddress.com.
How do they fetch it ?

Link to comment
Share on other sites

3 hours ago, phpsane said:

Correct, Requinix ?

Yes.

3 hours ago, phpsane said:

Re-instate me back on devshed.com. I don't know why you banned me there. If it was you that banned there, that is.

It probably was, and no.

3 hours ago, phpsane said:

By grabbing the User's browser details during reg, I can make sure the login checks if the user is logging in from his same machine that he signed-up with. If it's a different browser then most likely he is logging-in with a different machine.

All you need is IP address and user agent. You don't need browser details.

3 hours ago, phpsane said:

Say, can php do that ?

No, you cannot get the MAC address of your user. You cannot get it, you cannot change it, you cannot do anything related to it.

2 hours ago, phpsane said:

I need to grab the visitor's isp. So, how to do it with php ?

With a different third-party service.

Link to comment
Share on other sites

I can't imagine a scenario where the gobbledy-gook of a system you apparently are trying to create would be justified, or possible within your demonstrated engineering capabilities.   You are talking about trying to create a system that requires a user to only use one workstation and browser to access your system.  I don't know what your system would be doing, but it better be providing literally life saving services, because short of that, nobody is going to put up with the restrictions you have in mind.  They are anti-user, and when you make things difficult for users, they stop using your system, or never even stay long enough to pass the entry point.  It is damn difficult to get anyone to sign up to use legitimately valuable services, which is why you see so many systems that integrate with facebook, google and twitter, so that you can create your account and trust authentication from those systems to allow access.

Furthermore some of your plans reflect an apparent lack of understanding of Internet basics like NAT.  In your system, if we were to follow along with your plans, for a large company with perhaps 1000 employees at a particular site, you plan to only allow 1 employee there to use your system.  Ditto universities, or even an average household:  "Hey there roommate, I just made an account at this site, you should too!"  "WTF, the system says I'm banned!"

Since you are focused on investigating a client IP, I will say this about IP addresses -- they are reliable at least to the degree that they reflect the tcp socket connection from the client to the server.   That information bubbles up to PHP from the IP layer, to the server, and finally to PHP's $_SERVER superglob.  The problem is, that a client could have bounced through a variety of gateways, proxy servers or VPN prior to the point that you are finally connected.  

In many sophisticated hosting environments there are things like load balancers or reverse proxy servers that sit between the client connection and the server which interfere with $_SERVER['REMOTE_ADDR'].  Rather than see the client IP, you instead see the IP of the proxy server.  If you have that sort of environment, then you can examine $_SERVER['X-Forwarded-For'] or $_SERVER['HTTP_X_FORWARDED_FOR'] variables.  These may be arrays with a series of addresses.  Again you have the issue that these are provided by the "client" so if it is a proxy server you can depend on at least the most recent address to have been the one that made the TCP socket connection to YOUR proxy server.  Other legitimate proxy servers will provide the same data.

However, someone who is taking steps to hide their origin is not going to be prevented from obscuring their IP and there is absolutely nothing you can do about it.   Almost everyone uses NAT in some form, so the actual person IP address of a workstation on a network is never going to be visible (and would also be useless if it was, since these will be non-routable IP addresses that are shared by hundreds of millions of users).

Solutions to the issue of certification and authentication, when people have real and legitimate reasons to solve them, involve cryptography.  What you are trying to do can be accomplished using X.509 certificates which have support built into browsers.

In a nutshell, at account creation time you would generate an client certificate for that user, installing that into your server, and then providing the signed cert back to them in a specific header (application/x-x509-user-cert ).  This will cause the browser to prompt the user to install the cert into their browser.  If they accept you know have a reliable way of identifying a specific user.  At that point, whenever they connect (must be under SSL) you'll be able to authenticate them back to your system via that particular certificate.  Those without a client certificate will be unable to connect.  You can think of this as white listing. 

It is highly effective but is typically used only in environments where the system knows in advance who their allowed users are.  Trying to use it in a public facing website with an unknown user base is something you just don't see because the benefits of trying to do this far outweigh the tolerance that people have for a system that has that degree of odious overhead and invasion of their privacy.  

In conclusion:

The types of things you are obsessed with are all edge case items.  No quality system begins with the premise that the #1 goal is to try and catch and outsmart an imaginary horde of people attacking your site for reasons unknown.  

This started as a specific thread about the contents of $_SERVER variables and then escalated into fairly delusional territory, with a dash of your personal Devshed drama thrown in.  And let's just be clear about one thing:  If you ever bring up your personal issues regarding your Devshed access again, which are irrelevant to this community, then your access to this community will end as well.  It's off topic, it's a waste of people's time and efforts here, and it's rude.  I just want to be clear that I won't tolerate it again.

Link to comment
Share on other sites

On 11/7/2018 at 12:21 AM, gizmola said:

I can't imagine a scenario where the gobbledy-gook of a system you apparently are trying to create would be justified, or possible within your demonstrated engineering capabilities.   You are talking about trying to create a system that requires a user to only use one workstation and browser to access your system.  I don't know what your system would be doing, but it better be providing literally life saving services, because short of that, nobody is going to put up with the restrictions you have in mind.  They are anti-user, and when you make things difficult for users, they stop using your system, or never even stay long enough to pass the entry point.  It is damn difficult to get anyone to sign up to use legitimately valuable services, which is why you see so many systems that integrate with facebook, google and twitter, so that you can create your account and trust authentication from those systems to allow access.

Furthermore some of your plans reflect an apparent lack of understanding of Internet basics like NAT.  In your system, if we were to follow along with your plans, for a large company with perhaps 1000 employees at a particular site, you plan to only allow 1 employee there to use your system.  Ditto universities, or even an average household:  "Hey there roommate, I just made an account at this site, you should too!"  "WTF, the system says I'm banned!"

Since you are focused on investigating a client IP, I will say this about IP addresses -- they are reliable at least to the degree that they reflect the tcp socket connection from the client to the server.   That information bubbles up to PHP from the IP layer, to the server, and finally to PHP's $_SERVER superglob.  The problem is, that a client could have bounced through a variety of gateways, proxy servers or VPN prior to the point that you are finally connected.  

In many sophisticated hosting environments there are things like load balancers or reverse proxy servers that sit between the client connection and the server which interfere with $_SERVER['REMOTE_ADDR'].  Rather than see the client IP, you instead see the IP of the proxy server.  If you have that sort of environment, then you can examine $_SERVER['X-Forwarded-For'] or $_SERVER['HTTP_X_FORWARDED_FOR'] variables.  These may be arrays with a series of addresses.  Again you have the issue that these are provided by the "client" so if it is a proxy server you can depend on at least the most recent address to have been the one that made the TCP socket connection to YOUR proxy server.  Other legitimate proxy servers will provide the same data.

However, someone who is taking steps to hide their origin is not going to be prevented from obscuring their IP and there is absolutely nothing you can do about it.   Almost everyone uses NAT in some form, so the actual person IP address of a workstation on a network is never going to be visible (and would also be useless if it was, since these will be non-routable IP addresses that are shared by hundreds of millions of users).

Solutions to the issue of certification and authentication, when people have real and legitimate reasons to solve them, involve cryptography.  What you are trying to do can be accomplished using X.509 certificates which have support built into browsers.

In a nutshell, at account creation time you would generate an client certificate for that user, installing that into your server, and then providing the signed cert back to them in a specific header (application/x-x509-user-cert ).  This will cause the browser to prompt the user to install the cert into their browser.  If they accept you know have a reliable way of identifying a specific user.  At that point, whenever they connect (must be under SSL) you'll be able to authenticate them back to your system via that particular certificate.  Those without a client certificate will be unable to connect.  You can think of this as white listing. 

It is highly effective but is typically used only in environments where the system knows in advance who their allowed users are.  Trying to use it in a public facing website with an unknown user base is something you just don't see because the benefits of trying to do this far outweigh the tolerance that people have for a system that has that degree of odious overhead and invasion of their privacy.  

In conclusion:

The types of things you are obses sed with are all edge case items.  No quality system begins with the premise that the #1 goal is to try and catch and outsmart an imaginary horde of people attacking your site for reasons unknown.  

This started as a specific thread about the contents of $_SERVER variables and then escalated into fairly delusional territory, with a dash of your personal Devshed drama thrown in.  And let's just be clear about one thing:  If you ever bring up your personal issues regarding your Devshed access again, which are irrelevant to this community, then your access to this community will end as well.  It's off topic, it's a waste of people's time and efforts here, and it's rude.  I just want to be clear that I won't tolerate it again.

Well. I liked your in-depth feedback (apart from the final paragraph but I understand why you reacted the way you did, though. So, no offense taken).

I am now gonna take your advice and quit trying to tie an account holder to a single machine. Quite frankly, I don't know what came over me to attempt that. (Scratching my head). Maybe, I read some article somewhere about servers getting hacked.

Anyway, let's try keeping this thread on-topic. I am playing around with these 2 codes and am wondering why they fail.

1. Code from:

http://php.net/manual/en/function.geoip-isp-by-name.php

	<?php
$isp = geoip_isp_by_name('www.example.com');
if ($isp) {
    echo 'This host IP is from ISP: ' . $isp;
}
?>
	

 

Fatal error: Uncaught Error: Call to undefined function geoip_isp_by_name() in C:\xampp\htdocs\test\test.php:130 Stack trace: #0 {main} thrown in 

 

2. Same result on this too:

Code from:

http://php.net/manual/en/function.geoip-country-name-by-name.php

	<?php
$country = geoip_country_name_by_name('www.example.com');
if ($country) {
    echo 'This host is located in: ' . $country;
}
?>
	

Fatal error: Uncaught Error: Call to undefined function geoip_country_name_by_name() in C:\xampp\htdocs\test\test.php:130 Stack trace: #0 {main} thrown in 

 

I thought these 2 functions are defined by default. Definition of these 2 are built-into php.

Link to comment
Share on other sites

6 minutes ago, Barand said:

Why would you think that when the manual clearly tells you otherwise. (Read last sentence of the function description)

RTFM!

Oops! I skipped the description! That is why I missed it. Went straight to the example code. Lol! :D

However, this one does not say such in it's description:

http://php.net/manual/en/function.geoip-country-name-by-name.php

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.