blob: 31608c1e2a61faaac2d66c836354c889f0f8a48d [file] [log] [blame]
<?php
/**
* File containing the ezcUrlTools 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
* under the License.
*
* @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version //autogen//
* @filesource
* @package Url
*/
/**
* Class providing methods for URL parsing.
*
* Static methods contained in this class:
* - parseQueryString() - It implements the functionality of the PHP function
* parse_str(), but without converting dots to underscores in parameter names.
* - getCurrentUrl() - Returns the current URL as a string from the provided
* array (by default $_SERVER).
*
* @package Url
* @version //autogen//
*/
class ezcUrlTools
{
/**
* Parses the provided string and returns an associative array structure.
*
* It implements the functionality of the PHP function parse_str(), but
* without converting dots to underscores in parameter names.
*
* Example:
* <code>
* $str = 'foo[]=bar&openid.nonce=123456';
*
* parse_str( $str, $params );
* $params = ezcUrlTools::parseQueryString( $str );
* </code>
*
* In the first case (parse_str()), $params will be:
* <code>
* array( 'foo' => array( 'bar' ), 'openid_nonce' => '123456' );
* </code>
*
* In the second case (ezcUrlTools::parseQueryString()), $params will be:
* <code>
* array( 'foo' => array( 'bar' ), 'openid.nonce' => '123456' );
* </code>
*
* @param array(string=>mixed) $str The string to parse
* @return array(string=>mixed)
*/
public static function parseQueryString( $str )
{
$result = array();
// $params will be returned, but first we have to ensure that the dots
// are not converted to underscores
parse_str( $str, $params );
$separator = ini_get( 'arg_separator.input' );
if ( empty( $separator ) )
{
$separator = '&';
}
// go through $params and ensure that the dots are not converted to underscores
$args = explode( $separator, $str );
foreach ( $args as $arg )
{
$parts = explode( '=', $arg, 2 );
if ( !isset( $parts[1] ) )
{
$parts[1] = null;
}
if ( substr_count( $parts[0], '[' ) === 0 )
{
$key = $parts[0];
}
else
{
$key = substr( $parts[0], 0, strpos( $parts[0], '[' ) );
}
$paramKey = str_replace( '.', '_', $key );
if ( isset( $params[$paramKey] ) && strpos( $paramKey, '_' ) !== false )
{
$newKey = '';
for ( $i = 0; $i < strlen( $paramKey ); $i++ )
{
$newKey .= ( $paramKey{$i} === '_' && $key{$i} === '.' ) ? '.' : $paramKey{$i};
}
$keys = array_keys( $params );
if ( ( $pos = array_search( $paramKey, $keys ) ) !== false )
{
$keys[$pos] = $newKey;
}
$values = array_values( $params );
$params = array_combine( $keys, $values );
}
}
return $params;
}
/**
* Returns the current URL as a string from the array $source
* (by default $_SERVER).
*
* The following fields are used in building the URL:
* - HTTPS - determines the scheme ('http' or 'https'). 'https' only if
* the 'HTTPS' field is set or if it is 'on' or '1'
* - SERVER_NAME
* - SERVER_PORT - determines if port is default (80 = do not include port)
* or not default (other than 80 = include port)
* - REQUEST_URI
*
* For example, if $_SERVER has these fields:
* <code>
* $_SERVER = array(
* 'HTTPS' => '1',
* 'SERVER_NAME' => 'www.example.com',
* 'SERVER_PORT' => 80,
* 'REQUEST_URI' => '/index.php'
* );
* </code>
*
* Then by calling this function (with no parameters), this URL will be
* returned: 'http://www.example.com/index.php'.
*
* The source of the URL parts can be changed to be other than $_SERVER by
* specifying an array parameter when calling this function.
*
* @todo check if REQUEST_URI works in Windows + IIS.
* - Use PHP_SELF instead?
* - Or use SCRIPT_NAME + QUERY_STRING?
* - Or even use an ISAPI filter?
* @todo check for proxy servers
* - Use $_SERVER['HTTP_X_FORWARDED_SERVER']?
*
* @param array(string=>mixed) $source The default array source, default $_SERVER
* @return string
*/
public static function getCurrentUrl( array $source = null )
{
if ( $source === null )
{
$source = $_SERVER;
}
$url = '';
if ( isset( $source['HTTPS'] ) &&
( strtolower( $source['HTTPS'] ) === 'on' || $source['HTTPS'] === '1' ) )
{
$url .= 'https://';
}
else
{
$url .= 'http://';
}
$url .= isset( $source['SERVER_NAME'] ) ? $source['SERVER_NAME'] : null;
if ( isset( $source['SERVER_PORT'] ) && $source['SERVER_PORT'] != 80 )
{
$url .= ":{$source['SERVER_PORT']}";
}
$url .= isset( $source['REQUEST_URI'] ) ? $source['REQUEST_URI'] : null;
return $url;
}
}
?>