Location: PHPKode > scripts > path to vars > path-to-vars/class.pathToVars.php
<?php
	
/*!

class: pathToVars
released: 05-08-2002
author: kumar mcmillan (hide@address.com)


****description: 
allows you to use a pseudo directory path in your HTML links --instead of a query string-- to declare variables so that your pages will be properly crawled by search engines.  This is an alternative to using mod_rewrite rules to handle your URLs (http://httpd.apache.org/docs/mod/mod_rewrite.html).  I based this on several articles and news posts I read on how search engines crawl dynamic, php-generated URLs.

links to the articles are here:
http://www.phpwizard.net/resources/tutorials/dynamic_and_searchengines.html
http://www.phpbuilder.com/forum/read.php3?num=2&id=124088&loc=0&thread=124088
http://www.sitepointforums.com/showthread.php?s=&threadid=15798

****usage:
see the example script.  it was reported that googlebot (google.com's search engines) will not crawl URLs that end in a directory but no trailing slash.  
for example,
http://somesite.com/index.php/fake_dir/fake_for_variable 
will not be crawled, but 
http://somesite.com/index.php/fake_dir/fake_for_variable/
will, according to one article.

I couldn't find any definitive info on how URLs which carry session IDs (or that end in ?something=something) are crawled.  if you know, please let me know.  I've noticed recently from stats that googlebot _has_ crawled URIs of mine which include query strings so it's possible googlebot, at least, recognizes query strings (but not sure about other crawlers and the crawl I saw from stats wasn't on a URI that passes a session ID).  the pseudo-directory method still ups your odds of getting crawled, I would imagine.  

it seems that pages which end in '.php' are usually crawled by most search engines so I'm not sure if using the '.html' suffix is necessary.

more on robots:
http://www.google.com/bot.html
http://www.robotstxt.org/wc/robots.html

this class was written for http://chicagomodular.com , so you can go to the site to see how it's working.


****security:
see using register_globals chapter in the manual for security reasons brefore running this class
http://www.php.net/manual/en/security.registerglobals.php
this script is most secure with register_globals = off

****converting a query string website:
to convert a website's URIs to use this path to variable method, first see the methods createPTV_SELF() and createPTV_SELF_Q(), these may be helpful.  you will certainly need to change img src paths from being relative to being absolute.  for example src="images/some.gif" needs to be src="/images/some.gif"

****requirements:
PHP >= 4.0.0 (uses is_array() )

****warning: 
this probably won't work with windows because there is some path work
that I think is UNIX-specific.  please test first.

****known issues:
you can't declare global array elements to be set with the varLookup() method 
(a workaround for that is in the example)


license: The GNU General Public License (GPL)
http://www.opensource.org/licenses/gpl-license.html

!*/

class pathToVars
{
	// public:
	var $useVarLookupMethod = FALSE; // see varLookup() = more fexibility but you have to write lookups
	var $useVar_ValueMethod = FALSE; // see var_value() = this is fastest and easiest to code
	var $useBothMethods = TRUE;
	var $DeBug = FALSE; // shows you which variables are created 
						// -- make sure this is false when you are not testing otherwise pages which 
						// pass a lot of variables will load slower
	
	// private:
	var $lookup = array(array());
	var $regexLookup = array(array());
	var $extractedPathParts = array();
	var $varPath = '';
	var $varsCreated = array();
	
	// constructor:
	function pathToVars()
	{
		// PHP < 4.1.0
		if(!function_exists("array_key_exists"))
		{
			function array_key_exists($key, $array, $value = false) {
            	while(list($k, $v) = each($array))
            	{
            		if($key == $k)        {
                    if($value && $value == $v)
                    	return true;
                    else if($value && $value != $v)
                    	return false;
                    else
                    	return true;
                    }
            	}
            	return false;
           	}
		}
	}
	
	// public:
	// param: string [class variable to set]
	// param: mixed [variable value] 
	function set($var,$value)
	{
		$this->$var = $value;
	}
	
	// public:
	// param: string [extracted path part to look up]
	// (...if lookup is found:)
	// param: array [global var name => value to set (you can leave this blank 
	// 													to take the value of the input you are looking up; 
	// 													see the example script)...]
	function createLookup($lookup,$varsToSet)
	{
		if(!is_array($varsToSet)){
			return FALSE;
		} else {
			foreach($varsToSet as $varToSet => $value){
				// __LOOKUP__ is a special value that resolves to the input (the pseudo-dirname):
				if(empty($value)) $value = "__LOOKUP__"; 
				$this->lookup[$lookup][$varToSet] = $value;
			}
			return TRUE;
		}
	}
	
