I try not to comment the obvious things, however the modern techniques of documenting the code often force to break this "rule". Consider the following code:
/**
* Returns the user name.
*
* @return String The username.
*/
public function getUsername()
{
return $this->_username;
} // end getUserName();
Do we need this "phpdoc" (or "otherlanguagedoc") longer that the function itself to know what it is supposed to do? No - the code itself is clear enough and obvious, but unless we add the comment, there will be problems with the documentation generators and IDEs.
Generally, I think that the answer to the question "what do we comment" depend on the code we are going to write. When making a website application, I unsually don't put any for the standard parts of the CRUD-s, because almost all of them follow the same schema: check the permissions, parse the input, optionally get the item, do the something with the database, redirect the user somewhere". Such code is easily readable even after two or more years.
On the other hands, we have a specialized code that solves a particular technical problem, for example a kind of parser. Here, the complexity is greater: we use some data structures, the algorithm may move the data between them to perform a certain task etc. If I see that the algorithm does not follow any popular schema, I describe the used data structures, its purpose and what operations are performed on them in order to complete the task. I also try to explain, why the specified solution was chosen. Here, I find the "somelanguagedoc" comment syntax useful - internal and system functions that are not exposed publicly, but also should be briefly described, especially in complex code just to know, what they are actually doing, why and what their arguments mean. The alternative is to find all the occurences of them and guessing.
However, I must also point that sometimes it is very hard to predict, what is worth commenting. A couple of months ago I returned to a piece of code in one of my projects to add some extra functionality. Suddenly I noticed a quite important condition and had no idea, why I used it. I think it must have been something obvious while writing this part, but even the investigation didn't help :).
The last comment practice I use is marking the end of the function, class and interface with its name:
void somefunction()
{
....
} // end somefunction();
It helps me navigating.