Ever wished you could avoid the ugly array style $_GET vars in PHP?
1) www.mydomain.com/?cat=1&cat=12&cat=5
Looks so much better than
2) www.mydomain.com/?cat[]=1&cat[]=12&cat[]=5
Unfortunately PHP’s internal storage for GCP $_GET,$_POST,$_COOKIE works like arrays therefor you cannot send the same request variable key more than once as the latter will replace all previous values, i.e:
$_GET['cat'] = 1;
$_GET['cat'] = 12;
$_GET['cat'] = 5; // cat now has only 1 value of 5
Below is a solution I came up with for the Zend Framework, but this can easily be adapted to use in conventional PHP.
1: First create the below class and save it in your Library:
<?php class CC_Controller_Request_Http extends Zend_Controller_Request_Http { /** * Retrieve an array of $_GET parameters with the same key name * * If no match is found an empty array is returned * If the $key is an alias, the actual key aliased will be used. * * @param string $key * @param array $default Default values to use if key not found * @return array */ public function getParamMultiQuery($key, array $default = array()) { $keyName = (null !== ($alias = $this->getAlias($key))) ? $alias : $key; $query = $_SERVER['QUERY_STRING']; $vars = array(); foreach (explode('&', $query) as $pair) { list($qkey, $value) = explode('=', $pair); if($qkey != $keyName || '' == trim($value)){ continue; } $vars[$qkey][] = urldecode($value); } return (count($vars)==0) ? array($keyName=>$default) : $vars; } /** * Retrieve an array of all $_GET parameters by same key name * * @return array */ public function getParamsMultiQuery() { $query = $_SERVER['QUERY_STRING']; $vars = array(); foreach (explode('&', $query) as $pair) { list($key, $value) = explode('=', $pair); if('' == trim($value)){ continue; } $vars[$key][] = urldecode($value); } return $vars; } }
2: In your Application Bootstrap file add the below “highlighted” snippet
<?php class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initAppAutoload() { $moduleLoad = new Zend_Application_Module_Autoloader(array( 'namespace' => '', 'basePath' => APPLICATION_PATH )); } function _initApplication () { $this->bootstrap('frontcontroller'); $front = $this->getResource('frontcontroller'); $front->setRequest('CC_Controller_Request_Http'); }
3: Optionally you can now create a base Controller for all your Controller, this is only for convenience, can be skipped.
<?php class CC_Controller_BaseController extends Zend_Controller_Action { /** * Return an array of values matching 1 parameter in the {@link $_request Request object} * grouped by the same $_GET name * * @param string $key * @param array $default Default values to use if key not found * @return array */ protected function _getParamMultiQuery($key, array $default = array()) { return $this->getRequest()->getParamMultiQuery($key, $default); } /** * Return an array of values matching all parameters in the {@link $_request Request object} * grouped by the same $_GET name * * @return array */ protected function _getParamsMultiQuery() { return $this->getRequest()->getParamsMultiQuery(); } }
4.1: Usage, this is how you would access the Request object to retrieve multiple $_GET values. Use this method only if you applied step 3 with base Controller.
Sample url for this controller: mydomain.com/search/?cat=1233&cat=44&cat=7866&foo=abc&bar=1&cat=32
<?php class SearchController extends CC_Controller_BaseController { public function indexAction() { $allMultiVars = $this->_getParamsMultiQuery(); $multiCats = $this->_getParamMultiQuery('cat'); //echo '<pre>'; print_r($allMultiVars); if(count($multiCats['cat'])){ $model = new Model_Products(); $data = $model->fetchAll('cats_id IN ('.implode(',', $multiCats).')'); }
4.2: Usage, this is how you would access the Request object to retrieve multiple $_GET values. Use this method if you applied step 3 with base Controller OR NOT.
Sample url for this controller: mydomain.com/search/?cat=1233&cat=44&cat=7866&foo=abc&bar=1&cat=3
<?php class SearchController extends Zend_Controller_Action { public function indexAction() { $allMultiVars = $this->getRequest()->getParamsMultiQuery(); $multiCats = $this->getRequest()->getParamMultiQuery('cat'); //the standard ZF way $allZf = $this->_getParams(); $zfCat = $this->_getParam('cat'); /* * $zfCats will always only return 1 value,this is caused by PHP * and not ZF. * Optionally you can pass default array values if nothing is found * $multiCats will be populated and returned */ $multiCats = $this->getRequest()->getParamMultiQuery('cat', array(233,55,1)); //echo '<pre>'; print_r($allMultiVars); if(count($multiCats['cats'])){ $model = new Model_Products(); $data = $model->fetchAll('cats_id IN ('.implode(',', $multiCats).')'); }
Hope this helps someone!