Reputation: 37750
Before you tell me to use parse_url
, it's not nearly good enough and has too many bugs. There are many questions on the subject of parsing URLs be found on here, but nearly all are to parse only some specific class of URLs or are otherwise incomplete.
I'm looking for a definitive RFC-compliant URL parser in PHP that will reliably process any URL that a browser is likely to encounter. In this I include:
#
, #title
blah/thing.php
/blah/thing.php
//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js
callto:+442079460123
file:///Users/me/thisfile.txt
mailto:[email protected]?subject=hello
, mailto:?subject=hello
and support for all the usual scheme/authentication/domain/path/query/fragment etc, and break all of those elements out into an array, with extra flags for relative/schemaless URLs. Ideally it would come with a URL reconstructor (like http_build_url) supporting the same elements, and I'd also like validation to be applied (i.e. it should be able to make a best-guess interpretation of a URL if it's invalid, but flag it as such, just like browsers do).
This answer contained a tantalising Fermat-style reference to such a beast, but it doesn't actually go anywhere.
I've looked in all the major frameworks, but they only seem to provide thin wrappers around parse_url which is generally a bad place to start since it makes so many mistakes.
So, does such a thing exist?
Upvotes: 9
Views: 1131
Reputation: 173582
Not sure how many bugs parse_url()
has, but this might help:
As the "first-match-wins" algorithm is identical to the "greedy" disambiguation method used by POSIX regular expressions, it is natural and commonplace to use a regular expression for parsing the potential five components of a URI reference.
The following line is the regular expression for breaking-down a well-formed URI reference into its components.
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
12 3 4 5 6 7 8 9
Source: https://www.rfc-editor.org/rfc/rfc3986#page-51
It breaks down the location as:
$2 - scheme
$4 - host
$5 - path
$6 - query string
$8 - fragment
To rebuild, you could use:
$1 . $3 . $5 . $6 . $8
Upvotes: 3