I don't think it is possible using PHP.
I'm not sure how much you know about TCP/IP but any person in the world can have any IP address (as long as its not reserved and not in use by someone else in the same subnet), so there is no way to say something like "person with IP 147.171.x.x definetly lives in the US", as any company in the world can reserve an IP subnet.
If you do want to do this urself, and don't fancy going with GeoIP, then one way is to reverse DNS the IP address, see if there's a recognisable domain suffix (.co.uk, .fr, .de etc) and map it to a country that way.
That way is pretty unreliable though, as a lot of ISPs will hand out hostnames to their users with a .com suffix, which could be anywhere in the world.
I think that the web stats software, "awstats" uses a method similiar to this, as it shows stats for people visiting from hostnames with a country identifier in their hostname, and just classes ".com" as "commercial".
Most reliable way i guess is for users to sign up to your site, and have "location/country" field as part of their profile. Of course, that won't show every single visitor :/
Many shoes ("Regards" for people wondering why I use 'shoes'),