Huang Cong: PHP conversion URL relative path to absolute path of a way

I believe that many programs (especially class collection procedures) will be necessary to convert the relative path URL into the path of absolute need, for example, to collect the HTML code of a page contains resource files often see such a file name:

  • <link rel="stylesheet" href="css/style.css" />
  • <img src="/logo.png" />
  • <img src="../banner.jpg" />

If you directly get its href attribute or the src attribute Clearly this address is not open, which requires the relative path into one of the absolute path. Check the Internet-related code a lot, but most of the code is difficult to read, but not necessarily high-efficiency, based on this I started out to write its own transformation method.

Since the acquisition of the URL format to address or an absolute majority in the root directory of addresses, so the code address these two formats of priority processing and return to improve the efficiency of the code.

Source follows: function receives two parameters, the first parameter is acquired relative path, the second parameter to the original URL is acquired, for example, to collect from the www.example.com/a/b/c.html a resource address css / style.css, then the function call is filter_relative_url('css/style.css', 'http://www.example.com/a/b/c.html');(Note: the authentication function is omitted and filtering operations on URI parameter, the parameter is not applied if the URI http: // prefix being given, the relevant verification code may add their own ).

  • /**
  • * Convert the relative path acquired from the HTML source code to an absolute pathname
  • * @Param String $ url HTML acquired URL
  • * @Param String $ for the URI determination reference original address
  • * @Return returns the modified URL, if the URL is incorrect returns FALSE
  • */
  • function filter_relative_url($url, $URI){
  • // STEP1: go to determine whether the URL contains the protocol, if it contains instructions that can be returned as an absolute address
  • if(strpos($url, '://') !== FALSE){
  • return $url;
  • }
  • // STEP2: parsing the incoming URI
  • $ URI_part = parse_url ($ S);
  • if($URI_part == FALSE)
  • return FALSE;
  • $ URI_root = $ URI_part [ 'scheme']. ': //'. $ URI_part [ 'host']. ( Isset ($ URI_part [ 'port'])? ''. $ URI_part [ 'port'] ');
  • // STEP3: If the URL begins with slash indicates the root directory
  • if(strpos($url, '/') === 0){
  • return $URI_root . $url;
  • }
  • // STEP4: not located in the root directory or an absolute path, consider if does not contain './', then, need to be connected to the relative address of the original URL directory name
  • $URI_dir = (isset($URI_part['path']) &amp;&amp; $URI_part['path']) ? '/' . ltrim(dirname($URI_part['path']), '/') : '';
  • if(strpos($url, './') === FALSE){
  • ow ($ URI_dir! = '') {
  • return $ URI_root. $ URI_dir. '/'. $ url;
  • } else {
  • return $URI_root . '/' . $url;
  • }
  • }
  • // STEP5: If the relative path contains '../' or './' directory represented by paths need to be parsed and recursively
  • //STEP5.1: all the paths './' to '/', '@' to '/'
  • $url = preg_replace('/[^\.]\.\/|\/\//', '/', $url);
  • if(strpos($url, './') === 0)
  • $url = substr($url, 2);
  • //STEP5.2: Use '/' URL strings for dividing each part table is determined
  • $ URI_full_dir = ltrim ($ URI_dir. '/'. $ Url, '/');
  • $URL_arr = explode('/', $URI_full_dir);
  • if($URL_arr[0] == '..')
  • return FALSE;
  • // as the first element of the array is not possible to '..', where it starts from the second loop element
  • dst_arr = $ URL_arr $; // copy of a copy, for combining URL
  • for($i = 1; $i < count($URL_arr); $i ++){
  • if($URL_arr[$i] == '..'){
  • $j = 1;
  • while(TRUE){
  • if(isset($dst_arr[$i - $j]) &amp;&amp; $dst_arr[$i - $j] != FALSE){
  • $dst_arr[$i - $j] = FALSE;
  • $dst_arr[$i] = FALSE;
  • break;
  • } else {
  • $j ++;
  • }
  • }
  • }
  • }
  • // URL and returns a combination of final
  • $ Dst_str = $ URI_root;
  • foreach($dst_arr as $val){
  • if($val != FALSE)
  • $dst_str .= '/' . $val;
  • }
  • return $dst_str;
  • }
php

As a short code is processed into different formats for the relative path and return, the following are the test code:

  • $ URI_1 = 'http://www.abc.com/a/b/c/d.html';
  • $ URI_2 = 'http://www.abc.com';
  • $test [] = 'http://www.abc.com/css/style.css';
  • $test [] = '/img/banner.jpg';
  • $test [] = 'images/res_03.png';
  • $test [] = '../../js/jquery.min.js';
  • $test [] = './../res/js/../jquery/./1.8.3/jquery.js';
  • foreach($test as $val){
  • echo filter_relative_url($val, $URI_1);
  • }
  • foreach($test as $val){
  • echo filter_relative_url($val, $URI_2);
  • }
php

The program returns:

  • http://www.abc.com/css/style.css
  • http://www.abc.com/img/banner.jpg
  • http://www.abc.com/a/b/c/images/res_03.png
  • http://www.abc.com/a/js/jquery.min.js
  • http://www.abc.com/a/b/res/jquery/1.8.3/jquery.js
  • http://www.abc.com/css/style.css
  • http://www.abc.com/img/banner.jpg
  • http://www.abc.com/images/res_03.png

* Note: the second cycle test code only returns three result, because the two results is returned FALSE, because the original site URI is located in the root directory, then preceded by "../" parent directory request is invalid of.

The main advantage of the above code is code that solves the spread of the Internet can not be perfectly compatible with the format of the relative path complex problems, taking the efficiency, reduce the number of judgments and decomposition. This code is currently being used myself, if you have any questions please leave a message or e-mail also contact me, thank you!


Updated May 17, 2016

See a relative address written on the conversion of PHP official website WIKI above, written below for reference:

  • function normalizePath($path)
  • {
  • $parts = array();// Array to build a new path from the good parts
  • $path = str_replace('\\', '/', $path);// Replace backslashes with forwardslashes
  • $path = preg_replace('/\/+/', '/', $path);// Combine multiple slashes into a single slash
  • $segments = explode('/', $path);// Collect path segments
  • $test = '';// Initialize testing variable
  • foreach($segments as $segment)
  • {
  • if($segment != '.')
  • {
  • $test = array_pop($parts);
  • if(is_null($test))
  • $parts[] = $segment;
  • else if($segment == '..')
  • {
  • if($test == '..')
  • $parts[] = $test;
  • if($test == '..' || $test == '')
  • $parts[] = $segment;
  • }
  • else
  • {
  • $parts[] = $test;
  • $parts[] = $segment;
  • }
  • }
  • }
  • return implode('/', $parts);
  • }
php

References:

This link: https://icewing.cc/post/php-conv-addr-re-ab-2.html

Guess you like

Origin www.cnblogs.com/huangcong/p/11628443.html