In PHP, when defining a function what is the maximum number of arguments that you can create? This isn't something I am doing, just a question that popped up when discussing it with a colleague :)
Would this be purely down a memory limitation? effectively unlimited?
There is no limit. And you can always use func_get_args(), func_get_arg() and func_num_args() to avoid writing all the arguments in the function definition.
Arguments to a function are pushed on a stack, after which the function is called which in turn reads the stack and uses those values as parameters.
So as long as the stack isn't full, you can keep adding parameters, but it'll depend on the situation, and at design-time you won't know the stack size.
But I really hope this is pure a technical discussion and you don't need it IRL. ;-)
when defining a function what is the maximum number of arguments that you can create?
I'm not aware of specific limit in the number of arguments as a fixed number. A quick test revealed that I had no problems to define a function with 255 555 arguments. It does take some time to define the function and to execute it. However, it works.
As the number was raised, I was running into a memory limit which could be string limit. You might want to improve the test-case, use a buffer and save the file to disk sequentially and include it then:
$count = 255555;
$code = 'function test(%s) {return 1;}; return test();';
$params = ltrim(implode('=0, $p', range(0, $count)), '0, =').'=0';
echo eval(sprintf($code, $params));
I don't really know what are the limits, but either way, if you create a function with too many arguments your code will not be so easy to read it. In case you like to add many function arguments you can do something like that:
$option = array(
'arg_1' => 'value',
'arg_2' => 'value',
....
'arg_x' => 'value'
);
function function_name($args = "")
{
$defaults = array(
'arg_1' => 'default_value',
'arg_2' => 'default_value'
....
'arg_x' => 'default_value'
);
$arguments = array_merge($defaults, (array)$args);
extract($arguments);
echo $arg_1;
echo $arg_x;
}
Related
I need to create a function which will have large amount of parameters can be null or value. Now I am creating function as below example:
function container($args){
$args += array(
'limit' => 10,
'container' => null,
'container_class' => null,
'list_class' => null,
);
echo'<'.$args['container'].' class="'.$args['container_class'].'" >';
echo 'My function will have other content here with the '.$args['limit'];
echo '<ul class="'.$args['list_class'].'" >';
echo '<li>list itme here</li>';
echo '</ul>'
echo '</'.$container.'>';
}
This is fine if I have to pass 4-5 value in array but what if I have more than 15-20 key to pass? There must be some appropriate way to achieve.
So how can I create a function in such efficient way to pass many array key as a parameters?
Thanks a lot
15-20 keys is not really a big array. When you need to think about how to pass something into args it's when you have 1000+ keys.
Anyway you can use "Passing by reference" concept (see http://php.net/manual/en/language.references.pass.php). This concept is useful when you have to modify the variable into function without any returning statment.
But to achieve this goal, instead of sending a copy of your variable, PHP just send a key that reference the variable in memory.
And this key does not depend of the size of the variable.
How to use? By using & symbol in your function declaration
ex:
function container(&$args)
{
// your function
}
$args = array(1, 2, 3 ..., 100000);
container($args);
But if you use "Passing by reference" concept be careful to do not modify the $args or $args will be modify on the main script.
Final world: if you have less than 50 keys do not care about how to pass your args, just use by copy (default behavior) will be safer!
The last statement of Kakawait is true.
You should use $args instead of &$args while calling function.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Any way to specify optional parameter values in PHP?
just randomly came across this.
If I have a function like so:
public function getSomething($orderBy='x', $direction = 'DESC', $limit=null){
//do something random
}
When calling the function is it possible to ignore the first two fields and leave them default yet specify the 3rd.
For example:
$random = $this->my_model->getSomething(USE_DEFAULT, USE_DEFAULT, 10);
I know I can pass the 1st and 2nd parameters but all im asking is if their is some kind of special keyword that just says use the default value.
Hope that makes sense. its not a problem, just curious.
thanks for reading
You need to do that yourself. You can use null to indicate that a default value should be used:
public function getSomething($orderBy = null, $direction = null, $limit = null) {
// fallbacks
if ($orderBy === null) $orderBy = 'x';
if ($direction === null) $direction = 'DESC';
// do something random
}
Then pass null when calling it to indicate that you want to use the defaults:
$random = $this->my_model->getSomething(null, null, 10);
Another possible solution that I use sometimes is an additional parameter at the very end of the parameter list, containing all optional parameters:
public function foo($options = array()) {
// merge with defaults
$options = array_merge(array(
'orderBy' => 'x',
'direction' => 'DESC',
'limit' => null
), $options);
// do stuff
}
That way you do not need to specify all optional arguments. array_merge() ensures that you are always dealing with a complete set of options. You would use it like this:
$random = $this->my_model->foo(array('limit' => 10));
It seems like there is no required parameter this particular case, but if you need one, simply add it in front of the optional ones:
public function foo($someRequiredParameter, $someOtherRequiredParameter, $options = array()) {
// ...
}
Honestly, this becomes a problem when functions are trying to do too much. There's almost always a better design pattern when you see a function grow to more than a few parameters (usually it's the poor guy that inherited the old code, and appending parameters is this quickest way to "get the job done").
Elusive's answer is the best according to your question, but take a look at cyclomatic complexity:
http://en.wikipedia.org/wiki/Cyclomatic_complexity
This is a good way to know if your function is doing too much, which makes your question less of a problem than it probably is now.
I don't think PHP can do this. The best solution that I know of is outlined here:
http://www.php.net/manual/en/functions.arguments.php#70511
You cannot ignore params. But you can do something Like this:
public function getSomething($limit=null){
return $this->getSomething('x','DESC',$limit);
}
public function getSomething($orderBy='x', $direction = 'DESC', $limit=null){
...
}
see ya
in PHP, I'm considering doing something like this:
function foo(){
echo 'bar';
}
$fn = 'foo';
$fn();
It works, but is it considered bad practice?
I have an multidimensional array of elements that each have a corresponding function. I would like to store that function name, and call the corresponding functions for each element when traversing the array.
something like:
function render_el1(){ echo 'et';}
function render_el2(){ echo 'to';}
$elements = array(
'el_1' => array(
'name' => 'Element One'
, 'func' => 'render_el1'
)
, 'el_2' => array(
'name' => 'Element Two'
, 'func' => 'render_el2'
)
);
foreach($elements as $element => $options){
$fn = $options['func'];
echo '<h1>'.$options['name'].'</h1>';
if (function_exists($fn)) {
$fn();
}
}
Any comments to this approach is highly welcome, and I'd also like to know what this method is called in programming terms.
Not sure it is bad practice, but it makes your code hard to understand : to understand your short (5 lines) example, I've had to think :-(
Using call_user_func() and other functions of the same kind could have at least one advantage : looking at the code, one would immediatly understand you are calling a function in a way that's not the one we're generally used to.
You want to register functions into an array in your second example and then call them for what looks like a render process. This is similar to using function pointers in C (or paint event callbacks etc). It is an okay approach if you don't want to/can't use polymorphism (the feature that makes OOP worthwhile).
Your approach is simpler at that stage, but will probably get more bloated if you are adding more sophisticated code.
Being new to PHP, and with a lot riding on this "function wrapper", I thought I'd get a few opinions and a little feedback. I'd like to get about five comments, if possible.
Now before you ask, I have many reasons for wanting to wrap other (WordPress) functions, the primary being hassle-free upgrading. It was also important for me to be able to set a custom name for each function definition, hence the $wrap array.
But I digress, does this look acceptable and relatively bulletproof?
function core_oo( $function )
{
$args = array_slice( func_get_args(), 1 );
$wrap = array
(
'comment' => 'the_comment',
'comments' => 'have_comments',
'post' => 'the_post',
'posts' => 'have_posts'
);
return call_user_func_array( $wrap[ $function ], $args );
}
... and the function will be called like...
core_oo( 'post', 'arg1', 'arg2' );
Many thanks!
EDIT:
Per chaos's sugeestion below, is this the right way to declare $wrap as static?
static $wrap = array
( ...
Well, your fundamental aim seems like madness, but with your fundamental aim taken as a given, yes, that function looks like a fine way to accomplish it.
You should declare $wrap as static to ensure that you're not pointlessly regenerating the array every time the function is called, though.
And this:
if(!isset($wrap[$function]))
trigger_error('No underlying function known for ' . $function, E_USER_ERROR);
would probably be smart too.
I happened to be making some changes to a WordPress blog and noticed that they use parse_str (http://php.net/parse_str) for parsing and setting their optional parameters to a function.
I'm wondering if there is an advantage to this over sending an array?
Examples:
With array:
$blahOptions = array(
'option_1' => true,
);
BlahArray($blahOptions);
function BlahArray($options = array()) {
$defaults = array(
'option_1' => false,
'option_2' => 'blah',
);
// this would probably be in a function to be used everywhere
foreach ($defaults as $defaultOption => $defaultValue) {
if (!isset($options[$defaultOption])) $options[$defaultOption] = $defaultValue;
}
}
With parse_str:
$blahOptions = 'option_1=1';
BlahString($blahOptions);
function BlahString($options = '') {
$defaults = array(
'option_1' => false,
'option_2' => 'blah',
);
parse_str($options, $defaults);
$options = $defaults;
}
No. That seems like a ridiculous way to pass functional parameter arguments. I could understand it if you needed to recreate $_GET or $_POST variables or something along those lines, but for parameters to a function? That's code smell right there.
They should be using an array, and then utilizing extract() instead. I've worked with Wordpress before, and my advice is to keep the code at arm's length. It is not an example of model programming.
No. There are more disadvantages than advantages.
When you’re using a single string, you just can pass string values. With an array you can use every PHP data type and every element’s value type is independently of each other.
With parse_str, you can potentially drop in the query string from the URL, and the function will work. If you use an array, and you want to use the query string, you'll have to enumerate everything into an array before calling the function.
I'm not totally convinced it's the best way to go, but I see how it can add a bit of flexibility.