LVS (managed with the ipvsadm command) runs in kernel mode and mainly just routes packets, and perhaps does DNATing (depending on how you configure it). I've had the most luck with using the NATing option, I think the direct routing are a little bit harder to set up from a network topology standpoint, the NATing option is more, uh, "obvious". The drawback is that your topology has to be setup so that your LVS load balancer is also the default gateway. LVS is protocol agnostic, it's a layer 4 load balancer. In this setup, you'll need to run SSL on your webservers. You'll configure LVS with something like keepalived, which is a userspace program to do healthchecks and manage the kernel interface to LVS. There are others, but I'm only familiar with keepalived.
haproxy is a user-space program. It can be both a plain TCP load balancer but also can do Layer 7 load balancing of HTTP based on header matching and whatever ACLs you want to write. haproxy doesn't support SSL out of the box, you need to use something like stunnel in front of it. Of course, you can configure all SSL traffic and just use TCP load balancing, but then you can't do layer 7 load balancing (because haproxy can't see into the request) which is one of haproxy's strengths. Of course, since it is userspace, your web server will see your load balancer's IP as the source of the request. There is an apache module, rpaf (I think), that honors X-Forwarded-For headers that can be inserted by haproxy. I think something similar exists for nginx and lighttpd. You need a patched version of stunnel to have it insert X-Forwarded-For headers if you want to wrap haproxy in stunnel.
Right now, I'm preferring haproxy because the setup can be much more customized. It's also easier to firewall haproxy, since it's application level. Getting iptables and LVS to work well together is possible but can be confusing if you use NAT mode because of where LVS integrates into the IP stack in relation to where iptables integrates. haproxy has many more options to deal with timeouts and healthchecks than keepalived.
But if you're just finishing up a weekend project, load balancing may be a premature optimization right now. The thing to keep in mind is that you want to make sure your program will work with load balancing so it's easier to transition to it when the time comes. Things like not assuming there is only one node services all requests -- common problem with PHP and the default PHP session handler is that it writes its sessions to the local file system. If future requests come in and go to a different web server, it won't see the session. This often manifests itself as having to continuously login. You'll need some way to share session data between web servers (or store everything in (encrypted) cookies. This problem is in no way limited to PHP, however.