Page 1 of 1

URL Class thingy

Posted: Fri Mar 09, 2007 8:37 am
by Begby
One thing I hate is having to save state on a URL. Sessions are the obvious solution, but sometimes I would like to have page viewers be able to bookmark a page and save the state, or mail the URL. Examples are things like search terms, current page (when viewing a paged list of records) etc. Typically you need to check if the parameters are on the url and make sure to create new URLs with the matching parameters.

So I wrote this simple class. This is only setup for standard non-search friendly URLs like http://www.site.com/index.php?page=2.0. After that I realized that its actually pretty handy for just handling URLs in general and was thinking about adding methods. It also works great with smarty since the object also behaves like a string as far as smarty is concerned.

One thing I was thinking of adding is better functionality for the base page, like being able to specify http:// or https:// as well as using delegates to handle other argument types like search friendly urls.

Code: Select all

/**
 * A class creates urls using oo functionality
 *
 */
class URLThingy implements Countable, IteratorAggregate
{
	
	/**
	 * The url parameters as an associative array
	 *
	 * @var array
	 */
	private $params = array() ;
	
	/**
	 * The base page for the url
	 *
	 * @var string
	 */
	private $basePage ;
	
	
	/**
	 * Constructor
	 *
	 * @param string $basePage Optional base page
	 */
	public function __construct($basePage = 'index.php')
	{
		$this->basePage = $basePage ;
	}
	
	
	/**
	 * Build the object using the current page URL and parameters
	 *
	 */
	public function useCurrentPageURL()
	{
		$this->basePage = $_SERVER['SCRIPT_NAME'] ;
		$this->setParamsFromArray($_GET);
	}
	
	
	/**
	 * Set the base page
	 *
	 * @param string $page
	 */
	public function setBasePage($page)
	{
		$this->basePage = $page ;
	}
	
	/**
	 * Get the url as a string
	 *
	 * @return string
	 */
	public function __toString()
	{
		$formattedParams = array() ;
		foreach($this->params as $param => $value)
		{
			$formattedParams[] = $param.'='.$value ;
		}
		
		return $this->basePage.'?'.implode('&', $formattedParams);
	}
	
	
	/**
	 * Get the value of a parameter
	 *
	 * @param string $paramName
	 * @return string
	 */
	public function __get($paramName)
	{
		return (isset($this->params[$paramName])) ? $this->params[$paramName] : null ;
	}
	
	
	/**
	 * Set the value of a parameter
	 *
	 * @param string $paramName
	 * @param mixed $value
	 */
	public function __set($paramName, $value)
	{
		$this->params[$paramName] = $value ;
	}
	
	
	/**
	 * Unset a parameter
	 *
	 * @param string $paramName
	 */
	public function __unset($paramName)
	{
		unset($this->params[$paramName]) ;
	}
	
	
	/**
	 * Check if a parameter is set
	 *
	 * @param unknown_type $paramName
	 * @return unknown
	 */
	public function __isset($paramName)
	{
		return isset($this->params[$paramName]) ;
	}
	
	
	/**
	 * Set the parameters from an associative array (current parameters in the object are preserverd)
	 *
	 * @param string $paramsArray
	 */
	public function setParamsFromArray($paramsArray)
	{
		foreach( $paramsArray as $param => $value)
		{
			$this->$param = $value ;
		}
	}
	
	
	/**
	 * Get the count of the number of parameters
	 *
	 * @return int
	 */
	public function count()
	{
		return count($this->params) ;
	}
	
	
	/**
	 * Get an iterator for looping over the parameters
	 *
	 * @return ArrayIterator
	 */
	public function getIterator()
	{
		return new ArrayIterator($this->params) ;
	}
	
}

usage

Code: Select all

$url = new URLThingy() ;
echo $url ;
// prints 'index.php?'

$url->prodID = 10 ;
echo $url ;
//prints index.php?prodID = 10 ;


// Lets say you are on the following page - http://www.site.com/dir/list.php?page=2 ... lientID=10
$url = new URLThingy() ;
$url->useCurrentPageURL() ;
echo $url ;
// prints 'dir/list.php?page=2&search=fred&clientID=10' ;

unset($url->clientID)
$url->page=4 ;
echo $url ;
// prints 'dir/list.php?page=4&search=fred

// and then in smarty
$url = new URLThing() ;
$url->userCurrentPageURL() ;
$smarty->assign('link', $url) ;

// within smarty
<a href="{$link}">Click me</a>

Posted: Fri Mar 09, 2007 8:41 am
by feyd
You may want to test the calling of __toString() in various situations as, at least in slightly older versions of PHP 5, it's called only for very specific circumstances.

Posted: Fri Mar 09, 2007 9:19 am
by Begby
feyd wrote:You may want to test the calling of __toString() in various situations as, at least in slightly older versions of PHP 5, it's called only for very specific circumstances.
Yes, in php 5.0 to 5.1 it is called only on a echo or print where the object was the only argument. This is enough to make it work fine in smarty.

Starting in php 5.2 it works in string concatenation like echo '<a href='.$url.'>' ;

Posted: Fri Mar 09, 2007 2:08 pm
by s.dot
That looks pretty nifty!

The only thing I can think of is this line

Code: Select all

return $this->basePage.'?'.implode('&', $formattedParams);
If this were used inside a link, w3c will holler that the ampersand needs to be &.