Apache Zeta Components Manual :: File Source for url.php
Source for file url.php
Documentation is available at url.php
* File containing the ezcUrl class.
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* ezcUrl stores an URL both absolute and relative and contains methods to
* retrieve the various parts of the URL and to manipulate them.
* A URL is assumed to be of this form:
* scheme://host/basedir/script/ordered_parameters/unordered_parameters
* http://example.com/mydir/index.php/groups/Games/Adventure/Adult/(game)/Larry/7
* ordered parameters = "groups", "Games", "Adventure", "Adult"
* unordered parameters = array( "Larry", "7" )
* When creating a configuration with ordered parameters, those parameters are
* required to be present in the parsed URL, in the same number as the
* configuration states. Having a different number of ordered parameters in the
* parsed URL will lead to wrong values assigned to the unordered parameters (if
* any follow the ordered parameters).
* See the tutorial for a way to change configurations dynamically based on
* the ordered parameters.
* // create an ezcUrlConfiguration object
* $urlCfg = new ezcUrlConfiguration();
* // set the basedir and script values
* $urlCfg->basedir = 'mydir';
* $urlCfg->script = 'index.php';
* // define delimiters for unordered parameter names
* $urlCfg->unorderedDelimiters = array( '(', ')' );
* // define ordered parameters
* $urlCfg->addOrderedParameter( 'section' );
* $urlCfg->addOrderedParameter( 'group' );
* $urlCfg->addOrderedParameter( 'category' );
* $urlCfg->addOrderedParameter( 'subcategory' );
* // define unordered parameters
* $urlCfg->addUnorderedParameter( 'game', ezcUrlConfiguration::MULTIPLE_ARGUMENTS );
* // create a new ezcUrl object from a string URL and use the above $urlCfg
* $url = new ezcUrl( 'http://www.example.com/mydir/index.php/groups/Games/Adventure/Adult/(game)/Larry/7', $urlCfg );
* // to get the parameter values from the URL use $url->getParam():
* $section = $url->getParam( 'section' ); // will be "groups"
* $group = $url->getParam( 'group' ); // will be "Games"
* $category = $url->getParam( 'category' ); // will be "Adventure"
* $subcategory = $url->getParam( 'subcategory' ); // will be "Adult"
* $game = $url->getParam( 'game' ); // will be array( "Larry", "7" )
* Example of aggregating values for unordered parameters:
* $urlCfg = new ezcUrlConfiguration();
* $urlCfg->addUnorderedParameter( 'param1', ezcUrlConfiguration::AGGREGATE_ARGUMENTS );
* $url = new ezcUrl( 'http://www.example.com/(param1)/x/(param1)/y/z', $urlCfg );
* $param1 = $url->getParam( 'param1' ); // will be array( array( "x" ), array( "y", "z" ) )
* Unordered parameters can also be fetched as a flat array (useful if the
* URL doesn't have delimiters for the unordered parameter names). Example:
* $urlCfg = new ezcUrlConfiguration();
* $urlCfg->basedir = '/mydir/shop';
* $urlCfg->script = 'index.php';
* $urlCfg->addOrderedParameter( 'module' );
* $url = new ezcUrl( 'http://www.example.com/mydir/shop/index.php/order/Software/PHP/Version/5.2/Extension/XDebug/Extension/openssl', $urlCfg );
* $params = $url->getParams(); // will be array( 'Software', 'PHP', 'Version', '5.2', 'Extension', 'XDebug', 'Extension', 'openssl' )
* @property array(string) $path
* Complete path as an array.
* @property string $scheme
* @property array(string=>mixed) $query
* Complete query string as an associative array.
* @property string $fragment
* @property array(string) $basedir
* Base directory (the part before the script name) or null.
* @property array(string) $script
* Script name (eg. 'index.php') or null.
* @property array(string) $params
* Complete ordered parameters as array.
* @property array(string=>mixed) $uparams
* Complete unordered parameters as associative array.
* @property ezcUrlConfiguration $configuration
* The URL configuration defined for this URL, or null.
* Holds the properties of this class.
* @var array(string=>mixed)
private $properties =
array();
* Constructs a new ezcUrl object from the string $url.
* If the $configuration parameter is provided, then it will apply the
* configuration to the URL by calling {@link applyConfiguration()}.
* @param string $url A string URL from which to construct the URL object
* @param ezcUrlConfiguration $configuration An optional URL configuration used when parsing and building the URL
public function __construct( $url =
null, ezcUrlConfiguration $configuration =
null )
$this->configuration =
$configuration;
if ( $configuration !=
null )
* Sets the property $name to $value.
* @throws ezcBasePropertyNotFoundException
* if the property $name does not exist
* @throws ezcBaseValueException
* if $value is not correct for the property $name
* @param string $name The name of the property to set
* @param mixed $value The new value of the property
public function __set( $name, $value )
$this->properties[$name] =
$value;
$this->properties[$name] =
$value;
* Returns the property $name.
* @throws ezcBasePropertyNotFoundException
* if the property $name does not exist
* @param string $name The name of the property for which to return the value
public function __get( $name )
return $this->properties[$name];
* Returns true if the property $name is set, otherwise false.
* @param string $name The name of the property to test if it is set
public function __isset( $name )
return isset
( $this->properties[$name] );
* Returns this URL as a string by calling {@link buildUrl()}.
* Parses the string $url and sets the class properties.
* @param string $url A string URL to parse
private function parseUrl( $url =
null )
$this->properties['host'] = isset
( $urlArray['host'] ) ?
$urlArray['host'] :
null;
$this->properties['user'] = isset
( $urlArray['user'] ) ?
$urlArray['user'] :
null;
$this->properties['pass'] = isset
( $urlArray['pass'] ) ?
$urlArray['pass'] :
null;
$this->properties['port'] = isset
( $urlArray['port'] ) ?
$urlArray['port'] :
null;
$this->properties['scheme'] = isset
( $urlArray['scheme'] ) ?
$urlArray['scheme'] :
null;
$this->properties['fragment'] = isset
( $urlArray['fragment'] ) ?
$urlArray['fragment'] :
null;
$this->properties['path'] = isset
( $urlArray['path'] ) ?
explode( '/', trim( $urlArray['path'], '/' ) ) :
array();
$this->properties['basedir'] =
array();
$this->properties['script'] =
array();
$this->properties['params'] =
array();
$this->properties['uparams'] =
array();
if ( isset
( $urlArray['query'] ) )
$this->properties['query'] =
array();
* Applies the URL configuration $configuration to the current url.
* It fills the arrays $basedir, $script, $params and $uparams with values
* It also sets the property configuration to the value of $configuration.
* @param ezcUrlConfiguration $configuration An URL configuration used in parsing
$this->configuration =
$configuration;
$this->basedir =
$this->parsePathElement( $configuration->basedir, 0 );
$this->script =
$this->parsePathElement( $configuration->script, count( $this->basedir ) );
* Parses $path based on the configuration $config, starting from $index.
* Returns the first few elements of $this->path matching $config,
* @param string $config A string which will be matched against the path part of the URL
* @param int $index The index in the URL path part from where to start the matching of $config
* @return array(string=>mixed)
private function parsePathElement( $config, $index )
$config =
trim( $config, '/' );
$paramParts =
explode( '/', $config );
foreach ( $paramParts as $part )
if ( isset
( $this->path[$index] ) &&
$part ==
$this->path[$index] )
* Returns ordered parameters from the $path array.
* @param array(string) $config An array of ordered parameters names, from the URL configuration used in parsing
* @param int $index The index in the URL path part from where to start the matching of $config
* @return array(string=>mixed)
$pathCount =
count( $this->path );
for ( $i =
0; $i <
count( $config ); $i++
)
if ( isset
( $this->path[$index +
$i] ) )
$result[] =
$this->path[$index +
$i];
* Returns unordered parameters from the $path array.
* The format of the returned array is:
* array( param_name1 => array( 0 => array( value1, value2, ... ),
* 1 => array( value1, value2, ... ) ),
* param_name2 = array( 0 => array( value1, value2, ... ),
* 1 => array( value1, value2, ... ) ), ... )
* where 0, 1, etc are numbers meaning the nth encounter of each param_name
* For example, if the URL is 'http://www.example.com/(param1)/a/(param2)/x/(param2)/y/z'
* then the result of this function will be:
* array( 'param1' => array( 0 => array( 'a' ) ),
* 'param2' => array( 0 => array( 'x' ),
* 1 => array( 'y', 'z' ) ) );
* For the URL 'http://www.example.com/(param1)/x/(param1)/y/z', these
* methods can be employed to get the values of param1:
* $urlCfg = new ezcUrlConfiguration();
* // single parameter value
* $urlCfg->addUnorderedParameter( 'param1' ); // type is SINGLE_ARGUMENT by default
* $url = new ezcUrl( 'http://www.example.com/(param1)/x/(param1)/y/z', $urlCfg );
* $param1 = $url->getParam( 'param1' ); // will return "y"
* // multiple parameter values
* $urlCfg->addUnorderedParameter( 'param1', ezcUrlConfiguration::MULTIPLE_ARGUMENTS );
* $url = new ezcUrl( 'http://www.example.com/(param1)/x/(param1)/y/z', $urlCfg );
* $param1 = $url->getParam( 'param1' ); // will return array( "y", "z" )
* // multiple parameter values with aggregation
* $urlCfg->addUnorderedParameter( 'param1', ezcUrlConfiguration::AGGREGATE_ARGUMENTS );
* $url = new ezcUrl( 'http://www.example.com/(param1)/x/(param1)/y/z', $urlCfg );
* $param1 = $url->getParam( 'param1' ); // will return array( array( "x" ), array( "y", "z" ) )
* Note: in the examples above, if the URL does not contain the string 'param1',
* then all the unordered parameters from and including param1 will be null,
* so $url->getParam( 'param1' ) will return null (see issue #12825).
* @param array(string) $config An array of unordered parameters names, from the URL configuration used in parsing
* @param int $index The index in the URL path part from where to start the matching of $config
* @return array(string=>mixed)
// holds how many times a parameter name is encountered in the URL.
// for example, for '/(param1)/a/(param2)/x/(param2)/y',
// $encounters = array( 'param1' => 1, 'param2' => 2 );
$urlCfg =
$this->configuration;
$pathCount =
count( $this->path );
if ( $pathCount ==
0 ||
( $pathCount ==
1 &&
trim( $this->path[0] ) ===
"" ) )
// special case: a bug? in parse_url() which makes $this->path
// be array( "" ) if the provided URL is null or empty
for ( $i =
$index; $i <
$pathCount; $i++
)
$param =
$this->path[$i];
$param{0} ==
$urlCfg->unorderedDelimiters[0] )
$param =
trim( trim( $param, $urlCfg->unorderedDelimiters[0] ), $urlCfg->unorderedDelimiters[1] );
if ( isset
( $encounters[$param] ) )
$result[$param][$encounters[$param]] =
array();
while ( ( $i +
$j ) <
$pathCount &&
$this->path[$i +
$j]{0} !=
$urlCfg->unorderedDelimiters[0] )
$result[$param][$encounters[$param]][] =
trim( trim( $this->path[$i +
$j], $urlCfg->unorderedDelimiters[0] ), $urlCfg->unorderedDelimiters[1] );
* Returns this URL as a string.
* The query part of the URL is build with http_build_query() which
* encodes the query in a similar way to urlencode().
* If $includeScriptName is true, then the script name (eg. 'index.php')
* will be included in the result. By default the script name is hidden (to
* ensure backwards compatibility).
* @apichange The default value for $includeScriptName might be changed to
* true in future versions
* @param bool $includeScriptName
public function buildUrl( $includeScriptName =
false )
$url .=
$this->scheme .
'://';
$url .=
':' .
$this->pass;
$url .=
':' .
$this->port;
if ( $this->configuration !=
null )
if ( !( count( $this->basedir ) ==
0 ||
trim( $this->basedir[0] ) ===
"" ) )
$url .=
'/' .
implode( '/', $this->basedir );
if ( $includeScriptName &&
$this->script )
if ( !( count( $this->script ) ==
0 ||
trim( $this->script[0] ) ===
"" ) )
$url .=
'/' .
implode( '/', $this->script );
if ( $this->params &&
count( $this->params ) !=
0 )
$url .=
'/' .
implode( '/', $this->params );
if ( $this->uparams &&
count( $this->uparams ) !=
0 )
foreach ( $this->properties['uparams'] as $key =>
$encounters )
foreach ( $encounters as $encounter =>
$values )
$url .=
'/(' .
$key .
')/' .
implode( '/', $values );
$url .=
'/' .
implode( '/', $this->path );
$url .=
'#' .
$this->fragment;
* Returns true if this URL is relative and false if the URL is absolute.
if ( $this->host ===
null ||
$this->host ==
'' )
* Returns the value of the specified parameter from the URL based on the
* active URL configuration.
* Ordered parameters must appear before unordered parameters in the parsed
* URL, in the same number and order as they are defined in the configuration.
* Unordered parameter examples:
* $urlCfg = new ezcUrlConfiguration();
* // single parameter value
* $urlCfg->addUnorderedParameter( 'param1' ); // type is SINGLE_ARGUMENT by default
* $url = new ezcUrl( 'http://www.example.com/(param1)/x/(param1)/y/z', $urlCfg );
* $param1 = $url->getParam( 'param1' ); // will return "y"
* // multiple parameter values
* $urlCfg->addUnorderedParameter( 'param1', ezcUrlConfiguration::MULTIPLE_ARGUMENTS );
* $url = new ezcUrl( 'http://www.example.com/(param1)/x/(param1)/y/z', $urlCfg );
* $param1 = $url->getParam( 'param1' ); // will return array( "y", "z" )
* // multiple parameter values with aggregation
* $urlCfg->addUnorderedParameter( 'param1', ezcUrlConfiguration::AGGREGATE_ARGUMENTS );
* $url = new ezcUrl( 'http://www.example.com/(param1)/x/(param1)/y/z', $urlCfg );
* $param1 = $url->getParam( 'param1' ); // will return array( array( "x" ), array( "y", "z" ) )
* Ordered parameter examples:
* $urlCfg = new ezcUrlConfiguration();
* $urlCfg->addOrderedParameter( 'param1' );
* $urlCfg->addOrderedParameter( 'param2' );
* $url = new ezcUrl( 'http://www.example.com/x/y', $urlCfg );
* $param1 = $url->getParam( 'param1' ); // will return "x"
* $param2 = $url->getParam( 'param2' ); // will return "y"
* @throws ezcUrlNoConfigurationException
* if an URL configuration is not defined
* @throws ezcUrlInvalidParameterException
* if the specified parameter is not defined in the URL configuration
* @param string $name The name of the parameter for which to return the value
$urlCfg =
$this->configuration;
if ( !( isset
( $urlCfg->orderedParameters[$name] ) ||
isset
( $urlCfg->unorderedParameters[$name] ) ) )
$uparams =
$this->uparams;
if ( isset
( $urlCfg->orderedParameters[$name] ) &&
isset
( $params[$urlCfg->orderedParameters[$name]] ) )
return $params[$urlCfg->orderedParameters[$name]];
if ( isset
( $urlCfg->unorderedParameters[$name] ) &&
isset
( $uparams[$name][0] ) )
if ( count( $uparams[$name][0] ) >
0 )
return $uparams[$name][count( $uparams[$name] ) -
1][0];
$result =
$uparams[$name];
return $uparams[$name][count( $uparams[$name] ) -
1];
* Sets the specified parameter in the URL based on the URL configuration.
* For ordered parameters, the value cannot be an array, otherwise an
* ezcBaseValueException will be thrown.
* For unordered parameters, the value can be one of:
* Any of these values can be assigned to an unordered parameter, whatever the
* parameter type (SINGLE_ARGUMENT, MULTIPLE_ARGUMENTS, AGGREGATE_ARGUMENTS).
* If there are ordered and unordered parameters with the same name, only the
* ordered parameter value will be set.
* $urlCfg = new ezcUrlConfiguration();
* $urlCfg->addUnorderedParameter( 'param1' );
* $url = new ezcUrl( 'http://www.example.com' );
* $url->setParam( 'param1', 'x' );
* echo $url->buildUrl(); // will output http://www.example.com/(param1)/x
* $url->setParam( 'param1', array( 'x', 'y' ) );
* echo $url->buildUrl(); // will output http://www.example.com/(param1)/x/y
* $url->setParam( 'param1', array( array( 'x' ), array( 'y', 'z' ) ) );
* echo $url->buildUrl(); // will output http://www.example.com/(param1)/x/(param1)/y/z
* @throws ezcBaseValueException
* if trying to assign an array value to an ordered parameter
* @throws ezcUrlNoConfigurationException
* if an URL configuration is not defined
* @throws ezcUrlInvalidParameterException
* if the specified parameter is not defined in the URL configuration
* @param string $name The name of the parameter to set
* @param string|array(string=>mixed)$value The new value of the parameter
public function setParam( $name, $value )
$urlCfg =
$this->configuration;
if ( !( isset
( $urlCfg->orderedParameters[$name] ) ||
isset
( $urlCfg->unorderedParameters[$name] ) ) )
if ( isset
( $urlCfg->orderedParameters[$name] ) )
$this->properties['params'][$urlCfg->orderedParameters[$name]] =
$value;
if ( isset
( $urlCfg->unorderedParameters[$name] ) )
if ( !isset
( $this->properties['uparams'][$name] ) )
$this->properties['uparams'][$name] =
array();
foreach ( $value as $part )
$this->properties['uparams'][$name] =
$value;
$this->properties['uparams'][$name][count( $this->properties['uparams'][$name] ) -
1] =
$value;
$this->properties['uparams'][$name][count( $this->properties['uparams'][$name] ) -
1] =
array( $value );
* Returns the unordered parameters from the URL as a flat array.
* It takes into account the basedir, script and ordered parameters.
* It can be used for URLs which don't have delimiters for the unordered
* $urlCfg = new ezcUrlConfiguration();
* $urlCfg->basedir = '/mydir/shop';
* $urlCfg->script = 'index.php';
* $urlCfg->addOrderedParameter( 'module' );
* $url = new ezcUrl( 'http://www.example.com/mydir/shop/index.php/order/Software/PHP/Version/5.2/Extension/XDebug/Extension/openssl', $urlCfg );
* $params = $url->getParams(); // will be array( 'Software', 'PHP', 'Version', '5.2', 'Extension', 'XDebug', 'Extension', 'openssl' )
* Returns the query elements as an associative array.
* for 'http://www.example.com/mydir/shop?content=view&products=10'
* returns array( 'content' => 'view', 'products' => '10' )
* @return array(string=>mixed)
* Set the query elements using the associative array provided.
* for 'http://www.example.com/mydir/shop'
* and $query = array( 'content' => 'view', 'products' => '10' )
* then 'http://www.example.com/mydir/shop?content=view&products=10'
* @param array(string=>mixed) $query The new value of the query part