There's just a method to be somehow sure that a user is "online". To accomplish it you need to understand that with "online" people usually refer to an user being online in that moment; while checking this is not easy (or even not possible), to check if a user has made any action within an x amount of time is very easy, and it's the choice most of the programmers do.
It's pretty easy:
- You create a field for each logged in user in a database called 
last_activity. 
- Every time a user visit a page you set 
last_activity to the current time()stamp. 
- You define a 
$x amount of seconds that a user can be idle (not browsing any new page) before being considered offline. (Usually it is 15 min or 30 min or 1 hour). 
- You do a simple query like 
"SELECT * FROM users WHERE last_activity >= ". (time() - $x) 
- You now have a list of users that has loaded a page within 
$x seconds. 
Unlike other things, in PHP and with web browser there's no way to detect for sure when a user has closed one of your page in the browser, so it's technically impossible to know whenever a user has closed the browser window or exit your website.
By the way, I lied, there's a method but it's really expensive so please think a lot about it because it could crash your server or something like that:
- Create the 
last_activity field in the user table (as below). 
- Create a Javascript code (using AJAX) that every 
y seconds require update.php (just an example). 
- Put that javascript in every page of your website (Consider 
y to be the bigger number you can (< 30 seconds may be bad)). 
- Create 
update.php where you update last_activity with the current time()stamp. 
- Do the same query as before using 
$x = $y + 1 when you want to find out the online people. 
With the latest solution you can be sure that whenever a user is not on the page anymore, he is also not running the AJAX call and then within y seconds it will be not considered online anymore. It's a very similar solution to the first one, but you can set y to be smaller than the previous x. In this way you have more informations about the current state of the browser window of the user but you have much more database load than before.