Guest User

exploit

a guest
Feb 16th, 2017
413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 66.60 KB | None | 0 0
  1. F0r__Y0u7ub3__3xp10i7ation
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14. php
  15.  
  16. Downloads
  17. Documentation
  18. Get Involved
  19. Help
  20.  
  21. PHP 7.0.16 Released
  22. rawurldecode »
  23. « http_build_query
  24.  
  25. PHP Manual Function Reference Other Basic Extensions URLs URL Functions
  26.  
  27. Change language:
  28. Edit Report a Bug
  29. parse_url
  30.  
  31. (PHP 4, PHP 5, PHP 7)
  32.  
  33. parse_url — Parse a URL and return its components
  34. Description ¶
  35. mixed parse_url ( string $url [, int $component = -1 ] )
  36.  
  37. This function parses a URL and returns an associative array containing any of the various components of the URL that are present.
  38.  
  39. This function is not meant to validate the given URL, it only breaks it up into the above listed parts. Partial URLs are also accepted, parse_url() tries its best to parse them correctly.
  40. Parameters ¶
  41.  
  42. url
  43.  
  44. The URL to parse. Invalid characters are replaced by _.
  45.  
  46. component
  47.  
  48. Specify one of PHP_URL_SCHEME, PHP_URL_HOST, PHP_URL_PORT, PHP_URL_USER, PHP_URL_PASS, PHP_URL_PATH, PHP_URL_QUERY or PHP_URL_FRAGMENT to retrieve just a specific URL component as a string (except when PHP_URL_PORT is given, in which case the return value will be an integer).
  49.  
  50. Return Values ¶
  51.  
  52. On seriously malformed URLs, parse_url() may return FALSE.
  53.  
  54. If the component parameter is omitted, an associative array is returned. At least one element will be present within the array. Potential keys within this array are:
  55.  
  56. scheme - e.g. http
  57. host
  58. port
  59. user
  60. pass
  61. path
  62. query - after the question mark ?
  63. fragment - after the hashmark #
  64.  
  65. If the component parameter is specified, parse_url() returns a string (or an integer, in the case of PHP_URL_PORT) instead of an array. If the requested component doesn't exist within the given URL, NULL will be returned.
  66. Changelog ¶
  67. Version Description
  68. 5.4.7 Fixed host recognition when scheme is omitted and a leading component separator is present.
  69. 5.3.3 Removed the E_WARNING that was emitted when URL parsing failed.
  70. 5.1.2 Added the component parameter.
  71. Examples ¶
  72.  
  73. Example #1 A parse_url() example
  74. <?php
  75. $url = 'http://username:password@hostname:9090/path?arg=value#anchor';
  76.  
  77. var_dump(parse_url($url));
  78. var_dump(parse_url($url, PHP_URL_SCHEME));
  79. var_dump(parse_url($url, PHP_URL_USER));
  80. var_dump(parse_url($url, PHP_URL_PASS));
  81. var_dump(parse_url($url, PHP_URL_HOST));
  82. var_dump(parse_url($url, PHP_URL_PORT));
  83. var_dump(parse_url($url, PHP_URL_PATH));
  84. var_dump(parse_url($url, PHP_URL_QUERY));
  85. var_dump(parse_url($url, PHP_URL_FRAGMENT));
  86. ?>
  87.  
  88. The above example will output:
  89.  
  90. array(8) {
  91. ["scheme"]=>
  92. string(4) "http"
  93. ["host"]=>
  94. string(8) "hostname"
  95. ["port"]=>
  96. int(9090)
  97. ["user"]=>
  98. string(8) "username"
  99. ["pass"]=>
  100. string(8) "password"
  101. ["path"]=>
  102. string(5) "/path"
  103. ["query"]=>
  104. string(9) "arg=value"
  105. ["fragment"]=>
  106. string(6) "anchor"
  107. }
  108. string(4) "http"
  109. string(8) "username"
  110. string(8) "password"
  111. string(8) "hostname"
  112. int(9090)
  113. string(5) "/path"
  114. string(9) "arg=value"
  115. string(6) "anchor"
  116.  
  117. Example #2 A parse_url() example with missing scheme
  118. <?php
  119. $url = '//www.example.com/path?googleguy=googley';
  120.  
  121. // Prior to 5.4.7 this would show the path as "//www.example.com/path"
  122. var_dump(parse_url($url));
  123. ?>
  124.  
  125. The above example will output:
  126.  
  127. array(3) {
  128. ["host"]=>
  129. string(15) "www.example.com"
  130. ["path"]=>
  131. string(5) "/path"
  132. ["query"]=>
  133. string(17) "googleguy=googley"
  134. }
  135.  
  136. Notes ¶
  137.  
  138. Note:
  139.  
  140. This function doesn't work with relative URLs.
  141.  
  142. Note:
  143.  
  144. This function is intended specifically for the purpose of parsing URLs and not URIs. However, to comply with PHP's backwards compatibility requirements it makes an exception for the file:// scheme where triple slashes (file:///...) are allowed. For any other scheme this is invalid.
  145.  
  146. See Also ¶
  147.  
  148. pathinfo() - Returns information about a file path
  149. parse_str() - Parses the string into variables
  150. http_build_query() - Generate URL-encoded query string
  151. dirname() - Returns a parent directory's path
  152. basename() - Returns trailing name component of path
  153. » RFC 3986
  154.  
  155. add a note add a note
  156. User Contributed Notes 57 notes
  157. up
  158. down
  159. 83
  160. thomas at gielfeldt dot com ¶
  161. 5 years ago
  162. [If you haven't yet] been able to find a simple conversion back to string from a parsed url, here's an example:
  163.  
  164. <?php
  165.  
  166. $url = 'http://usr:pss@example.com:81/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment';
  167. if ($url === unparse_url(parse_url($url))) {
  168. print "YES, they match!\n";
  169. }
  170.  
  171. function unparse_url($parsed_url) {
  172. $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
  173. $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
  174. $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
  175. $user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
  176. $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
  177. $pass = ($user || $pass) ? "$pass@" : '';
  178. $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
  179. $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
  180. $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
  181. return "$scheme$user$pass$host$port$path$query$fragment";
  182. }
  183.  
  184. ?>
  185. up
  186. down
  187. 14
  188. jerome at chaman dot ca ¶
  189. 2 years ago
  190. It may be worth reminding that the value of the #fragment never gets sent to the server. Anchors processing is exclusively client-side.
  191. up
  192. down
  193. 15
  194. lauris () lauris ! lv ¶
  195. 2 years ago
  196. Here is utf-8 compatible parse_url() replacement function based on "laszlo dot janszky at gmail dot com" work. Original incorrectly handled URLs with user:pass. Also made PHP 5.5 compatible (got rid of now deprecated regex /e modifier).
  197.  
  198. <?php
  199.  
  200. /**
  201. * UTF-8 aware parse_url() replacement.
  202. *
  203. * @return array
  204. */
  205. function mb_parse_url($url)
  206. {
  207. $enc_url = preg_replace_callback(
  208. '%[^:/@?&=#]+%usD',
  209. function ($matches)
  210. {
  211. return urlencode($matches[0]);
  212. },
  213. $url
  214. );
  215.  
  216. $parts = parse_url($enc_url);
  217.  
  218. if($parts === false)
  219. {
  220. throw new \InvalidArgumentException('Malformed URL: ' . $url);
  221. }
  222.  
  223. foreach($parts as $name => $value)
  224. {
  225. $parts[$name] = urldecode($value);
  226. }
  227.  
  228. return $parts;
  229. }
  230.  
  231. ?>
  232. up
  233. down
  234. 16
  235. james at roundeights dot com ¶
  236. 6 years ago
  237. I was writing unit tests and needed to cause this function to kick out an error and return FALSE in order to test a specific execution path. If anyone else needs to force a failure, the following inputs will work:
  238.  
  239. <?php
  240. parse_url("http:///example.com");
  241. parse_url("http://:80");
  242. parse_url("http://user@:80");
  243. ?>
  244. up
  245. down
  246. 9
  247. admin at griefer1999 dot uhostfull dot com ¶
  248. 2 years ago
  249. <?php
  250. function url_parse($url){
  251. $sflfdfldf=$url;
  252. if(strpos($url,"?")>-1){
  253. $a=explode("?",$url,2);
  254. $url=$a[0];
  255. $query=$a[1];
  256. }
  257. if(strpos($url,"://")>-1){
  258. $scheme=substr($url,0,strpos($url,"//")-1);
  259. $url=substr($url,strpos($url,"//")+2,strlen($url));
  260. }
  261. if(strpos($url,"/")>-1){
  262. $a=explode("/",$url,2);
  263. $url=$a[0];
  264. $path="/".$a[1];
  265. }
  266. if(strpos($url,":")>-1){
  267. $a=explode(":",$url,2);
  268. $url=$a[0];
  269. $port=$a[1];
  270. }
  271. $host=$url;
  272. $url=null;
  273. foreach(array("url","scheme","host","port","path","query") as $var){
  274. if(!empty($$var)){
  275. $return[$var]=$$var;
  276. }
  277. }
  278. //return array("url"=>$sflfdfldf,"scheme"=>$scheme,"host"=>$host,"port"=>$port,"path"=>$path,"query"=>$query,"a"=>$url);
  279. return $return;
  280. }
  281. ?>
  282.  
  283. <?php
  284. /* Compare two outputs */
  285. //mine
  286. print_r(url_parse("http://login.yahoo.com?.src=ym&.intl=gb&.lang=zh-Hans-HK&.done=https://mail.yahoo.com"));
  287. //internal
  288. print_r(parse_url("http://login.yahoo.com?.src=ym&.intl=gb&.lang=zh-Hans-HK&.done=https://mail.yahoo.com"));
  289. ?>
  290. up
  291. down
  292. 6
  293. ivijan dot stefan at gmail dot com ¶
  294. 2 years ago
  295. Here's a good way to using parse_url () gets the youtube link.
  296. This function I used in many works:
  297.  
  298. <?php
  299. function youtube($url, $width=560, $height=315, $fullscreen=true)
  300. {
  301. parse_str( parse_url( $url, PHP_URL_QUERY ), $my_array_of_vars );
  302. $youtube= '<iframe allowtransparency="true" scrolling="no" width="'.$width.'" height="'.$height.'" src="//www.youtube.com/embed/'.$my_array_of_vars['v'].'" frameborder="0"'.($fullscreen?' allowfullscreen':NULL).'></iframe>';
  303. return $youtube;
  304. }
  305.  
  306. // show youtube on my page
  307. $url='http://www.youtube.com/watch?v=yvTd6XxgCBE';
  308. youtube($url, 560, 315, true);
  309. ?>
  310.  
  311. parse_url () allocates a unique youtube code and put into iframe link and displayed on your page. The size of the videos choose yourself.
  312.  
  313. Enjoy.
  314. up
  315. down
  316. 1
  317. stevenlewis at hotmail dot com ¶
  318. 9 years ago
  319. an update to the glue url function.
  320.  
  321. you are able to put a host and a path without a slash at the beginning of the path
  322.  
  323. <?php
  324. function glue_url($parsed)
  325. {
  326. if (! is_array($parsed)) return false;
  327. $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '':'//'): '';
  328. $uri .= isset($parsed['user']) ? $parsed['user'].($parsed['pass']? ':'.$parsed['pass']:'').'@':'';
  329. $uri .= isset($parsed['host']) ? $parsed['host'] : '';
  330. $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
  331. if(isset($parsed['path']))
  332. {
  333. $uri .= (substr($parsed['path'],0,1) == '/')?$parsed['path']:'/'.$parsed['path'];
  334. }
  335. $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
  336. $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
  337. return $uri;
  338. }
  339. ?>
  340. up
  341. down
  342. 4
  343. jesse at example dot com ¶
  344. 6 years ago
  345. @ solenoid: Your code was very helpful, but it fails when the current URL has no query string (it appends '&' instead of '?' before the query). Below is a fixed version that catches this edge case and corrects it.
  346.  
  347. <?php
  348. function modify_url($mod)
  349. {
  350. $url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  351. $query = explode("&", $_SERVER['QUERY_STRING']);
  352. if (!$_SERVER['QUERY_STRING']) {$queryStart = "?";} else {$queryStart = "&";}
  353. // modify/delete data
  354. foreach($query as $q)
  355. {
  356. list($key, $value) = explode("=", $q);
  357. if(array_key_exists($key, $mod))
  358. {
  359. if($mod[$key])
  360. {
  361. $url = preg_replace('/'.$key.'='.$value.'/', $key.'='.$mod[$key], $url);
  362. }
  363. else
  364. {
  365. $url = preg_replace('/&?'.$key.'='.$value.'/', '', $url);
  366. }
  367. }
  368. }
  369. // add new data
  370. foreach($mod as $key => $value)
  371. {
  372. if($value && !preg_match('/'.$key.'=/', $url))
  373. {
  374. $url .= $queryStart.$key.'='.$value;
  375. }
  376. }
  377. return $url;
  378. }
  379. ?>
  380. up
  381. down
  382. 2
  383. utilmind ¶
  384. 3 years ago
  385. parse_url doesn't works if the protocol doesn't specified. This seems like sandard, even the youtube doesn't gives the protocol name when generates code for embedding which have a look like "//youtube.com/etc".
  386.  
  387. So, to avoid bug, you must always check, whether the provided url has the protocol, and if not (starts with 2 slashes) -- add the "http:" prefix.
  388. up
  389. down
  390. 2
  391. php at domblogger dot net ¶
  392. 2 years ago
  393. At least in php 5.6.x this function does appear to work with relative URLs despite what it says above.
  394.  
  395. Obviously it does not return the scheme or host, but it does return the path and query string and fragment from a relative URL.
  396. up
  397. down
  398. 2
  399. laszlo dot janszky at gmail dot com ¶
  400. 4 years ago
  401. Created another parse_url utf-8 compatible function.
  402. <?php
  403. function mb_parse_url($url) {
  404. $encodedUrl = preg_replace('%[^:/?#&=\.]+%usDe', 'urlencode(\'$0\')', $url);
  405. $components = parse_url($encodedUrl);
  406. foreach ($components as &$component)
  407. $component = urldecode($component);
  408. return $components;
  409. }
  410. ?>
  411. up
  412. down
  413. 2
  414. theoriginalmarksimpson at gmail dot com ¶
  415. 7 years ago
  416. An update to the function by FredLudd at gmail dot com. I added IPv6 functionality as well.
  417.  
  418. <?php
  419. function j_parseUrl($url) {
  420. $r = "(?:([a-z0-9+-._]+)://)?";
  421. $r .= "(?:";
  422. $r .= "(?:((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9a-f]{2})*)@)?";
  423. $r .= "(?:\[((?:[a-z0-9:])*)\])?";
  424. $r .= "((?:[a-z0-9-._~!$&'()*+,;=]|%[0-9a-f]{2})*)";
  425. $r .= "(?::(\d*))?";
  426. $r .= "(/(?:[a-z0-9-._~!$&'()*+,;=:@/]|%[0-9a-f]{2})*)?";
  427. $r .= "|";
  428. $r .= "(/?";
  429. $r .= "(?:[a-z0-9-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+";
  430. $r .= "(?:[a-z0-9-._~!$&'()*+,;=:@\/]|%[0-9a-f]{2})*";
  431. $r .= ")?";
  432. $r .= ")";
  433. $r .= "(?:\?((?:[a-z0-9-._~!$&'()*+,;=:\/?@]|%[0-9a-f]{2})*))?";
  434. $r .= "(?:#((?:[a-z0-9-._~!$&'()*+,;=:\/?@]|%[0-9a-f]{2})*))?";
  435. preg_match("`$r`i", $url, $match);
  436. $parts = array(
  437. "scheme"=>'',
  438. "userinfo"=>'',
  439. "authority"=>'',
  440. "host"=> '',
  441. "port"=>'',
  442. "path"=>'',
  443. "query"=>'',
  444. "fragment"=>'');
  445. switch (count ($match)) {
  446. case 10: $parts['fragment'] = $match[9];
  447. case 9: $parts['query'] = $match[8];
  448. case 8: $parts['path'] = $match[7];
  449. case 7: $parts['path'] = $match[6] . $parts['path'];
  450. case 6: $parts['port'] = $match[5];
  451. case 5: $parts['host'] = $match[3]?"[".$match[3]."]":$match[4];
  452. case 4: $parts['userinfo'] = $match[2];
  453. case 3: $parts['scheme'] = $match[1];
  454. }
  455. $parts['authority'] = ($parts['userinfo']?$parts['userinfo']."@":"").
  456. $parts['host'].
  457. ($parts['port']?":".$parts['port']:"");
  458. return $parts;
  459. }
  460. ?>
  461.  
  462. When using the url
  463.  
  464. /* line too long for this site's comment handler */
  465. "foo://username:password@[2001:4860:0:2001::68]:8042".
  466. "/over/there/index.dtb;type=animal?name=ferret#nose"
  467.  
  468. The original would return
  469.  
  470. Array
  471. (
  472. [scheme] => foo
  473. [userinfo] => username:password
  474. [authority] => username:password@
  475. [host] =>
  476. [port] =>
  477. [path] =>
  478. [query] =>
  479. [fragment] =>
  480. )
  481.  
  482. The new one returns
  483.  
  484. Array
  485. (
  486. [scheme] => foo
  487. [userinfo] => username:password
  488. [authority] => username:password@[2001:4860:0:2001::68]:8042
  489. [host] => [2001:4860:0:2001::68]
  490. [port] => 8042
  491. [path] => /over/there/index.dtb;type=animal
  492. [query] => name=ferret
  493. [fragment] => nose
  494. )
  495.  
  496. All of the other examples FredLudd used below still work exactly the same.
  497. up
  498. down
  499. 1
  500. solenoid at example dot com ¶
  501. 6 years ago
  502. Here's a piece of code that modifies, replaces or removes the url query. This can typically used in paging situations where there are more parameters than the page.
  503.  
  504. <?php
  505. function modify_url($mod)
  506. {
  507. $url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  508. $query = explode("&", $_SERVER['QUERY_STRING']);
  509. // modify/delete data
  510. foreach($query as $q)
  511. {
  512. list($key, $value) = explode("=", $q);
  513. if(array_key_exists($key, $mod))
  514. {
  515. if($mod[$key])
  516. {
  517. $url = preg_replace('/'.$key.'='.$value.'/', $key.'='.$mod[$key], $url);
  518. }
  519. else
  520. {
  521. $url = preg_replace('/&?'.$key.'='.$value.'/', '', $url);
  522. }
  523. }
  524. }
  525. // add new data
  526. foreach($mod as $key => $value)
  527. {
  528. if($value && !preg_match('/'.$key.'=/', $url))
  529. {
  530. $url .= '&'.$key.'='.$value;
  531. }
  532. }
  533. return $url;
  534. }
  535.  
  536. // page url: "http://www.example.com/page.php?p=5&show=list&style=23"
  537.  
  538. $url = modify_url(array('p' => 4, 'show' => 'column'));
  539.  
  540. // $url = "http://www.example.com/page.php?p=4&show=column&style=23"
  541. ?>
  542. up
  543. down
  544. 1
  545. need_sunny at yahoo dot com ¶
  546. 7 years ago
  547. Thanks to xellisx for his parse_query function. I used it in one of my projects and it works well. But it has an error. I fixed the error and improved it a little bit. Here is my version of it:
  548.  
  549. <?php
  550. // Originally written by xellisx
  551. function parse_query($var)
  552. {
  553. /**
  554. * Use this function to parse out the query array element from
  555. * the output of parse_url().
  556. */
  557. $var = parse_url($var, PHP_URL_QUERY);
  558. $var = html_entity_decode($var);
  559. $var = explode('&', $var);
  560. $arr = array();
  561.  
  562. foreach($var as $val)
  563. {
  564. $x = explode('=', $val);
  565. $arr[$x[0]] = $x[1];
  566. }
  567. unset($val, $x, $var);
  568. return $arr;
  569. }
  570. ?>
  571.  
  572. At the first line there was parse_query($val), I made it $var. It used to return a null array before this fix.
  573.  
  574. I have added the parse_url line. So now the function will only focus in the query part, not the whole URL. This is useful if something like below is done:
  575. <?php
  576. $my_GET = parse_query($_SERVER['REQUEST_URI']);
  577. ?>
  578. up
  579. down
  580. 2
  581. nirazuelos at gmail dot com ¶
  582. 7 years ago
  583. Hello, for some odd reason, parse_url returns the host (ex. example.com) as the path when no scheme is provided in the input url. So I've written a quick function to get the real host:
  584.  
  585. <?php
  586. function getHost($Address) {
  587. $parseUrl = parse_url(trim($Address));
  588. return trim($parseUrl[host] ? $parseUrl[host] : array_shift(explode('/', $parseUrl[path], 2)));
  589. }
  590.  
  591. getHost("example.com"); // Gives example.com
  592. getHost("http://example.com"); // Gives example.com
  593. getHost("www.example.com"); // Gives www.example.com
  594. getHost("http://example.com/xyz"); // Gives example.com
  595. ?>
  596.  
  597. You could try anything! It gives the host (including the subdomain if exists).
  598.  
  599. Hope it helped you.
  600. up
  601. down
  602. 1
  603. xellisx ¶
  604. 8 years ago
  605. I need to parse out the query string from the referrer, so I created this function.
  606.  
  607. <?php
  608. function parse_query($val)
  609. {
  610. /**
  611. * Use this function to parse out the query array element from
  612. * the output of parse_url().
  613. */
  614. $var = html_entity_decode($var);
  615. $var = explode('&', $var);
  616. $arr = array();
  617.  
  618. foreach($var as $val)
  619. {
  620. $x = explode('=', $val);
  621. $arr[$x[0]] = $x[1];
  622. }
  623. unset($val, $x, $var);
  624. return $arr;
  625. }
  626. ?>
  627. up
  628. down
  629. 1
  630. mpyw ¶
  631. 3 months ago
  632. Yet another URL builder implementation:
  633.  
  634. <?php
  635. function build_url(array $elements)
  636. {
  637. $e = $elements;
  638. return
  639. (isset($e['host']) ? (
  640. (isset($e['scheme']) ? "$e[scheme]://" : '//') .
  641. (isset($e['user']) ? $e['user'] . (isset($e['pass']) ? ":$e[pass]" : '') . '@' : '') .
  642. $e['host'] .
  643. (isset($e['port']) ? ":$e[port]" : '')
  644. ) : '') .
  645. (isset($e['path']) ? $e['path'] : '/') .
  646. (isset($e['query']) ? '?' . (is_array($e['query']) ? http_build_query($e['query'], '', '&') : $e['query']) : '') .
  647. (isset($e['fragment']) ? "#$e[fragment]" : '')
  648. ;
  649. }
  650. ?>
  651.  
  652. For convenience, you can pass $elements['query'] as array.
  653.  
  654. Example:
  655.  
  656. <?php
  657. $elements = [
  658. "host" => "example.com",
  659. "user" => "root",
  660. "pass" => "stupid",
  661. "path" => "/x/y/z",
  662. "query" => [
  663. "a" => "b",
  664. "c" => "d",
  665. ],
  666. ];
  667. echo build_url($elements);
  668. ?>
  669.  
  670. will output
  671.  
  672. //root:stupid@example.com/x/y/z?a=b&c=d
  673. up
  674. down
  675. 0
  676. Anonymous ¶
  677. 16 days ago
  678. Here is an update to the glue_url() function.
  679.  
  680. It can now handle relative URLs if only 'path' is provided.
  681.  
  682. <?php
  683. function glue_url($parsed) {
  684. if (!is_array($parsed)) {
  685. return false;
  686. }
  687.  
  688. $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
  689. $uri .= isset($parsed['user']) ? $parsed['user'].(isset($parsed['pass']) ? ':'.$parsed['pass'] : '').'@' : '';
  690. $uri .= isset($parsed['host']) ? $parsed['host'] : '';
  691. $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
  692.  
  693. if (isset($parsed['path'])) {
  694. $uri .= (substr($parsed['path'], 0, 1) == '/') ?
  695. $parsed['path'] : ((!empty($uri) ? '/' : '' ) . $parsed['path']);
  696. }
  697.  
  698. $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
  699. $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
  700.  
  701. return $uri;
  702. }
  703. ?>
  704. up
  705. down
  706. http://www.e-consulting.ma/
  707. up
  708. down
  709. 0
  710. wrdshaan at gmail dot com ¶
  711. 19 days ago
  712. Here is an update to the glue_url() function.
  713.  
  714. It can now handle relative URLs if only 'path' is provided.
  715.  
  716. <?php
  717. function glue_url($parsed) {
  718. if (!is_array($parsed)) {
  719. return false;
  720. }
  721.  
  722. $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
  723. $uri .= isset($parsed['user']) ? $parsed['user'].(isset($parsed['pass']) ? ':'.$parsed['pass'] : '').'@' : '';
  724. $uri .= isset($parsed['host']) ? $parsed['host'] : '';
  725. $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
  726.  
  727. if (isset($parsed['path'])) {
  728. $uri .= (substr($parsed['path'], 0, 1) == '/') ?
  729. $parsed['path'] : ((!empty($uri) ? '/' : '' ) . $parsed['path']);
  730. }
  731.  
  732. $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
  733. $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
  734.  
  735. return $uri;
  736. }
  737. ?>
  738. up
  739. down
  740. https://forum.wrdshan.com/
  741. up
  742. down
  743. 0
  744. Anonymous ¶
  745. 6 months ago
  746. Here is an update to the glue_url() function.
  747.  
  748. It can now handle relative URLs if only 'path' is provided.
  749.  
  750. <?php
  751. function glue_url($parsed) {
  752. if (!is_array($parsed)) {
  753. return false;
  754. }
  755.  
  756. $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
  757. $uri .= isset($parsed['user']) ? $parsed['user'].(isset($parsed['pass']) ? ':'.$parsed['pass'] : '').'@' : '';
  758. $uri .= isset($parsed['host']) ? $parsed['host'] : '';
  759. $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
  760.  
  761. if (isset($parsed['path'])) {
  762. $uri .= (substr($parsed['path'], 0, 1) == '/') ?
  763. $parsed['path'] : ((!empty($uri) ? '/' : '' ) . $parsed['path']);
  764. }
  765.  
  766. $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
  767. $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
  768.  
  769. return $uri;
  770. }
  771. ?>
  772. up
  773. down
  774. http://forum.el-wlid.com
  775. up
  776. down
  777. 0
  778. mys5droid at gmail dot com ¶
  779. 10 months ago
  780. I have coded a function which converts relative URL to absolute URL for a project of mine. Considering I could not find it elsewhere, I figured I would post it here.
  781.  
  782. The following function takes in 2 parameters, the first parameter is the URL you want to convert from relative to absolute, and the second parameter is a sample of the absolute URL.
  783.  
  784. Currently it does not resolve '../' in the URL, only because I do not need it. Most webservers will resolve this for you. If you want it to resolve the '../' in the path, it just takes minor modifications.
  785.  
  786. <?php
  787.  
  788. function relativeToAbsolute($inurl, $absolute) {
  789. // Get all parts so not getting them multiple times :)
  790. $absolute_parts = parse_url($absolute);
  791. // Test if URL is already absolute (contains host, or begins with '/')
  792. if ( (strpos($inurl, $absolute_parts['host']) == false) ) {
  793. // Define $tmpurlprefix to prevent errors below
  794. $tmpurlprefix = "";
  795. // Formulate URL prefix (SCHEME)
  796. if (!(empty($absolute_parts['scheme']))) {
  797. // Add scheme to tmpurlprefix
  798. $tmpurlprefix .= $absolute_parts['scheme'] . "://";
  799. }
  800. // Formulate URL prefix (USER, PASS)
  801. if ((!(empty($absolute_parts['user']))) and (!(empty($absolute_parts['pass'])))) {
  802. // Add user:port to tmpurlprefix
  803. $tmpurlprefix .= $absolute_parts['user'] . ":" . $absolute_parts['pass'] . "@";
  804. }
  805. // Formulate URL prefix (HOST, PORT)
  806. if (!(empty($absolute_parts['host']))) {
  807. // Add host to tmpurlprefix
  808. $tmpurlprefix .= $absolute_parts['host'];
  809. // Check for a port, add if exists
  810. if (!(empty($absolute_parts['port']))) {
  811. // Add port to tmpurlprefix
  812. $tmpurlprefix .= ":" . $absolute_parts['port'];
  813. }
  814. }
  815. // Formulate URL prefix (PATH) and only add it if the path to image does not include ./
  816. if ( (!(empty($absolute_parts['path']))) and (substr($inurl, 0, 1) != '/') ) {
  817. // Get path parts
  818. $path_parts = pathinfo($absolute_parts['path']);
  819. // Add path to tmpurlprefix
  820. $tmpurlprefix .= $path_parts['dirname'];
  821. $tmpurlprefix .= "/";
  822. }
  823. else {
  824. $tmpurlprefix .= "/";
  825. }
  826. // Lets remove the '/'
  827. if (substr($inurl, 0, 1) == '/') { $inurl = substr($inurl, 1); }
  828. // Lets remove the './'
  829. if (substr($inurl, 0, 2) == './') { $inurl = substr($inurl, 2); }
  830. return $tmpurlprefix . $inurl;
  831. }
  832. else {
  833. // Path is already absolute. Return it :)
  834. return $inurl;
  835. }
  836. }
  837.  
  838. // Define a sample absolute URL
  839. $absolute = "http://" . "user:pass@example.com:8080/path/to/index.html"; // Just evading php.net spam filter, not sure how example.com is spam...
  840.  
  841. /* EXAMPLE 1 */
  842. echo relativeToAbsolute($absolute, $absolute) . "\n";
  843. /* EXAMPLE 2 */
  844. echo relativeToAbsolute("img.gif", $absolute) . "\n";
  845. /* EXAMPLE 3 */
  846. echo relativeToAbsolute("/img.gif", $absolute) . "\n";
  847. /* EXAMPLE 4 */
  848. echo relativeToAbsolute("./img.gif", $absolute) . "\n";
  849. /* EXAMPLE 5 */
  850. echo relativeToAbsolute("../img.gif", $absolute) . "\n";
  851. /* EXAMPLE 6 */
  852. echo relativeToAbsolute("images/img.gif", $absolute) . "\n";
  853. /* EXAMPLE 7 */
  854. echo relativeToAbsolute("/images/img.gif", $absolute) . "\n";
  855. /* EXAMPLE 8 */
  856. echo relativeToAbsolute("./images/img.gif", $absolute) . "\n";
  857. /* EXAMPLE 9 */
  858. echo relativeToAbsolute("../images/img.gif", $absolute) . "\n";
  859.  
  860. ?>
  861.  
  862. OUTPUTS:
  863. http :// user:pass@example.com:8080/path/to/index.html
  864. http :// user:pass@example.com:8080/path/to/img.gif
  865. http :// user:pass@example.com:8080/img.gif
  866. http :// user:pass@example.com:8080/path/to/img.gif
  867. http :// user:pass@example.com:8080/path/to/../img.gif
  868. http :// user:pass@example.com:8080/path/to/images/img.gif
  869. http :// user:pass@example.com:8080/images/img.gif
  870. http :// user:pass@example.com:8080/path/to/images/img.gif
  871. http :// user:pass@example.com:8080/path/to/../images/img.gif
  872.  
  873. Sorry if the above code is not your style, or if you see it as "messy" or you think there is a better way to do it. I removed as much of the white space as possible.
  874.  
  875. Improvements are welcome :)
  876. up
  877. down
  878. 0
  879. mostafa at alfehrest dot org ¶
  880. 1 year ago
  881. This function will attempt to parse relative URLs but relaying on it can produce unexpected behavior that can cause some hard to track bugs. (The following results are obtained from PHP 5.5.19)
  882.  
  883. Attempting to parse a url like this
  884. http://example.com/entities/GOA:98/?search=8989157d1f22
  885. Correctly produces
  886. <?php
  887. array (
  888. 'scheme' => 'http',
  889. 'host' => 'example.com',
  890. 'path' => '/entities/GOA:98/',
  891. 'query' => 'search=8989157d1f22',
  892. );
  893. ?>
  894.  
  895. However, Attempting to parse the relative URL
  896. entities/GOA:98/?search=8989157d1f22
  897. <?php
  898. array (
  899. 'host' => 'entities',
  900. 'port' => 98,
  901. 'path' => '/GOA:98/',
  902. 'query' => 'search=8989157d1f22',
  903. )
  904. ?>
  905. If I change :98 to :A98 parse_url parses the URL correctly as
  906. <?php
  907. array (
  908. 'path' => 'entities/GOA:A98/',
  909. 'query' => 'search=8989157d1f22',
  910. )
  911. ?>
  912. Bottom line, Avoid using parse_url for relative urls unless you have tested the expected input and you know parse_url will handle them well.
  913. up
  914. down
  915. 0
  916. therselman at gmail ¶
  917. 5 years ago
  918. UTF-8 aware parse_url() replacement.
  919.  
  920. I've realized that even though UTF-8 characters are not allowed in URL's, I have to work with a lot of them and parse_url() will break.
  921.  
  922. Based largely on the work of "mallluhuct at gmail dot com", I added parse_url() compatible "named values" which makes the array values a lot easier to work with (instead of just numbers). I also implemented detection of port, username/password and a back-reference to better detect URL's like this: //en.wikipedia.com
  923. ... which, although is technically an invalid URL, it's used extensively on sites like wikipedia in the href of anchor tags where it's valid in browsers (one of the types of URL's you have to support when crawling pages). This will be accurately detected as the host name instead of "path" as in all other examples.
  924.  
  925. I will submit my complete function (instead of just the RegExp) which is an almost "drop-in" replacement for parse_url(). It returns a cleaned up array (or false) with values compatible with parse_url(). I could have told the preg_match() not to store the unused extra values, but it would complicate the RegExp and make it more difficult to read, understand and extend. The key to detecting UTF-8 characters is the use of the "u" parameter in preg_match().
  926.  
  927. <?php
  928. function parse_utf8_url($url)
  929. {
  930. static $keys = array('scheme'=>0,'user'=>0,'pass'=>0,'host'=>0,'port'=>0,'path'=>0,'query'=>0,'fragment'=>0);
  931. if (is_string($url) && preg_match(
  932. '~^((?P<scheme>[^:/?#]+):(//))?((\\3|//)?(?:(?P<user>[^:]+):(?P<pass>[^@]+)@)?(?P<host>[^/?:#]*))(:(?P<port>\\d+))?' .
  933. '(?P<path>[^?#]*)(\\?(?P<query>[^#]*))?(#(?P<fragment>.*))?~u', $url, $matches))
  934. {
  935. foreach ($matches as $key => $value)
  936. if (!isset($keys[$key]) || empty($value))
  937. unset($matches[$key]);
  938. return $matches;
  939. }
  940. return false;
  941. }
  942. ?>
  943.  
  944. UTF-8 URL's can/should be "normalized" after extraction with this function.
  945. up
  946. down
  947. 0
  948. gustavo dot andriuolo at vulcabras dot com dot ar ¶
  949. 5 years ago
  950. Here's a method to get the REAL name of a domain. This return just the domain name, not the rest. First check if is not an IP, then return the name:
  951.  
  952. <?php
  953. function esip($ip_addr)
  954. {
  955. //first of all the format of the ip address is matched
  956. if(preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/",$ip_addr))
  957. {
  958. //now all the intger values are separated
  959. $parts=explode(".",$ip_addr);
  960. //now we need to check each part can range from 0-255
  961. foreach($parts as $ip_parts)
  962. {
  963. if(intval($ip_parts)>255 || intval($ip_parts)<0)
  964. return FALSE; //if number is not within range of 0-255
  965. }
  966. return TRUE;
  967. }
  968. else
  969. return FALSE; //if format of ip address doesn't matches
  970. }
  971.  
  972.  
  973.  
  974. function domain($domainb)
  975. {
  976. $bits = explode('/', $domainb);
  977. if ($bits[0]=='http:' || $bits[0]=='https:')
  978. {
  979. $domainb= $bits[2];
  980. } else {
  981. $domainb= $bits[0];
  982. }
  983. unset($bits);
  984. $bits = explode('.', $domainb);
  985. $idz=count($bits);
  986. $idz-=3;
  987. if (strlen($bits[($idz+2)])==2) {
  988. $url=$bits[$idz].'.'.$bits[($idz+1)].'.'.$bits[($idz+2)];
  989. } else if (strlen($bits[($idz+2)])==0) {
  990. $url=$bits[($idz)].'.'.$bits[($idz+1)];
  991. } else {
  992. $url=$bits[($idz+1)].'.'.$bits[($idz+2)];
  993. }
  994. return $url;
  995. }
  996.  
  997. $address='clients1.sub3.google.co.uk';
  998. $parsed_url = parse_url($address);
  999. $check = esip($parsed_url['host']);
  1000. $host = $parsed_url['host'];
  1001. if ($check == FALSE){
  1002. if ($host != ""){
  1003. $host = domain($host);
  1004. }else{
  1005. $host = domain($address);
  1006. }
  1007. }
  1008. echo $host;
  1009. ?>
  1010. This return: google.co.uk
  1011. 'http://sub1.sub2.sub3.example.com:443';
  1012. return: example.com
  1013. 'example.com';
  1014. return: example.com
  1015.  
  1016. Many times parse_url return nothing when domain is google.com only for example.
  1017.  
  1018. Now, google.com, or google.co.uk will return the same.
  1019.  
  1020. Maybe is a little dirty, but works well for me, i use it to group internet access log from squid.
  1021.  
  1022. Regards.
  1023. up
  1024. down
  1025. 0
  1026. Simon D ¶
  1027. 5 years ago
  1028. To get the params (url query) as Associative array, use this function:
  1029.  
  1030. <?php
  1031. /**
  1032. * Returns the url query as associative array
  1033. *
  1034. * @param string query
  1035. * @return array params
  1036. */
  1037. function convertUrlQuery($query) {
  1038. $queryParts = explode('&', $query);
  1039.  
  1040. $params = array();
  1041. foreach ($queryParts as $param) {
  1042. $item = explode('=', $param);
  1043. $params[$item[0]] = $item[1];
  1044. }
  1045.  
  1046. return $params;
  1047. }
  1048. ?>
  1049. up
  1050. down
  1051. 0
  1052. Egor Chernodarov ¶
  1053. 5 years ago
  1054. Noticed the following differences in error handling:
  1055.  
  1056. <?php
  1057. print_r(parse_url('ftp://user:password@host:port'));
  1058. ?>
  1059.  
  1060. In PHP 5.2.6 returns:
  1061. Array
  1062. (
  1063. [scheme] => ftp
  1064. [host] => host
  1065. [user] => user
  1066. [pass] => password
  1067. )
  1068.  
  1069. port is just skipped.
  1070.  
  1071. But in PHP 5.3.6 returns NULL without any warnings.
  1072. up
  1073. down
  1074. 0
  1075. ap dot public1 at gmail dot com ¶
  1076. 7 years ago
  1077. Simple static library that allows easy manipulation of url parameters:
  1078.  
  1079. <?php
  1080. /**
  1081. * File provides easy way to manipulate url parameters
  1082. * @author Alexander Podgorny
  1083. */
  1084.  
  1085. class Url {
  1086. /**
  1087. * Splits url into array of it's pieces as follows:
  1088. * [scheme]://[user]:[pass]@[host]/[path]?[query]#[fragment]
  1089. * In addition it adds 'query_params' key which contains array of
  1090. * url-decoded key-value pairs
  1091. *
  1092. * @param String $sUrl Url
  1093. * @return Array Parsed url pieces
  1094. */
  1095. public static function explode($sUrl) {
  1096. $aUrl = parse_url($sUrl);
  1097. $aUrl['query_params'] = array();
  1098. $aPairs = explode('&', $aUrl['query']);
  1099. DU::show($aPairs);
  1100. foreach($aPairs as $sPair) {
  1101. if (trim($sPair) == '') { continue; }
  1102. list($sKey, $sValue) = explode('=', $sPair);
  1103. $aUrl['query_params'][$sKey] = urldecode($sValue);
  1104. }
  1105. return $aUrl;
  1106. }
  1107. /**
  1108. * Compiles url out of array of it's pieces (returned by explodeUrl)
  1109. * 'query' is ignored if 'query_params' is present
  1110. *
  1111. * @param Array $aUrl Array of url pieces
  1112. */
  1113. public static function implode($aUrl) {
  1114. //[scheme]://[user]:[pass]@[host]/[path]?[query]#[fragment]
  1115.  
  1116. $sQuery = '';
  1117.  
  1118. // Compile query
  1119. if (isset($aUrl['query_params']) && is_array($aUrl['query_params'])) {
  1120. $aPairs = array();
  1121. foreach ($aUrl['query_params'] as $sKey=>$sValue) {
  1122. $aPairs[] = $sKey.'='.urlencode($sValue);
  1123. }
  1124. $sQuery = implode('&', $aPairs);
  1125. } else {
  1126. $sQuery = $aUrl['query'];
  1127. }
  1128.  
  1129. // Compile url
  1130. $sUrl =
  1131. $aUrl['scheme'] . '://' . (
  1132. isset($aUrl['user']) && $aUrl['user'] != '' && isset($aUrl['pass'])
  1133. ? $aUrl['user'] . ':' . $aUrl['pass'] . '@'
  1134. : ''
  1135. ) .
  1136. $aUrl['host'] . (
  1137. isset($aUrl['path']) && $aUrl['path'] != ''
  1138. ? $aUrl['path']
  1139. : ''
  1140. ) . (
  1141. $sQuery != ''
  1142. ? '?' . $sQuery
  1143. : ''
  1144. ) . (
  1145. isset($aUrl['fragment']) && $aUrl['fragment'] != ''
  1146. ? '#' . $aUrl['fragment']
  1147. : ''
  1148. );
  1149. return $sUrl;
  1150. }
  1151. /**
  1152. * Parses url and returns array of key-value pairs of url params
  1153. *
  1154. * @param String $sUrl
  1155. * @return Array
  1156. */
  1157. public static function getParams($sUrl) {
  1158. $aUrl = self::explode($sUrl);
  1159. return $aUrl['query_params'];
  1160. }
  1161. /**
  1162. * Removes existing url params and sets them to those specified in $aParams
  1163. *
  1164. * @param String $sUrl Url
  1165. * @param Array $aParams Array of Key-Value pairs to set url params to
  1166. * @return String Newly compiled url
  1167. */
  1168. public static function setParams($sUrl, $aParams) {
  1169. $aUrl = self::explode($sUrl);
  1170. $aUrl['query'] = '';
  1171. $aUrl['query_params'] = $aParams;
  1172. return self::implode($aUrl);
  1173. }
  1174. /**
  1175. * Updates values of existing url params and/or adds (if not set) those specified in $aParams
  1176. *
  1177. * @param String $sUrl Url
  1178. * @param Array $aParams Array of Key-Value pairs to set url params to
  1179. * @return String Newly compiled url
  1180. */
  1181. public static function updateParams($sUrl, $aParams) {
  1182. $aUrl = self::explode($sUrl);
  1183. $aUrl['query'] = '';
  1184. $aUrl['query_params'] = array_merge($aUrl['query_params'], $aParams);
  1185. return self::implode($aUrl);
  1186. }
  1187. }
  1188.  
  1189. ?>
  1190. up
  1191. down
  1192. 0
  1193. pbcomm at gmail dot com ¶
  1194. 8 years ago
  1195. Modification to the code from:
  1196. theoriginalmarksimpson at gmail dot com
  1197.  
  1198. Change:
  1199. $r .= "(?:(?P<login>\w+):(?P<pass>\w+)@)?";
  1200.  
  1201. Replace with:
  1202. $r .= "(?:(?P<login>\w+):?(?P<pass>\w+)?@)?";
  1203.  
  1204. This will cover the case the only username is present in the url:
  1205.  
  1206. http://username@subdomain.domain.com/index.php?arg1=test#anchor
  1207. up
  1208. down
  1209. 0
  1210. vdklah at hotmail dot com ¶
  1211. 8 years ago
  1212. Some example that determines the URL port.
  1213. When port not specified, it derives it from the scheme.
  1214.  
  1215. <?php
  1216. function getUrlPort( $urlInfo )
  1217. {
  1218. if( isset($urlInfo['port']) ) {
  1219. $port = $urlInfo['port'];
  1220. } else { // no port specified; get default port
  1221. if (isset($urlInfo['scheme']) ) {
  1222. switch( $urlInfo['scheme'] ) {
  1223. case 'http':
  1224. $port = 80; // default for http
  1225. break;
  1226. case 'https':
  1227. $port = 443; // default for https
  1228. break;
  1229. case 'ftp':
  1230. $port = 21; // default for ftp
  1231. break;
  1232. case 'ftps':
  1233. $port = 990; // default for ftps
  1234. break;
  1235. default:
  1236. $port = 0; // error; unsupported scheme
  1237. break;
  1238. }
  1239. } else {
  1240. $port = 0; // error; unknown scheme
  1241. }
  1242. }
  1243. return $port;
  1244. }
  1245.  
  1246. $url = "http://nl3.php.net/manual/en/function.parse-url.php";
  1247. $urlInfo = parse_url( $url );
  1248. $urlPort = getUrlPort( $urlInfo );
  1249. if( $urlPort !== 0 ) {
  1250. print 'Found URL port: '.$urlPort;
  1251. } else {
  1252. print 'ERROR: Could not find port at URL: '.$url;
  1253. }
  1254. ?>
  1255. up
  1256. down
  1257. 0
  1258. nospam at spellingcow dot com ¶
  1259. 8 years ago
  1260. URL's in the query string of a relative URL will cause a problem
  1261.  
  1262. fails:
  1263. /page.php?foo=bar&url=http://www.example.com
  1264.  
  1265. parses:
  1266. http://www.foo.com/page.php?foo=bar&url=http://www.example.com
  1267. up
  1268. down
  1269. 0
  1270. marco panichi ¶
  1271. 8 years ago
  1272. my function catch the url written on the browser by the user and does the same thing of parse_url. but better, I think. I don't like parse_url because it says nothing about elements that it doesn't find in the url. my function instead return an empty string.
  1273.  
  1274. <?php
  1275. function get_url()
  1276. {
  1277. $arr = array();
  1278. $uri = $_SERVER['REQUEST_URI'];
  1279.  
  1280. // query
  1281. $x = array_pad( explode( '?', $uri ), 2, false );
  1282. $arr['query'] = ( $x[1] )? $x[1] : '' ;
  1283.  
  1284. // resource
  1285. $x = array_pad( explode( '/', $x[0] ), 2, false );
  1286. $x_last = array_pop( $x );
  1287. if( strpos( $x_last, '.' ) === false )
  1288. {
  1289. $arr['resource'] = '';
  1290. $x[] = $x_last;
  1291. }
  1292. else
  1293. {
  1294. $arr['resource'] = $x_last;
  1295. }
  1296.  
  1297. // path
  1298. $arr['path'] = implode( '/', $x );
  1299. if( substr( $arr['path'], -1 ) !== '/' ) $arr['path'] .= '/';
  1300.  
  1301. // domain
  1302. $arr['domain'] = $_SERVER['SERVER_NAME'];
  1303.  
  1304. // scheme
  1305. $server_prt = explode( '/', $_SERVER['SERVER_PROTOCOL'] );
  1306. $arr['scheme'] = strtolower( $server_prt[0] );
  1307.  
  1308. // url
  1309. $arr['url'] = $arr['scheme'].'://'.$arr['domain'].$uri;
  1310.  
  1311. return $arr;
  1312. }
  1313. ?>
  1314.  
  1315. PS: I found working with explode is faster than using preg_match (I tryed with getmicrotime function and 'for' cycles).
  1316.  
  1317. PPS: I used array_pad to prevent any notice.
  1318. up
  1319. down
  1320. 0
  1321. andrewtheartist at hotmail dot com ¶
  1322. 8 years ago
  1323. Here's the easiest way to get the URL to the path that your script is in (so not the actual script name itself, just the complete URL to the folder it's in)
  1324.  
  1325. echo "http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
  1326. up
  1327. down
  1328. 0
  1329. to1ne at hotmail dot com ¶
  1330. 8 years ago
  1331. Based on the idea of "jbr at ya-right dot com" have I been working on a new function to parse the url:
  1332.  
  1333. <?php
  1334. function parseUrl($url) {
  1335. $r = "^(?:(?P<scheme>\w+)://)?";
  1336. $r .= "(?:(?P<login>\w+):(?P<pass>\w+)@)?";
  1337. $r .= "(?P<host>(?:(?P<subdomain>[\w\.]+)\.)?" . "(?P<domain>\w+\.(?P<extension>\w+)))";
  1338. $r .= "(?::(?P<port>\d+))?";
  1339. $r .= "(?P<path>[\w/]*/(?P<file>\w+(?:\.\w+)?)?)?";
  1340. $r .= "(?:\?(?P<arg>[\w=&]+))?";
  1341. $r .= "(?:#(?P<anchor>\w+))?";
  1342. $r = "!$r!"; // Delimiters
  1343.  
  1344. preg_match ( $r, $url, $out );
  1345.  
  1346. return $out;
  1347. }
  1348. print_r ( parseUrl ( 'me:you@sub.site.org:29000/pear/validate.html?happy=me&sad=you#url' ) );
  1349. ?>
  1350.  
  1351. This returns:
  1352. Array
  1353. (
  1354. [0] => me:you@sub.site.org:29000/pear/validate.html?happy=me&sad=you#url
  1355. [scheme] =>
  1356. [1] =>
  1357. [login] => me
  1358. [2] => me
  1359. [pass] => you
  1360. [3] => you
  1361. [host] => sub.site.org
  1362. [4] => sub.site.org
  1363. [subdomain] => sub
  1364. [5] => sub
  1365. [domain] => site.org
  1366. [6] => site.org
  1367. [extension] => org
  1368. [7] => org
  1369. [port] => 29000
  1370. [8] => 29000
  1371. [path] => /pear/validate.html
  1372. [9] => /pear/validate.html
  1373. [file] => validate.html
  1374. [10] => validate.html
  1375. [arg] => happy=me&sad=you
  1376. [11] => happy=me&sad=you
  1377. [anchor] => url
  1378. [12] => url
  1379. )
  1380.  
  1381. So both named and numbered array keys are possible.
  1382.  
  1383. It's quite advanced, but I think it works in any case... Let me know if it doesn't...
  1384. up
  1385. down
  1386. 0
  1387. Nick Smith ¶
  1388. 9 years ago
  1389. Note that older versions of PHP (e.g., 4.1) returned an blank string as the path for URLs without any path, such as http://www.php.net
  1390.  
  1391. However more recent versions of PHP (e.g., 4.4.7) don't set the path element in the array, so old code will get a PHP warning about an undefined index.
  1392. up
  1393. down
  1394. 0
  1395. spam at paulisageek dot com ¶
  1396. 9 years ago
  1397. In reply to adrian,
  1398.  
  1399. Thank you very much for your function. There is a small issue with your relative protocol function. You need to remove the // when making the url the path. Here is the new function.
  1400.  
  1401. function resolve_url($base, $url) {
  1402. if (!strlen($base)) return $url;
  1403. // Step 2
  1404. if (!strlen($url)) return $base;
  1405. // Step 3
  1406. if (preg_match('!^[a-z]+:!i', $url)) return $url;
  1407. $base = parse_url($base);
  1408. if ($url{0} == "#") {
  1409. // Step 2 (fragment)
  1410. $base['fragment'] = substr($url, 1);
  1411. return unparse_url($base);
  1412. }
  1413. unset($base['fragment']);
  1414. unset($base['query']);
  1415. if (substr($url, 0, 2) == "//") {
  1416. // Step 4
  1417. return unparse_url(array(
  1418. 'scheme'=>$base['scheme'],
  1419. 'path'=>substr($url,2),
  1420. ));
  1421. } else if ($url{0} == "/") {
  1422. // Step 5
  1423. $base['path'] = $url;
  1424. } else {
  1425. // Step 6
  1426. $path = explode('/', $base['path']);
  1427. $url_path = explode('/', $url);
  1428. // Step 6a: drop file from base
  1429. array_pop($path);
  1430. // Step 6b, 6c, 6e: append url while removing "." and ".." from
  1431. // the directory portion
  1432. $end = array_pop($url_path);
  1433. foreach ($url_path as $segment) {
  1434. if ($segment == '.') {
  1435. // skip
  1436. } else if ($segment == '..' && $path && $path[sizeof($path)-1] != '..') {
  1437. array_pop($path);
  1438. } else {
  1439. $path[] = $segment;
  1440. }
  1441. }
  1442. // Step 6d, 6f: remove "." and ".." from file portion
  1443. if ($end == '.') {
  1444. $path[] = '';
  1445. } else if ($end == '..' && $path && $path[sizeof($path)-1] != '..') {
  1446. $path[sizeof($path)-1] = '';
  1447. } else {
  1448. $path[] = $end;
  1449. }
  1450. // Step 6h
  1451. $base['path'] = join('/', $path);
  1452.  
  1453. }
  1454. // Step 7
  1455. return unparse_url($base);
  1456. }
  1457. up
  1458. down
  1459. 0
  1460. christian at resource-it dot dk ¶
  1461. 9 years ago
  1462. I searched for an implementation of rfc3986, which is a newer version of rfc 2392. I may find it here : <http://www.chrsen.dk/fundanemt/files/scripter/php/misc/rfc3986.php> - read the rfc at <http://rfc.net/rfc3986.html>
  1463. up
  1464. down
  1465. 0
  1466. adrian-php at sixfingeredman dot net ¶
  1467. 9 years ago
  1468. Here's a function which implements resolving a relative URL according to RFC 2396 section 5.2. No doubt there are more efficient implementations, but this one tries to remain close to the standard for clarity. It relies on a function called "unparse_url" to implement section 7, left as an exercise for the reader (or you can substitute the "glue_url" function posted earlier).
  1469.  
  1470. <?php
  1471. /**
  1472. * Resolve a URL relative to a base path. This happens to work with POSIX
  1473. * filenames as well. This is based on RFC 2396 section 5.2.
  1474. */
  1475. function resolve_url($base, $url) {
  1476. if (!strlen($base)) return $url;
  1477. // Step 2
  1478. if (!strlen($url)) return $base;
  1479. // Step 3
  1480. if (preg_match('!^[a-z]+:!i', $url)) return $url;
  1481. $base = parse_url($base);
  1482. if ($url{0} == "#") {
  1483. // Step 2 (fragment)
  1484. $base['fragment'] = substr($url, 1);
  1485. return unparse_url($base);
  1486. }
  1487. unset($base['fragment']);
  1488. unset($base['query']);
  1489. if (substr($url, 0, 2) == "//") {
  1490. // Step 4
  1491. return unparse_url(array(
  1492. 'scheme'=>$base['scheme'],
  1493. 'path'=>$url,
  1494. ));
  1495. } else if ($url{0} == "/") {
  1496. // Step 5
  1497. $base['path'] = $url;
  1498. } else {
  1499. // Step 6
  1500. $path = explode('/', $base['path']);
  1501. $url_path = explode('/', $url);
  1502. // Step 6a: drop file from base
  1503. array_pop($path);
  1504. // Step 6b, 6c, 6e: append url while removing "." and ".." from
  1505. // the directory portion
  1506. $end = array_pop($url_path);
  1507. foreach ($url_path as $segment) {
  1508. if ($segment == '.') {
  1509. // skip
  1510. } else if ($segment == '..' && $path && $path[sizeof($path)-1] != '..') {
  1511. array_pop($path);
  1512. } else {
  1513. $path[] = $segment;
  1514. }
  1515. }
  1516. // Step 6d, 6f: remove "." and ".." from file portion
  1517. if ($end == '.') {
  1518. $path[] = '';
  1519. } else if ($end == '..' && $path && $path[sizeof($path)-1] != '..') {
  1520. $path[sizeof($path)-1] = '';
  1521. } else {
  1522. $path[] = $end;
  1523. }
  1524. // Step 6h
  1525. $base['path'] = join('/', $path);
  1526.  
  1527. }
  1528. // Step 7
  1529. return unparse_url($base);
  1530. }
  1531. ?>
  1532. up
  1533. down
  1534. 0
  1535. Elliott Brueggeman ¶
  1536. 9 years ago
  1537. Note that if you pass this function a url without a scheme (www.php.net, as opposed to http://www.php.net), the function will incorrectly parse the results. In my test case it returned the domain under the ['path'] element and nothing in the ['host'] element.
  1538. up
  1539. down
  1540. -2
  1541. Mark Dobrinic ¶
  1542. 6 years ago
  1543. It seems the host-part strips off the last [:port] off the end of the hostname
  1544.  
  1545. When something is wrong in the actual request, this proves to be the wrong way to do things.
  1546.  
  1547. It would be better to not strip off the [:port], but to keep the string *before* the first [:port] as the hostname.
  1548.  
  1549. Problem with (maybe malformed) provided HTTP_HOST
  1550. hostname:443:443
  1551. that resolved in
  1552. 'host' => 'hostname:443'
  1553.  
  1554. Which gave me problems.
  1555.  
  1556. Solution would be to enforce this yourself, explicitly:
  1557.  
  1558. <?php
  1559. $p = parse_url( $url );
  1560. $host = explode(':', $p['host']);
  1561. $hostname = $host[0];
  1562. ?>
  1563. up
  1564. down
  1565. 0
  1566. alistair at 21degrees dot com dot au ¶
  1567. 10 years ago
  1568. Heres a simple function to add the $component option in for PHP4. Haven't done exhaustive testing, but should work ok.
  1569.  
  1570. <?php
  1571.  
  1572. ## Defines only available in PHP 5, created for PHP4
  1573. if(!defined('PHP_URL_SCHEME')) define('PHP_URL_SCHEME', 1);
  1574. if(!defined('PHP_URL_HOST')) define('PHP_URL_HOST', 2);
  1575. if(!defined('PHP_URL_PORT')) define('PHP_URL_PORT', 3);
  1576. if(!defined('PHP_URL_USER')) define('PHP_URL_USER', 4);
  1577. if(!defined('PHP_URL_PASS')) define('PHP_URL_PASS', 5);
  1578. if(!defined('PHP_URL_PATH')) define('PHP_URL_PATH', 6);
  1579. if(!defined('PHP_URL_QUERY')) define('PHP_URL_QUERY', 7);
  1580. if(!defined('PHP_URL_FRAGMENT')) define('PHP_URL_FRAGMENT', 8);
  1581.  
  1582. function parse_url_compat($url, $component=NULL){
  1583.  
  1584. if(!$component) return parse_url($url);
  1585.  
  1586. ## PHP 5
  1587. if(phpversion() >= 5)
  1588. return parse_url($url, $component);
  1589.  
  1590. ## PHP 4
  1591. $bits = parse_url($url);
  1592.  
  1593. switch($component){
  1594. case PHP_URL_SCHEME: return $bits['scheme'];
  1595. case PHP_URL_HOST: return $bits['host'];
  1596. case PHP_URL_PORT: return $bits['port'];
  1597. case PHP_URL_USER: return $bits['user'];
  1598. case PHP_URL_PASS: return $bits['pass'];
  1599. case PHP_URL_PATH: return $bits['path'];
  1600. case PHP_URL_QUERY: return $bits['query'];
  1601. case PHP_URL_FRAGMENT: return $bits['fragment'];
  1602. }
  1603.  
  1604. }
  1605.  
  1606. ?>
  1607. up
  1608. down
  1609. 0
  1610. TheShadow ¶
  1611. 12 years ago
  1612. You may want to check out the PEAR NET_URL class. It provides easy means to manipulate URL strings.
  1613.  
  1614. http://pear.php.net/package/Net_URL
  1615. up
  1616. down
  1617. -2
  1618. Cool Coyote ¶
  1619. 8 years ago
  1620. based on the "laulibrius at hotmail dot com" function, this work for relatives url only:
  1621.  
  1622. <?php
  1623. function parseUrl($url) {
  1624. $r = "^(?:(?P<path>[\.\w/]*/)?";
  1625. $r .= "(?P<file>\w+(?:\.\w+)?)?)\.(?P<extension>\w+)?";
  1626. $r .= "(?:\?(?P<arg>[\w=&]+))?";
  1627. $r .= "(?:#(?P<anchor>\w+))?";
  1628. $r = "!$r!";
  1629.  
  1630. preg_match ( $r, $url, $out );
  1631. return $out;
  1632. }
  1633.  
  1634. print_r(parseUrl("../test/f.aq.php?p=1&v=blabla#X1"));
  1635.  
  1636. ?>
  1637.  
  1638. returns:
  1639. Array
  1640. (
  1641. [0] => ../test/faq.php?p=1&v=blabla#X1
  1642. [path] => ../test/
  1643. [1] => ../test/
  1644. [file] => faq
  1645. [2] => faq
  1646. [extension] => php
  1647. [3] => php
  1648. [arg] => p=1&v=blabla
  1649. [4] => p=1&v=blabla
  1650. [anchor] => X1
  1651. [5] => X1
  1652. )
  1653. up
  1654. down
  1655. -2
  1656. laulibrius at hotmail dot com ¶
  1657. 8 years ago
  1658. There was one thing missing in the function dropped by "to1ne at hotmail dot com" when i tried it : domain and subdomain couldn't have a dash "-". So i add it in the regexp and the function looks like this now :
  1659.  
  1660. <?php
  1661. function parseUrl($url) {
  1662. $r = "^(?:(?P<scheme>\w+)://)?";
  1663. $r .= "(?:(?P<login>\w+):(?P<pass>\w+)@)?";
  1664. $r .= "(?P<host>(?:(?P<subdomain>[-\w\.]+)\.)?" . "(?P<domain>[-\w]+\.(?P<extension>\w+)))";
  1665. $r .= "(?::(?P<port>\d+))?";
  1666. $r .= "(?P<path>[\w/]*/(?P<file>\w+(?:\.\w+)?)?)?";
  1667. $r .= "(?:\?(?P<arg>[\w=&]+))?";
  1668. $r .= "(?:#(?P<anchor>\w+))?";
  1669. $r = "!$r!"; // Delimiters
  1670.  
  1671. preg_match ( $r, $url, $out );
  1672.  
  1673. return $out;
  1674. }
  1675. ?>
  1676.  
  1677. Btw, thanks for the function, it helps me a lot.
  1678. up
  1679. down
  1680. -2
  1681. Michael Muryn ¶
  1682. 9 years ago
  1683. Another update to the glue_url function: applied the "isset" treatment to $parsed['pass'].
  1684.  
  1685. <?php
  1686. function glue_url($parsed)
  1687. {
  1688. if (!is_array($parsed)) return false;
  1689. $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
  1690. $uri .= isset($parsed['user']) ? $parsed['user'].(isset($parsed['pass']) ? ':'.$parsed['pass'] : '').'@' : '';
  1691. $uri .= isset($parsed['host']) ? $parsed['host'] : '';
  1692. $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
  1693. if(isset($parsed['path']))
  1694. {
  1695. $uri .= (substr($parsed['path'], 0, 1) == '/') ? $parsed['path'] : ('/'.$parsed['path']);
  1696. }
  1697. $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
  1698. $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
  1699. return $uri;
  1700. }
  1701. ?>
  1702. up
  1703. down
  1704. -1
  1705. martin at planio dot com ¶
  1706. 6 years ago
  1707. For those of you sending URLs in HTML emails with a redirect address in the query string, note that Hotmail unescapes / and : characters in the query string. So that breaks the parse_url() function call. Take this as an example:
  1708. href="http://example.com/redirect?url=http%3A%2F%2Fplanio.com"
  1709. Hotmail will transform it to this:
  1710. href="http://example.com/redirect?url=http://planio.com"
  1711.  
  1712. The solution is to be preventive before the call to parse_url():
  1713. <?php
  1714. $q_index = strpos($uri, '?');
  1715. if ($q_index !== FALSE &&
  1716. (strpos($uri, ':', $q_index) !== FALSE || strpos($uri, '/', $q_index) !== FALSE)) {
  1717. $begin = substr($uri, 0, $q_index);
  1718. $end = substr($uri, $q_index, strlen($uri)-$q_index);
  1719. $end = str_replace('/', '%2F', $end);
  1720. $end = str_replace(':', '%3A', $end);
  1721. $uri = $begin.$end;
  1722. }
  1723. ?>
  1724. up
  1725. down
  1726. -1
  1727. webmaster at bigbirdmedia dot com ¶
  1728. 3 years ago
  1729. A simple function using "parse_url" to find the base URL of the given link.
  1730.  
  1731. <?php
  1732.  
  1733. function getPrimaryDomain($url) {
  1734. $tld = parse_url($url,PHP_URL_HOST);
  1735. $tldArray = explode(".",$tld);
  1736.  
  1737. // COUNTS THE POSITION IN THE ARRAY TO IDENTIFY THE TOP LEVEL DOMAIN (TLD)
  1738. $l1 = '0';
  1739.  
  1740. foreach($tldArray as $s) {
  1741. // CHECKS THE POSITION IN THE ARRAY TO SEE IF IT MATCHES ANY OF THE KNOWN TOP LEVEL DOMAINS (YOU CAN ADD TO THIS LIST)
  1742. if($s == 'com' || $s == 'net' || $s == 'info' || $s == 'biz' || $s == 'us' || $s == 'co' || $s == 'org' || $s == 'me') {
  1743.  
  1744. // CALCULATES THE SECOND LEVEL DOMAIN POSITION IN THE ARRAY ONCE THE POSITION OF THE TOP LEVEL DOMAIN IS IDENTIFIED
  1745. $l2 = $l1 - 1;
  1746. }
  1747. else {
  1748. // INCREMENTS THE COUNTER FOR THE TOP LEVEL DOMAIN POSITION IF NO MATCH IS FOUND
  1749. $l1++;
  1750. }
  1751. }
  1752.  
  1753. // RETURN THE SECOND LEVEL DOMAIN AND THE TOP LEVEL DOMAIN IN THE FORMAT LIKE "SOMEDOMAIN.COM"
  1754. echo $tldArray[$l2] . '.' . $tldArray[$l1];
  1755. }
  1756.  
  1757. // CALL THE FUNCTION - THIS EXAMPLE RETURNS "BITLY.COM"
  1758. getPrimaryDomain('http://www.enterprise.bitly.com/?utm_source=homepage);
  1759.  
  1760. ?>
  1761. up
  1762. down
  1763. -1
  1764. bahtiar at gadimov dot de ¶
  1765. 6 years ago
  1766. Hi,
  1767.  
  1768. if you have problems with UTF8 encoded urls please see http://bugs.php.net/bug.php?id=52923 . parse_url breaks the utf8. :( You have to implement it yourself.
  1769. up
  1770. down
  1771. -1
  1772. ivijan dot stefan at gmail dot com ¶
  1773. 11 months ago
  1774. If you need check if URL exists or not, here is one my good function for that.
  1775.  
  1776. <?php
  1777.  
  1778. // Return false or URL
  1779. function url_exists($url='')
  1780. {
  1781. if(empty($url)) return false;
  1782. $curl = curl_init($url);
  1783. //don't fetch the actual page, you only want to check the connection is ok
  1784. curl_setopt($curl, CURLOPT_NOBODY, true);
  1785. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,5);
  1786. curl_setopt($curl, CURLOPT_TIMEOUT , 2);
  1787. //do request
  1788. $result = curl_exec($curl);
  1789. //if request did not fail
  1790. if ($result !== false) {
  1791. //if request was ok, check response code
  1792. $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  1793. if ((int)$statusCode === 200) return $url;
  1794. return false;
  1795. }
  1796. curl_close($curl);
  1797. return false;
  1798. }
  1799.  
  1800. if(url_exists("http://www.google.com")!==false)
  1801. {
  1802. // URL Exists
  1803. }
  1804. ?>
  1805. This can help if you decide to do some dynamic URL parser or something where need validations.
  1806. up
  1807. down
  1808. -1
  1809. Rob ¶
  1810. 1 year ago
  1811. I've been working on a generic class that would make URI parsing / building a little easier.
  1812.  
  1813. The composer package is here: https://packagist.org/packages/enrise/urihelper
  1814.  
  1815. And the repository is here: https://github.com/Enrise/UriHelper
  1816.  
  1817. An example of the usage:
  1818.  
  1819. <?php
  1820. $uri = new \Enrise\Uri('http://usr:pss@example.com:81/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment');
  1821. echo $uri->getScheme(); // http
  1822. echo $uri->getUser(); // usr
  1823. echo $uri->getPass(); // pss
  1824. echo $uri->getHost(); // example.com
  1825. echo $uri->getPort(); // 81
  1826. echo $uri->getPath(); // /mypath/myfile.html
  1827. echo $uri->getQuery(); // a=b&b[]=2&b[]=3
  1828. echo $uri->getFragment(); // myfragment
  1829. echo $uri->isSchemeless(); // false
  1830. echo $uri->isRelative(); // false
  1831.  
  1832. $uri->setScheme('scheme:child:scheme.VALIDscheme123:');
  1833. $uri->setPort(null);
  1834.  
  1835. echo $uri->getUri(); //scheme:child:scheme.VALIDscheme123:usr:pss@example.com/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment
  1836. ?>
  1837. up
  1838. down
  1839. -1
  1840. gautam at rogers dot com ¶
  1841. 8 years ago
  1842. What about using something like this to safely encoding all the values that are passed in the query portion?
  1843.  
  1844. Example input:
  1845. http://www.example.com/?first=john&last=smith&email=john@smith.com
  1846.  
  1847. Result:
  1848. http://www.example.com/?first=john&last=smith&email=john%40smith.com
  1849.  
  1850. <?php
  1851. function safe_url($url) {
  1852. // Make sure we have a string to work with
  1853. if(!empty($url)) {
  1854. // Explode into URL keys
  1855. $urllist=parse_url($url);
  1856.  
  1857. // Make sure we have a valid result set and a query field
  1858. if(is_array($urllist) && isset($urllist["query"])) {
  1859. // Explode into key/value array
  1860. $keyvalue_list=explode("&",($urllist["query"]));
  1861.  
  1862. // Store resulting key/value pairs
  1863. $keyvalue_result=array();
  1864.  
  1865. foreach($keyvalue_list as $key=>$value) {
  1866. // Explode each individual key/value into an array
  1867. $keyvalue=explode("=",$value);
  1868.  
  1869. // Make sure we have a "key=value" array
  1870. if(count($keyvalue)==2) {
  1871. // Encode the value portion
  1872. $keyvalue[1]=urlencode($keyvalue[1]);
  1873.  
  1874. // Add our key and encoded value into the result
  1875. array_push($keyvalue_result,implode("=",$keyvalue));
  1876. }
  1877. }
  1878.  
  1879. // Repopulate our query key with encoded results
  1880. $urllist["query"]=implode("&",$keyvalue_result);
  1881.  
  1882. // Build the the final output URL
  1883. $url=(isset($urllist["scheme"])?$urllist["scheme"]."://":"").
  1884. (isset($urllist["user"])?$urllist["user"].":":"").
  1885. (isset($urllist["pass"])?$urllist["pass"]."@":"").
  1886. (isset($urllist["host"])?$urllist["host"]:"").
  1887. (isset($urllist["port"])?":".$urllist["port"]:"").
  1888. (isset($urllist["path"])?$urllist["path"]:"").
  1889. (isset($urllist["query"])?"?".$urllist["query"]:"").
  1890. (isset($urllist["fragment"])?"#".$urllist["fragment"]:"");
  1891. }
  1892. }
  1893.  
  1894. return $url;
  1895. }
  1896. ?>
  1897. up
  1898. down
  1899. -1
  1900. ilja at radusch dot com ¶
  1901. 8 years ago
  1902. Here is an update to the glue_url() function.
  1903.  
  1904. It can now handle relative URLs if only 'path' is provided.
  1905.  
  1906. <?php
  1907. function glue_url($parsed) {
  1908. if (!is_array($parsed)) {
  1909. return false;
  1910. }
  1911.  
  1912. $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
  1913. $uri .= isset($parsed['user']) ? $parsed['user'].(isset($parsed['pass']) ? ':'.$parsed['pass'] : '').'@' : '';
  1914. $uri .= isset($parsed['host']) ? $parsed['host'] : '';
  1915. $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
  1916.  
  1917. if (isset($parsed['path'])) {
  1918. $uri .= (substr($parsed['path'], 0, 1) == '/') ?
  1919. $parsed['path'] : ((!empty($uri) ? '/' : '' ) . $parsed['path']);
  1920. }
  1921.  
  1922. $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
  1923. $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
  1924.  
  1925. return $uri;
  1926. }
  1927. ?>
  1928. up
  1929. down
  1930. -1
  1931. Nicolas Merlet - admin(at)merletn.org ¶
  1932. 8 years ago
  1933. Please note that parse_url seems not to produce always the same results when passing non-standard urls.
  1934.  
  1935. Eg. I was using this code since 2005 (both under PHP 4.3.10 and PHP 5.2.3) :
  1936.  
  1937. <?php
  1938.  
  1939. $p = parse_url ( 'http://domain.tld/tcp://domain2.tld/dir/file' ) ;
  1940.  
  1941. $d2 = parse_url ( $p['path'] ) ;
  1942.  
  1943. echo $d2 ; // returns '/dir/file'
  1944.  
  1945. ?>
  1946.  
  1947. Of course my example is very specific, as URL is not really correct. But using parse_url was a great trick to split URL easily (without using regular expressions).
  1948.  
  1949. Unfortunately under PHP 5.2.0-8 (+etch10), parse_url will fail as it does not accept the slash (/) at the beginning of URL.
  1950.  
  1951. Here is a possible patch :
  1952.  
  1953. <?php
  1954.  
  1955. $p = parse_url ( 'http://domain.tld/tcp://domain2.tld/dir/file' ) ;
  1956.  
  1957. $d2 = parse_url ( substr ( $p['path'] , 1 ) ) ;
  1958.  
  1959. echo $d2 ; // returns '/dir/file'
  1960.  
  1961. ?>
  1962.  
  1963. However this last code is not optimized at all, and should be replaced by a regular expression to split URL (so that parse_url would be no longer used).
  1964.  
  1965. So you should use parse_url very carefully, and verify that you pass only standard URLs...
  1966. up
  1967. down
  1968. -1
  1969. Marc-Antoine Ross ¶
  1970. 9 years ago
  1971. Do not look for the fragment in $_SERVER['QUERY_STRING'], you will not find it. You should read the fragment in JavaScript for example.
  1972. up
  1973. down
  1974. -3
  1975. jbr at ya-right dot com ¶
  1976. 8 years ago
  1977. This function never works the way you think it should...
  1978.  
  1979. Example....
  1980.  
  1981. <?php
  1982.  
  1983. print_r ( parse_url ( 'me:you@sub.site.org/pear/validate.html?happy=me&sad=you#url' ) );
  1984.  
  1985. ?>
  1986.  
  1987. Returns...
  1988.  
  1989. Array
  1990. (
  1991. [scheme] => me
  1992. [path] => you@sub.site.org/pear/validate.html
  1993. [query] => happy=me&sad=you
  1994. [fragment] => url
  1995. )
  1996.  
  1997. Here my way of doing parse_url
  1998.  
  1999. <?php
  2000.  
  2001. function parseUrl ( $url )
  2002. {
  2003. $r = '!(?:(\w+)://)?(?:(\w+)\:(\w+)@)?([^/:]+)?';
  2004. $r .= '(?:\:(\d*))?([^#?]+)?(?:\?([^#]+))?(?:#(.+$))?!i';
  2005.  
  2006. preg_match ( $r, $url, $out );
  2007.  
  2008. return $out;
  2009. }
  2010.  
  2011. print_r ( parseUrl ( 'me:you@sub.site.org/pear/validate.html?happy=me&sad=you#url' ) );
  2012.  
  2013. ?>
  2014.  
  2015. Returns...
  2016.  
  2017. Array
  2018. (
  2019. [0] => me:you@sub.site.org/pear/validate.html?happy=me&sad=you#url
  2020. [1] =>
  2021. [2] => me
  2022. [3] => you
  2023. [4] => sub.site.org
  2024. [5] =>
  2025. [6] => /pear/validate.html
  2026. [7] => happy=me&sad=you
  2027. [8] => url
  2028. )
  2029.  
  2030. Where as...
  2031.  
  2032. out[0] = full url
  2033. out[1] = scheme or '' if no scheme was found
  2034. out[2] = username or '' if no auth username was found
  2035. out[3] = password or '' if no auth password was found
  2036. out[4] = domain name or '' if no domain name was found
  2037. out[5] = port number or '' if no port number was found
  2038. out[6] = path or '' if no path was found
  2039. out[7] = query or '' if no query was found
  2040. out[8] = fragment or '' if no fragment was found
  2041. up
  2042. down
  2043. -2
  2044. mprz1024 at gmail dot com ¶
  2045. 10 months ago
  2046. So why on Earth does parse_url('file:1') work while parse_url('file:0') returns false?
  2047. up
  2048. down
  2049. -6
  2050. przemek at sobstel dot org ¶
  2051. 6 years ago
  2052. If you want to get host, function will return NULL if you pass only host.
  2053.  
  2054. Example:
  2055.  
  2056. <?php
  2057. parse_url($url, PHP_URL_HOST);
  2058. ?>
  2059.  
  2060. $url => value returned
  2061.  
  2062. http://example.com => string 'example.com' (length=11)
  2063. http://www.example.com =>string 'www.example.com' (length=15)
  2064. http://www.example.com:8080 => string 'www.example.com' (length=15)
  2065. example.com => null
  2066. www.example.com => null
  2067. example.com:8080 => string 'example.com' (length=11)
  2068. www.example.com:8080 => string 'www.example.com' (length=15)
  2069. up
  2070. down
  2071. -3
  2072. FredLudd at gmail dot com ¶
  2073. 8 years ago
  2074. Another shot at trying to find a better parser. I noticed that the laulibrius/theoriginalmarksimpson functions didn't quite handle the URL for the page they were displayed on. For my mirror, ca3, this is
  2075. http://ca3.php.net/manual/en/function.parse-url.php
  2076.  
  2077. Run it through the function and it parses to
  2078. scheme => http
  2079. login =>
  2080. pass =>
  2081. host => ca3.php.net
  2082. ip =>
  2083. subdomain => ca3
  2084. domain => php.
  2085. extension => net
  2086. port =>
  2087. path => /manual/en/function.parse
  2088. file => function.parse
  2089. that is, the file name gets a bit mangled
  2090.  
  2091. Rather than tweak the function's regular expression yet again, I opted to adapt a RegExp that served me well in Javascript:
  2092.  
  2093. function j_parseUrl($url) {
  2094. $r = "(?:([a-z0-9+-._]+)://)?";
  2095. $r .= "(?:";
  2096. $r .= "(?:((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9a-f]{2})*)@)?";
  2097. $r .= "((?:[a-z0-9-._~!$&'()*+,;=]|%[0-9a-f]{2})*)";
  2098. $r .= "(?::(\d*))?";
  2099. $r .= "(/(?:[a-z0-9-._~!$&'()*+,;=:@/]|%[0-9a-f]{2})*)?";
  2100. $r .= "|";
  2101. $r .= "(/?";
  2102. $r .= "(?:[a-z0-9-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+";
  2103. $r .= "(?:[a-z0-9-._~!$&'()*+,;=:@\/]|%[0-9a-f]{2})*";
  2104. $r .= ")?";
  2105. $r .= ")";
  2106. $r .= "(?:\?((?:[a-z0-9-._~!$&'()*+,;=:\/?@]|%[0-9a-f]{2})*))?";
  2107. $r .= "(?:#((?:[a-z0-9-._~!$&'()*+,;=:\/?@]|%[0-9a-f]{2})*))?";
  2108. preg_match("`$r`i", $url, $match);
  2109. $parts = array(
  2110. "scheme"=>'',
  2111. "userinfo"=>'',
  2112. "authority"=>'',
  2113. "host"=> '',
  2114. "port"=>'',
  2115. "path"=>'',
  2116. "query"=>'',
  2117. "fragment"=>'');
  2118. switch (count ($match)) {
  2119. case 9: $parts['fragment'] = $match[8];
  2120. case 8: $parts['query'] = $match[7];
  2121. case 7: $parts['path'] = $match[6];
  2122. case 6: $parts['path'] = $match[5] . $parts['path'];
  2123. case 5: $parts['port'] = $match[4];
  2124. case 4: $parts['host'] = $match[3];
  2125. case 3: $parts['userinfo'] = $match[2];
  2126. case 2: $parts['scheme'] = $match[1];
  2127. }
  2128. $parts['authority'] = ($parts['userinfo']?$parts['userinfo']."@":"").
  2129. $parts['host'].
  2130. ($parts['port']?":".$parts['port']:"");
  2131. return $parts;
  2132. }
  2133.  
  2134. This function, when fed "http://ca3.php.net/manual/en/function.parse-url.php", returns
  2135. scheme => http
  2136. userinfo =>
  2137. authority => ca3.php.net
  2138. host => ca3.php.net
  2139. port =>
  2140. path => /manual/en/function.parse-url.php
  2141. query =>
  2142. fragment =>
  2143. which is somewhat closer to my needs.
  2144.  
  2145. But everything should be tested against the two examples provided by RFC3986,
  2146.  
  2147. /* line too long for this site's commnet handler */
  2148. "foo://username:password@example.com:8042".
  2149. "/over/there/index.dtb;type=animal?name=ferret#nose"
  2150. and
  2151. "urn:example:animal:ferret:nose"
  2152.  
  2153. Here the native function parse_url() performs admirably on that "urn:" example. Mine fails to pick out the path ("example:animal:ferret:nose") and the laulibrius/theoriginalmarksimpson function can't decipher anything there. On the "foo:" example, both my function and parse_url() get it right, while the other examples on this page don't.
  2154.  
  2155. The laulibrius/theoriginalmarksimpson function delivers
  2156. scheme => foo
  2157. login => username
  2158. pass => password
  2159. host => example.com
  2160. ip =>
  2161. subdomain =>
  2162. domain => example.
  2163. extension => com
  2164. port => 8042
  2165. path => /over/there/index.dtb
  2166. file => index.dtb
  2167.  
  2168. As you can see, the query string ("name=ferret") and fragment ("nose") have dropped off, as well as the parameter ("type=animal").
  2169. add a note add a note
  2170.  
  2171. URL Functions
  2172. base64_​decode
  2173. base64_​encode
  2174. get_​headers
  2175. get_​meta_​tags
  2176. http_​build_​query
  2177. parse_​url
  2178. rawurldecode
  2179. rawurlencode
  2180. urldecode
  2181. urlencode
  2182.  
  2183. Copyright © 2001-2017 The PHP Group My PHP.net Contact Other PHP.net sites Mirror sites Privacy policy
  2184.  
  2185. To Top
Add Comment
Please, Sign In to add comment