URL Class thingy

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
Begby
Forum Regular
Posts: 575
Joined: Wed Dec 13, 2006 10:28 am

URL Class thingy

Post 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>
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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.
Begby
Forum Regular
Posts: 575
Joined: Wed Dec 13, 2006 10:28 am

Post 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.'>' ;
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post 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 &.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
Post Reply