	// public:
	// param: string [regex to perform on all extracted path part]
	// (...if expression is matched for a given path part:)
	// param: array [global var => value to set (you can leave this blank 
	// 								to take the value of the input you are looking up; 
	// 								see the example script)...]
	function createRegexLookup($regexLookup,$varsToSet)
	{
		if(!is_array($varsToSet)){
			return FALSE;
		} else {
			foreach($varsToSet as $varToSet => $value){
				if(empty($value)) $value = "__LOOKUP__"; 
				$this->regexLookup[$regexLookup][$varToSet] = $value;
			}
			return TRUE;
		}
	}
	
	// public:
	// (call this after you've created all your lookups to set the global variables)
	function setVars()
	{
		global $HTTP_SERVER_VARS;
		$this->varPath = (isset($HTTP_SERVER_VARS['PATH_INFO'])) ? $HTTP_SERVER_VARS['PATH_INFO']: "";
		if(!empty($this->varPath))
		{
			// build array with one pseudo-directory per index:
			$this->extractedPathParts = explode("/",$this->varPath);
			
			// make the variable declarations:
			if($this->useBothMethods){
				$this->var_value();
				$this->varLookup();
			}
			elseif($this->useVar_ValueMethod){
				$this->var_value();
			}
			elseif($this->useVarLookupMethod){
				$this->varLookup();
			} else {
				return FALSE;
			}
		} // end if thisFilename is not empty
		$this->createPTV_SELF(); // see the method
		$this->createPTV_SELF_Q(); // see the method
		return TRUE;
	}
	
	// public:
	// (call this after you've called setVars() for DeBug)
	// returns an array of names to the variables created from the path
	function getVarsCreated()
	{
		return (!empty($this->varsCreated)) ? $this->varsCreated: FALSE;
	}
	
	// private:
	function var_value()
	{
		foreach($this->extractedPathParts as $key => $part){
			if($this->useBothMethods){
				// check that this var_value hasn't been declared in createLookup()
				if(!array_key_exists($part,$this->lookup)){
					if(ereg("_",$part)){
						list($var,$value) = explode("_",$part);
						$GLOBALS[$var] = $value;
						unset($this->extractedPathParts[$key]);
						$this->varCreated($var);
					}
				}
			} else {
				list($var,$value) = explode("_",$part);
				$GLOBALS[$var] = $value;
				$this->varCreated($var);
			}
		}
	}
	
	// private:
	function varLookup()
	{
		foreach($this->extractedPathParts as $lookup)
		{
			if(!empty($lookup)){
				// for each pseudo-dirname, set the corresponding var=>val pairs:
				if(!empty($this->lookup)){
					if(array_key_exists($lookup,$this->lookup)){
						foreach($this->lookup[$lookup] as $key => $val){
							$GLOBALS[$key] = ($val=="__LOOKUP__") ? $lookup: $val;
							$this->varCreated($key);
						}
					}
				}
				// for each pseudo-dirname that matches the regex, 
				// set the corresponding var=>val pairs:
				if(!empty($this->regexLookup)){
					foreach($this->regexLookup as $regex => $lookupsToSet){
						if(eregi($regex,$lookup)){
							foreach($lookupsToSet as $key => $val){
								$GLOBALS[$key] = ($val=="__LOOKUP__") ? $lookup: $val;
								$this->varCreated($key);
							}
						}
					}
				}
			}
		}
	}

	// private:
	function varCreated($var)
	{
		if($this->DeBug) $this->varsCreated[] = $var;
	}
	
	// private:
	// creates a global variable PTV_SELF, for you to use in your scripts
	// this is just $PHP_SELF without the path_info you used for your variables, 
	// this may be helpful when converting a site to use PathToVars()
	function createPTV_SELF()
	{
		$GLOBALS['PTV_SELF'] = str_replace($this->varPath,"",$GLOBALS['PHP_SELF']);
		return TRUE;
	}
	// private:
	// creates a global variable PTV_SELF, for you to use in your scripts
	// this is just $PHP_SELF without the path_info but preserving the query string that was passed 
	// this may be helpful when converting a site to use PathToVars()
	function createPTV_SELF_Q()
	{
		$GLOBALS['PTV_SELF_Q'] = str_replace($this->varPath,"",$GLOBALS['PHP_SELF']);
		if(getenv('QUERY_STRING')) $GLOBALS['PTV_SELF_Q'] .= "?".getenv('QUERY_STRING');
		return TRUE;
	}
} // end of class

?>
Return current item: path to vars