3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?php /** * PHP URI Library * * A PHP library for working with URI's, that is designed around the URI * standard. Requires PHP 5.3 or later. This library replaces and extends all * of PHP's parse_url() features, and even has some handy aliases. * * Originally inspired by P Guardiario's work. * * @author Nicholas Jordon * @link https://github.com/ProjectCleverWeb/PHP-URI * @copyright 2014 Nicholas Jordon - All Rights Reserved * @version 1.0.0 * @license http://opensource.org/licenses/MIT * @see http://en.wikipedia.org/wiki/URI_scheme */ namespace {class uri extends \uri\main{}}namespace uri{abstract class main{ public $error; public $input; public $object; private $chain; private $authority; private $domain; private $fqdn; private $fragment; private $host; private $protocol; private $pass; private $password; private $path; private $port; private $query; private $scheme; private $scheme_name; private $scheme_symbols; private $user; private $username; public function __construct($input){$this->input=$input;$this->object=\uri\parser::parse($input);if(!empty($this->object->host)){\uri\generate::authority($this->object);\uri\generate::aliases($this->object);$this->chain=new \uri\chain($this);$this->authority=&$this->object->authority;$this->domain=&$this->object->domain;$this->fqdn=&$this->object->fqdn;$this->fragment=&$this->object->fragment;$this->host=&$this->object->host;$this->protocol=&$this->object->protocol;$this->pass=&$this->object->pass;$this->password=&$this->object->password;$this->path=&$this->object->path;$this->port=&$this->object->port;$this->query=&$this->object->query;$this->scheme=&$this->object->scheme;$this->scheme_name=&$this->object->scheme_name;$this->scheme_symbols=&$this->object->scheme_symbols;$this->user=&$this->object->user;$this->username=&$this->object->username;}else {$this->error='Input could not be parsed as a URI';}} public function __toString(){return \uri\generate::string($this->object);} public function __invoke(){return \uri\generate::string($this->object);} public function __clone(){$this->_err('CLONE',debug_backtrace(),'clone');} public function __get($name){if(isset($this->object->$name)){\uri\generate::scheme($this->object);\uri\generate::authority($this->object);return $this->object->$name;}else {$this->_err('UNDEFINED',debug_backtrace(),$name);return NULL;}} public function __set($name,$value){if(isset($this->object->$name)&&$name!='authority'){\uri\actions::modify($this->object,'replace',$name,$value);return $value;}else {$this->_err('FORBIDDEN',debug_backtrace(),$name);return NULL;}} public function __isset($name){\uri\generate::scheme($this->object);\uri\generate::authority($this->object);if(isset($this->object->$name)){return !empty($this->object->$name);}return FALSE;} public function __unset($name){if(isset($this->object->$name)&&$name!='host'&&$name!='authority'){\uri\actions::modify($this->object,'replace',$name,'');return TRUE;}elseif(isset($this->object->$name)){$this->_err('FORBIDDEN',debug_backtrace(),$name);}else {$this->_err('UNDEFINED',debug_backtrace(),$name);}return FALSE;} public function str(){return \uri\generate::string($this->object);} public function to_string(){return \uri\generate::string($this->object);} public function p_str($prepend='',$append=''){echo $prepend.\uri\generate::string($this->object).$append;} public function arr(){return \uri\generate::to_array($this->object);} public function to_array(){return \uri\generate::to_array($this->object);} public function path_info(){return \uri\generate::path_info($this->object);} public function query_arr(){return \uri\generate::query_array($this->object);} public function replace($section,$str){return \uri\actions::modify($this->object,'replace',$section,$str);} public function prepend($section,$str){return \uri\actions::modify($this->object,'prepend',$section,$str);} public function append($section,$str){return \uri\actions::modify($this->object,'append',$section,$str);} public function query_add($key,$value){return \uri\query::add($this->object,$key,$value);} public function query_replace($key,$value){\uri\query::replace($this->object,$key,$value);} public function query_remove($key){\uri\query::remove($this->object,$key);} public function query_exists($key){return \uri\query::exists($this->object,$key);} public function query_get($key){return \uri\query::get($this->object,$key);} public function query_rename($key,$new_key){return \uri\query::rename($this->object,$key,$new_key);} public function chain(){return $this->chain;} public function reset(){$this->__construct($this->input);} private function _err($type,$trace,$name){$fmt='Undifined property via <code>%1$s::%2$s()</code>: Property <code>%3$s</code> cannot be unset in <b>%4$s</b> on line <b>%5$s</b>. Error triggered';if($type=='FORBIDDEN'){$fmt='Forbidden property via <code>%1$s::%2$s()</code>: Property <code>%3$s</code> cannot be unset in <b>%4$s</b> on line <b>%5$s</b>. Error triggered';}elseif($type=='CLONE'){$fmt='Invalid clone in <b>%4$s</b> on line <b>%5$s</b>. Because of how cloning works, and how references are configured within the class, extensions of %1$s cannot be cloned. Please make a new instance instead, like so: <code>$clone = new \\uri($original->str()); $clone->input = $original->input;</code>. Error triggered';}trigger_error(sprintf($fmt,$trace[0]['class'],$trace[0]['function'],$name,$trace[0]['file'],$trace[0]['line']),E_USER_NOTICE);}}class parser{const REGEX='/^(([a-z]+)?(\:\/\/|\:|\/\/))?(?:([a-z0-9$_\.\+!\*\'\(\),;&=\-]+)(?:\:([a-z0-9$_\.\+!\*\'\(\),;&=\-]*))?@)?((?:\d{3}.\d{3}.\d{3}.\d{3})|(?:[a-z0-9\-_]+(?:\.[a-z0-9\-_]+)*))(?:\:([0-9]+))?((?:\:|\/)[a-z0-9\-_\/\.]+)?(?:\?([a-z0-9$_\.\+!\*\'\(\),;:@&=\-%]*))?(?:#([a-z0-9\-_]*))?/i'; public static function parse($uri){if(!is_string($uri)){return FALSE;}$parsed=self::regex_parse($uri);if(empty($parsed)){$parsed=array_fill(1,10,'');}return (object)array('scheme'=>$parsed[1],'scheme_name'=>$parsed[2],'scheme_symbols'=>$parsed[3],'user'=>$parsed[4],'pass'=>$parsed[5],'host'=>$parsed[6],'port'=>$parsed[7],'path'=>$parsed[8],'query'=>$parsed[9],'fragment'=>$parsed[10],);} private static function regex_parse($uri){preg_match_all(self::REGEX,$uri,$parsed,PREG_SET_ORDER);if(!isset($parsed[0][6])){return FALSE;}return $parsed[0]+array_fill(0,11,'');}}class modify{ public static function scheme_name(&$object,$action,$str){$org=$object->scheme_name;\uri\actions::callback($object,$action,__FUNCTION__,$str);if(!(preg_match('/\A[a-z]{1,10}\Z/',$object->scheme_name)||empty($str))){$object->scheme_name=$org;return FALSE;}elseif(empty($object->scheme_symbols)){$object->scheme_symbols='://';}return \uri\generate::string($object);} public static function scheme_symbols(&$object,$action,$str){$org=$object->scheme_symbols;\uri\actions::callback($object,$action,__FUNCTION__,$str);if(!(preg_match('/\A(:)?([\/]{2,3})?\Z/',$object->scheme_symbols)||empty($str))){$object->scheme_symbols=$org;return FALSE;}return \uri\generate::string($object);} public static function scheme(&$object,$action,$str){$org=array($object->scheme,$object->scheme_name,$object->scheme_symbols);\uri\actions::callback($object,$action,__FUNCTION__,$str);if(empty($object->scheme)){$object->scheme=$object->scheme_name=$object->scheme_symbols='';}else {preg_match('/\A([a-z]{1,10})?(\:|:\/\/|\/\/|:\/\/\/)\Z/i',$object->scheme,$matches);if(empty($matches[1])&&empty($matches[2])){$object->scheme=$org[0];$object->scheme_name=$org[1];$object->scheme_symbols=$org[2];return FALSE;}else {$matches=$matches+array('','','');$object->scheme=$matches[0];$object->scheme_name=$matches[1];$object->scheme_symbols=$matches[2];}}return \uri\generate::string($object);} public static function protocol(&$object,$action,$str){return self::scheme($object,$action,$str);} public static function user(&$object,$action,$str){$str=rawurlencode($str);\uri\actions::callback($object,$action,__FUNCTION__,$str);return \uri\generate::string($object);} public static function username(&$object,$action,$str){return self::user($object,$action,$str);} public static function pass(&$object,$action,$str){$str=rawurlencode($str);\uri\actions::callback($object,$action,__FUNCTION__,$str);return \uri\generate::string($object);} public static function password(&$object,$action,$str){return self::pass($object,$action,$str);} public static function host(&$object,$action,$str){$org=$object->host;\uri\actions::callback($object,$action,__FUNCTION__,$str);if((!preg_match('/\A(([a-z0-9_]([a-z0-9\-_]+)?)\.)+[a-z0-9]([a-z0-9\-]+)?\Z/i',$object->host)&&!preg_match('/\A([0-9]\.){3}[0-9]\Z/i',$object->host))){$object->host=$org;return FALSE;}return \uri\generate::string($object);} public static function domain(&$object,$action,$str){return self::host($object,$action,$str);} public static function fqdn(&$object,$action,$str){return self::host($object,$action,$str);} public static function port(&$object,$action,$str){$org=$object->port;if(isset($str[0])&&$str[0]==':'){$str=substr($str,1);}\uri\actions::callback($object,$action,__FUNCTION__,$str);if(!(preg_match('/\A[0-9]{0,5}\Z/',$object->port)||empty($str))){$object->port=$org;return FALSE;}return \uri\generate::string($object);} public static function path(&$object,$action,$str){\uri\actions::callback($object,$action,__FUNCTION__,$str);return \uri\generate::string($object);} public static function query(&$object,$action,$str){if(isset($str[0])&&$str[0]=='?'){$str=substr($str,1);}\uri\actions::callback($object,$action,__FUNCTION__,$str);return \uri\generate::string($object);} public static function fragment(&$object,$action,$str){if(isset($str[0])&&$str[0]=='#'){$str=substr($str,1);}$str=urlencode($str);\uri\actions::callback($object,$action,__FUNCTION__,$str);return \uri\generate::string($object);}}class actions{ public static function modify(&$object,$action,$section,$str){settype($section,'string');settype($str,'string');$section=strtolower($section);if(is_callable(array('\\uri\\modify',$section))){return call_user_func_array(array('\\uri\\modify',$section),array(&$object,$action,$str));}else {return FALSE;}} public static function callback(&$object,$action,$section,$str){switch($action){case 'replace':$object->$section=$str;break;case 'prepend':$object->$section=$str.$object->$section;break;case 'append':$object->$section=$object->$section.$str;}}}class generate{ public static function aliases(&$object){$object->protocol=&$object->scheme;$object->username=&$object->user;$object->password=&$object->pass;$object->domain=&$object->host;$object->fqdn=&$object->host;} public static function scheme(&$object){$object->scheme=$object->scheme_name.$object->scheme_symbols;} public static function authority(&$object){$str_arr=array($object->user);if(empty($object->user)==FALSE&&empty($object->pass)){$str_arr[]='@';}elseif(!empty($object->user)){$str_arr[]=':'.$object->pass.'@';}$str_arr[]=$object->host;if(!empty($object->port)){$str_arr[]=':'.$object->port;}$object->authority=implode('',$str_arr);} public static function string(&$object){self::scheme($object);self::authority($object);$str_arr=array($object->scheme,$object->authority,$object->path);if(!empty($object->query)){$str_arr[]='?'.$object->query;}if(!empty($object->fragment)){$str_arr[]='#'.$object->fragment;}return implode('',$str_arr);} public static function to_array(&$object){$arr=array('authority'=>$object->authority,'fragment'=>$object->fragment,'host'=>$object->host,'pass'=>$object->pass,'path'=>$object->path,'port'=>$object->port,'query'=>$object->query,'scheme'=>$object->scheme,'scheme_name'=>$object->scheme_name,'scheme_symbols'=>$object->scheme_symbols,'user'=>$object->user,);$arr['domain']=&$arr['host'];$arr['fqdn']=&$arr['host'];$arr['password']=&$arr['pass'];$arr['protocol']=&$arr['scheme'];$arr['username']=&$arr['user'];ksort($arr);return $arr;} public static function path_info(&$object){$defaults=array('dirname'=>'','basename'=>'','extension'=>'','filename'=>'','array'=>array());$info=pathinfo($object->path)+$defaults;$info['array']=array_values(array_filter(explode('/',$object->path)));ksort($info);return $info;} public static function query_array(&$object){parse_str($object->query,$return);return (array)$return;}}class query{ private static function build_query($query_array){return http_build_query($query_array,'','&',PHP_QUERY_RFC3986);} public static function add(&$object,$key,$value){$qarray=\uri\generate::query_array($object);if(!isset($qarray[$key])){$qarray[$key]=$value;\uri\actions::modify($object,'replace','QUERY',self::build_query($qarray));return TRUE;}return FALSE;} public static function replace(&$object,$key,$value){$qarray=\uri\generate::query_array($object);$qarray[$key]=$value;\uri\actions::modify($object,'replace','QUERY',self::build_query($qarray));} public static function remove(&$object,$key){$qarray=\uri\generate::query_array($object);if(isset($qarray[$key])){unset($qarray[$key]);\uri\actions::modify($object,'replace','QUERY',self::build_query($qarray));}} public static function exists(&$object,$key){$qarray=\uri\generate::query_array($object);return isset($qarray[$key]);} public static function get(&$object,$key){$qarray=\uri\generate::query_array($object);if(isset($qarray[$key])){return $qarray[$key];}return NULL;} public static function rename(&$object,$key,$new_key){$qarray=\uri\generate::query_array($object);if(isset($qarray[$key])){$qarray[$new_key]=$qarray[$key];unset($qarray[$key]);\uri\actions::modify($object,'replace','QUERY',self::build_query($qarray));return TRUE;}return FALSE;}}class chain{ private $class; private $object; public function __construct(&$class){$this->class=&$class;$this->object=&$class->object;return $this;} public function p_str($prepend='',$append=''){echo $prepend.\uri\generate::string($this->object).$append;return $this;} public function replace($section,$str){\uri\actions::modify($this->object,'replace',$section,$str);return $this;} public function prepend($section,$str){\uri\actions::modify($this->object,'prepend',$section,$str);return $this;} public function append($section,$str){\uri\actions::modify($this->object,'append',$section,$str);return $this;} public function query_add($key,$value){\uri\query::add($this->object,$key,$value);return $this;} public function query_replace($key,$value){\uri\query::replace($this->object,$key,$value);return $this;} public function query_remove($key){\uri\query::remove($this->object,$key);return $this;} public function query_rename($key,$new_key){\uri\query::rename($this->object,$key,$new_key);return $this;} public function reset(){$this->class->__construct($this->class->input);} private function _err($trace){trigger_error(sprintf('The method <code>%1$s()</code> cannot be chained in <b>%2$s</b> on line <b>%3$s</b>. Error triggered',$trace[0]['function'],$trace[0]['file'],$trace[0]['line']),E_USER_NOTICE);} public function str(){$this->_err(debug_backtrace());return $this;} public function to_string(){$this->_err(debug_backtrace());return $this;} public function arr(){$this->_err(debug_backtrace());return $this;} public function to_array(){$this->_err(debug_backtrace());return $this;} public function path_info(){$this->_err(debug_backtrace());return $this;} public function query_array(){$this->_err(debug_backtrace());return $this;} public function query_exists(){$this->_err(debug_backtrace());return $this;} public function query_get(){$this->_err(debug_backtrace());return $this;}}}
Output for 5.3.0 - 5.6.28, hhvm-3.10.0 - 3.12.0, 7.0.0 - 7.1.0