Putting the session_id into the URI may fail in a lot of situations, such as with users behind a caching proxy.
By "fail" do you mean that the pages will not be cacheable by the proxy? In that case, hidden form fields have exactly the same problem, since the content of the page has to be different for every user. Proxy servers don't cache POST requests and GET requests coming from a form submission look identical to URIs with query args on the end. Hidden fields also have the problem of making every single link a form submission, which is a real pain and means replacing text links with images and buttons.
Also, your use of the remote IP as part of your session ID does not prevent people from hijacking a session, it just makes it harder to guess a valid one, and it is possible to create duplicate IDs when using this in a cluster. It would be safer to use mod_unique_id for generating the ID and then use a MAC to verify it when it gets sent back, as described here.