How to pass parameters as a query string to your PHP functions
Many programming languages allow one to pass named parameters or keyword arguments to functions. Using named parameters provides the advantage of not having to worry about the order of your parameters. While I find passing an array of named parameters preferable to ordered parameters, query strings are another way to use named parameters and shorten the setup for your function calls.
Many WordPress functions allow you to pass parameters using query strings. What does that mean exactly? Key/pair values, just like you often see in a URL query string, e.g.
Below I will show a few examples of options for passing params to functions. Then I will provide a “parse_args()” function that lets me process the query string params in my functions.
Option 1: Ordered parameters
/** ordered parameters */
function get_tweets($var1,$var2,$var3){
// validate the params and make use of them.
// Order matters when you pass them in.
}
/** calling it */
get_tweets("arg1","arg2","arg3");
/** OR */
$arg1 = "barackobama";
$arg2 = "10";
$arg3 = "false";
get_tweets($arg1,$arg2,$arg3);
You can spice up ordered parameters a bit by using the native PHP functions:
func_get_args() // get array of all args
func_num_args() // get length of args
func_get_arg() // get specific argument from arguments array
Option 2: Pass an array and extract from within
Advantages: Unlike ordered params, you don’t need to worry about the order of your arguments. You also can have a varying number of arguments.
/**Setup an array of parameters and extract them from inside function.*/
function get_tweets($array){
extract($array)
// array keys are exposed now as variables
};
/** Setup */
$array=array(
"twitter_user" => "barackobama",
"number_of_tweets"=>"10",
"date" => "2010-11-01"
);
/** Calling it */
get_tweets($array);
Note: If one of your params is an array of data, you need to use the above approach. After passing the associative array of params to your function, you can use the php function extract() to get turn the array keys into variables. The query string params approach below will not work if you are passing an array of data. **Unless you serialize() your array before concatenating the final query string and passing the params to your function. Then inside the parse_args(), you'd need to revise it to test whether any of the params can be unserialized().
Option 3: Query-string-style params
Advantages: Less typing and preparation before executing functions()
Using query string parameters gets you the advantages noted for using Arrays – variable length and order of argument list – and also allows you to shorten the preparation required to setup your function calls.
function get_tweets($args){
extract( parse_args($args) );
// array keys are exposed now as variables
};
/** Setup, store query string args in variable*/
$var = "twitter_user=barackobama&number_of_tweets=3&date=2010-11-01";
get_tweets($var);
/** OR pass directly */
get_tweets("user=zeldman&limit=3&date=2010-11-15");
Implementation: A parse_args() function
/**
*
* parse_args($args) parses query string style params
* and returns array.
* @param String Your params as a string.
* E.g. 'day=10&month=11'
* @uses explode() to separate query string into key/pair
* @description Call this function inside your own
* functions to get an array of args passed, even
* though you didn't pass an array or multiple params.
* @return Array
*
*
*/
function parse_args($args){
if( empty($args) ):
throw new Exception("\n\nfunction parse_args() expects you to pass a param\n\n");
elseif( !is_string($args) ):
throw new Exception("\n\nfunction parse_args() expects a string, ". gettype($args). " passed\n\n");
endif;
// array to store our parsed args
$parsed = array();
// confirm there is at least one param, in format we expect
if( !strpos($args,"=") ):
// if not, trigger exception
$msg="\n\nfunction parse_args() expects query string params. \n\n";
$msg.="String passed does not contain any assignments using = operator\n\n";
throw new Exception($msg);
elseif( strpos($args,"&") ):
// if str contains &, assume multiple params
$parts = explode("&",$args);
for( $i=0, $len=count($parts); $i<$len; $i++ ):
$tmp = explode("=",$parts[$i]);
$parsed[$tmp[0]] = $tmp[1];
endfor;
else:
$tmp = explode("=",$args);
$parsed[$tmp[0]] = $tmp[1];
endif;
return $parsed;
}
function get_tweets($args){
/* parse our query string-style params & return
an array to php's native extract() function */
extract(parse_args($args) );
/** Now, after calling extract(), following items from this string -
"twitter_user=barackobama&number_of_tweets=3&date=2010-11-01"
- are now available to you as variables:
$user; // 'barackobama'
$number_of_tweets; // 3
$date; // 2010-11-01
*/
}
Modify parse_args() to return early if an array is passed
The next step I think would be to build in support for arrays, so you can call parse_args() on either query string params or an array of params. This wouldn't take much work and would provide even more flexibility and wider application. Here's an attempt, seems to work, which tests if an array has been passed in. If an array was passed, we return right away since there is no point in evaluating any more code.
function parse_args($args){
if( empty($args) ):
throw new Exception("\n\nfunction parse_args() expects you to pass a param\n\n");
elseif( is_array( func_get_arg(0) ) ):
/* return right away if param itself is an array */
return func_get_args();
elseif( !is_string($args) ):
throw new Exception("\n\nfunction parse_args() expects a string, ". gettype($args). " passed\n\n");
endif;
// array to store our parsed args
$parsed = array();
// confirm there is at least one param, in format we expect
if( !strpos($args,"=") ):
// if not, trigger exception
$msg="\n\nfunction parse_args() expects query string params. \n\n";
$msg.="String passed does not contain any assignments using = operator\n\n";
throw new Exception($msg);
elseif( strpos($args,"&") ):
// if str contains &, assume multiple params
$parts = explode("&",$args);
for( $i=0, $len=count($parts); $i<$len; $i++ ):
$tmp = explode("=",$parts[$i]);
$parsed[$tmp[0]] = $tmp[1];
endfor;
else:
$tmp = explode("=",$args);
$parsed[$tmp[0]] = $tmp[1];
endif;
return $parsed;
}
Thanks to Ryan Bagwell for helping me formulate this post. Find Ryan: @ryanbagwell, http://www.ryanbagwell.com/