urlencode
URL-encodes a string the way an HTML form does, turning spaces into plus signs.
urlencode(string $string): string- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string | string | The string to be encoded. |
Return value
stringA string in which all non-alphanumeric characters except -_. are replaced with a percent sign and two hex digits, and spaces are replaced with +.
Errors
Does not throw.
urlencode() produces application/x-www-form-urlencoded output — the exact encoding a browser uses when it submits a GET or POST form. Spaces become +, and everything except letters, digits and -_. becomes a percent escape.
Where it belongs
Query string values and form bodies. Nowhere else. A + in a URL path is a literal plus sign, not a space, so using urlencode() on a path segment silently corrupts filenames. The same applies to HTTP headers, OAuth signature strings, and anything consumed by a non-PHP client that follows RFC 3986 strictly. For those, use rawurlencode().
Prefer the builder
If you are encoding more than one parameter, http_build_query() does the whole job and cannot forget a value. Reach for urlencode() when you are splicing a single value into a template.
It is not HTML escaping
Encoding a value for a URL is unrelated to escaping it for HTML output. A URL placed inside an href attribute still needs htmlspecialchars() around it, because urlencode() leaves nothing that would close the attribute but also does not encode a pre-existing & in the surrounding template.
Example
When to use it
- Splice a user's search term into a query string template
- Build an application/x-www-form-urlencoded POST body for a legacy endpoint
- Encode a return-to URL that will be carried as a query parameter
- Construct a share link containing a title and description
Frequently asked questions
Why does urlencode turn spaces into + instead of %20?
Because it produces application/x-www-form-urlencoded output, the historical HTML form encoding. Use rawurlencode when you need the RFC 3986 %20 form.
Should I use urlencode or http_build_query?
Use http_build_query for a set of parameters; it encodes keys and values and joins them for you. Reserve urlencode for splicing a single value into a URL template.
Does urlencode protect against XSS?
No. It encodes for URLs, not HTML. A URL printed into an href attribute still needs htmlspecialchars.
More examples
urlencode versus rawurlencode
urlencode gives C%2B%2B+guide+%7E+v2 and rawurlencode gives C%2B%2B%20guide%20~%20v2: spaces differ, and ~ is escaped only by urlencode. Both round-trip correctly as long as you pair each encoder with its own decoder.
<?php
$value = 'C++ guide ~ v2';
echo 'urlencode : ' . urlencode($value) . "\n";
echo 'rawurlencode : ' . rawurlencode($value) . "\n";
// Round-trip each with its matching decoder.
var_dump(urldecode(urlencode($value)) === $value);
var_dump(rawurldecode(rawurlencode($value)) === $value);Encoding a whole URL is wrong
The first line escapes the colon, slashes and question mark, leaving a string that is no longer a URL. The second builds it from encoded pieces, so only the space inside the "a b" segment is escaped and the separators stay intact.
<?php
$url = 'https://example.com/a b/c?x=1&y=2';
// Wrong: the structure is destroyed.
echo urlencode($url), "\n";
// Right: encode the parts that need it.
$path = implode('/', array_map('rawurlencode', ['a b', 'c']));
echo 'https://example.com/' . $path . '?' . http_build_query(['x' => 1, 'y' => 2]), "\n";URL encoding is not HTML encoding
urlencode makes the nested URL safe as a parameter value, turning its & into %26. htmlspecialchars is still needed for the attribute itself: it escapes the outer & into & so the markup is valid HTML.
<?php
$next = 'https://example.com/?a=1&b=2';
$href = 'https://example.com/login?next=' . urlencode($next);
echo $href, "\n";
echo '<a href="' . htmlspecialchars($href, ENT_QUOTES) . '">Log in</a>', "\n";
Discussion