Location: PHPKode > scripts > Relative Path > RelativePath.php
<?php
/**
 * Simple relative path normalizer utility.
 *
 * The utility was inspired by PHP's realPath function, though that required the given path to exist, RelativePath does not.
 * 
 * Particularly useful is you need to parse and normalize paths gathered from for instance URL's and HTML pages.
 *
 * These functions are also included in Zip and ZipStream classes version 1.23 onwards on PHPClasses.org.
 * http://www.phpclasses.org/package/6110 and http://www.phpclasses.org/package/6616 respectively.
 * 
 * License: GNU LGPL, Attribution required for commercial implementations, requested for everything else.
 *
 * @author A. Grandt
 * @copyright A. Grandt 2011
 * @license GNU LGPL, Attribution required for commercial implementations, requested for everything else.
 * @link http://www.phpclasses.org/package/6844
 * @version 1.01
 */
class RelativePath {
	const VERSION = 1.01;

	/**
	 * Join $file to $dir path, and clean up any excess slashes.
	 *
	 * @param String $dir
	 * @param String $file
	 */
	public static function pathJoin($dir, $file) {
		if (empty($dir) || empty($file)) {
			return self::getRelativePath($dir . $file);
		}
		return self::getRelativePath($dir . '/' . $file);
	}

	/**
	 * Clean up a path, removing any unnecessary elements such as /./, // or redundant ../ segments.
	 * If the path starts with a "/", it is deemed an absolute path and any /../ in the beginning is stripped off.
	 * The returned path will not end in a "/".
	 *
	 * @param String $relPath The path to clean up
	 * @return String the clean path
	 */
	public static function getRelativePath($path) {
		$path = preg_replace("#/+\.?/+#", "/", str_replace("\\", "/", $path));
		$dirs = explode("/", rtrim(preg_replace('#^(\./)+#', '', $path), '/'));
				
		$offset = 0;
		$sub = 0;
		$subOffset = 0;
		$root = "";

		if (empty($dirs[0])) {
			$root = "/";
			$dirs = array_splice($dirs, 1);
		} else if (preg_match("#[A-Za-z]:#", $dirs[0])) {
			$root = strtoupper($dirs[0]) . "/";
			$dirs = array_splice($dirs, 1);
		} 

		$newDirs = array();
		foreach($dirs as $dir) {
			if ($dir !== "..") {
				$subOffset--;	
				$newDirs[++$offset] = $dir;
			} else {
				$subOffset++;
				if (--$offset < 0) {
					$offset = 0;
					if ($subOffset > $sub) {
						$sub++;
					} 
				}
			}
		}

		if (empty($root)) {
			$root = str_repeat("../", $sub);
		} 
		return $root . implode("/", array_slice($newDirs, 0, $offset));
	}
}
?>
Return current item: Relative Path