[PHP] URL парсинг

Бывают моменты в жизни, когда хочется написать свой велосипед под какую-то известную задачу. В этот раз было решено распарсить url по-своему.
Онлайн-демо
Вначале идет вывод работы класса, а ниже — результат parse_url.
Исходный код класса:

<?PHP
 
/**
 * Файл с описанием класса url
 * @author KronuS
 * @package web
 * @version 1.00 04.09.2011
 */
 
/**
 * Класс url. Используется для организации доступа к разным частям url - протокол, хост, порт, путь и т.д.
 * Пример использования:
 * <code>
 * $url = new url('http://kronus.me/?p=1#more');
 * echo($url->protocol);
 * print_r($url->get_info());
 * </code>
 * @package web
 * @author KronuS
 */
 
class url {
	/**
	 * На всякий случай будем хранить исходный url
	 * @access private
	 * @var string
	 */
	private $_url;
	/**
	 * Массив данных о url
	 * @access private
	 * @var array
	 */
	private $_data = array(
		'protocol' => '',
		'login' =>'',
		'password' => '',
		'host' => '',
		'port' => '',
		'path' => '',
		'parameters' => '',
		'anchor' => ''
	);
	/**
	 * Конструктор
	 * @access public
	 * @param $url string ссылка, которую надо распарсить
	 */
	public function __construct($url) {
		$this->_url = $url;
		$this->_parse_main();
	}
	/**
	 * Основной метод парсинга url
	 * @access private
	 * @return null
	 */
	private function _parse_main() {
		$url = $this->_url;
		// Протокол
		$d = $this->_separate_string($url, '://');
		if (count($d) == 2) {
			$this->_data['protocol'] = $d[0];
			$url = $d[1];
		}
		else {
			$url = $d[0];
		}
		$d = $this->_separate_string($url, '/');
		if (count($d) == 2) {
			// Если url-путь, параметры и анкор есть, то они будут идти вторым элементов возвращенного массива (так как находятся в url правее)
			$this->_parse_r($d[1]);
		}
		$this->_parse_l($d[0]);
		// Если протокол 'file', то может быть ':///' и надо убрать последний '/'
		if ($this->_data['protocol'] == 'file') {
			if (substr($this->_data['host'], 0, 1) == '/') {
				$this->_data['host'] = substr($this->_data['host'], 1);
			}
		}
	}
	/**
	 * Метод для разделения строки на две по разделителю (вспомогательный метод)
	 * @access private
	 * @param $string string
	 * @param $separator string
	 * @return array
	 */
	private function _separate_string($string, $separator) {
		$indx = strpos($string, $separator);
		if ($indx === false) {
			return array($string);
		}
		else {
			$ret = array();
			$ret[] = substr($string, 0 , $indx);
			$ret[] = substr($string, $indx + strlen($separator));
			return $ret;
		}
	}
	public function __get($name) {
		if (isset($this->_data[$name])) {
			return $this->_data[$name];
		}
		return null;
	}
	/**
	 * Метод возвращает массив всех данных об url
	 * @access public
	 * @return array
	 */
	public function get_info() {
		return $this->_data;
	}
 
	private function _parse_l($part) {
		$d = $this->_separate_string($part, '@');
		$host_port = '';
		if (count($d) == 2) {
			// Часть "логин/пароль" есть
			$login_pass = $d[0];
			$lp = $this->_separate_string($login_pass, ':');
			if (count($lp) == 2) {
				$this->_data['password'] = $lp[1];
			}
			$this->_data['login'] = $lp[0];
			$host_port = $d[1];
		}
		else {
			// Части "логин/пароль" нету
			$host_port = $d[0];
		}
		// Разбираем часть "хост/порт"
		$hp = $this->_separate_string($host_port, ':');
		if (count($hp) == 2) {
			// Порт есть
			$this->_data['port'] = $hp[1];
		}
		$this->_data['host'] = $hp[0];
	}
 
	private function _parse_r($part) {
		$d = $this->_separate_string($part, '#');
		if (count($d) == 2) {
			$this->_data['anchor'] = $d[1];
		}
		$pp = $this->_separate_string($d[0], '?');
		if (count($pp) == 2) {
			$this->_data['parameters'] = $pp[1];
		}
		$this->_data['path'] = '/'.$pp[0];
	}
}
 
?>

, , ,

1 комментарий
  1. Alexander сказал(а):

    Спасибо большое ваш код мне очень помог, буду использовать класс на своем сайте.

Оставить комментарий

Top ↑ | Main page | Back