PHP pass default argument to function - php

I have a PHP function, like this:
function($foo = 12345, $bar = false){}
What I want to do, is call this function with the default argument of $foo passed, but $bar set to true, like this (more or less)
function(DEFAULT_VALUE, true);
How do I do it? How do I pass an argument as a function's default value without knowing that value?
Thanks in advance!

This is not natively possible in PHP. There are workarounds like using arrays to pass all parameters instead of a row of arguments, but they have massive downsides.
The best manual workaround that I can think of is defining a constant with an arbitrary value that can't collide with a real value. For example, for a parameter that can never be -1:
define("DEFAULT_ARGUMENT", -1);
and test for that:
function($foo = DEFAULT_ARGUMENT, $bar = false){}

put them the other way round:
function($bar = false, $foo = 12345){}
function(true);

The usual approach to this is that if (is_null($foo)) the function replaces it with the default. Use null, empty string, etc. to "skip" arguments. This is how most built-in PHP functions that need to skip arguments do it.
<?php
function($foo = null, $bar = false)
{
if (is_null($foo))
{
$foo = 12345;
}
}
?>

PHP can't do exactly that, so you'll have to work around it. Since you already need the function in its current form, just define another:
function blah_foo($bar)
{
blah(12345, $bar);
}
function blah($foo = 12345, $bar = false) { }

i think, it's better sorted based on the argument that the most frequently changed, $bar for example, we put it first,
function foo( $bar = false, $foo = 12345){
// blah blah...
}
so when you want to pass $bar to true, and $foo to 12345, you do this,
foo(true);

Related

Strange behavior with unconventional passing of arguments

I accidentally copied the function header when calling a function in my code, and for some reason the code still works. Why is this?
$data = Utilities::multi_curl($substance_year_combo_groups, $files = false, $download_folder = null, $file_name = null, $pop = false, $handle_key = 'results');
Obviously, it's supposed to be written like this:
$data = Utilities::multi_curl($substance_year_combo_groups, false, null, null, false, 'results');
But I can see in my debugging that the last parameter indeed is 'results'. Shouldn't a pure variable assignment just be evaluated as true?
The $handle_key is null by default in the function header.
Already answered, but to include a reference from PHP: Assignment Operators Manual
The value of an assignment expression is the value assigned. That is, the value of "$a = 3" is 3.
The arguments get evaluated, and the results of those evaluations are passed in.
Remember that in PHP assignments have a "return value", which is the value that was assigned.
$foo = 'bar';
echo $foo;
$result = some_function($foo = 'blah');
echo $foo;
This code will echo out barblah, and pass blah into some_function as the argument.
This is the exact same mechanism that allows:
$a = $b = $c = $d = 42;
to work, and assigns 42 to all four variables.
The result of the assignment operation is the value being assigned. For instance, I can do this:
if($result = do_something_that_may_fail()) {}
Whatever the do_something_that_may_fail() method returns will be assigned to $result and, if that anything that doesn't evaluate to false, the if block will be executed. A byproduct of this is that you can still reference $result inside of the if block.
The same thing is happening in your method call, the values are being assigned and the value itself is being sent to the method.

Setting PHP multidimensional session variable in function

Say I have a function called set_session_variable that looks like:
function set_session_variable($name, $value) {
// ...write value to the specified path
}
How would I write this function (without using an eval) so that I can do something like:
set_session_variable('foo', 'bar'); // Would set $_SESSION['foo'] = 'bar';
set_session_variable('foo[bar][baz]', 'blah'); // Would set $_SESSION['foo']['bar']['baz'] = 'blah';
I highly suggest, that you won't use
set_session_variable('foo[bar][baz]', 'blah');
but instead
set_session_variable('foo', array('bar'=>array('baz' => 'blah')));
Additionally, you don't need a function call for that at all:
$_SESSION['foo']['bar']['baz'] = 'blah';
You can change the implementation of $_SESSION with the session save handler.
If you're only concerned how you could parse a string like 'foo[bar][baz]', this has been asked before, for example use strings to access (potentially large) multidimensional arrays.
A more relevant question is why you need a function at all. Function calls have a cost, and the function doesn't appear to do useful work.
Example assignments:
$_SESSION['foo'] = 'bar';
$_SESSION['foo']['bar']['baz'] = 'blah';
$foo['bar']['baz'] = 'blah';
$_SESSION['foo'] = $foo;
In direct answer to your question: You could parse the value of $name within set_session_variable() using the PCRE module and a regular expression.
Even simpler and faster would be parsing it with sscanf() provided you are able and willing to impose a convention on the naming of array keys.
A cleaner alternative function:
$array['bar']['baz'] = 'blah';
set_session_variable('foo', $array);
function set_session_variable($key, $val) {
$_SESSION[$key] = $val;
}
One way to solve this is to mimic function overloading, example in this post -> PHP function overloading
Another way is to add one string argument to your function, with your array indices delimited.
For example: set_session_variable('foo', 'bar', 'baz;key');
Which saves the value 'bar' into foo['baz']['key'].
All you have to do is tear the 3rd argument apart (i use ; as delimiter here).

Function to set default value of associative array if the key is not present

Is there a function in PHP to set default value of a variable if it is not set ?
Some inbuilt function to replace something like:
$myFruit = isset($_REQUEST['myfruit']) ? $_REQUEST['myfruit'] : "apple" ;
PHP kind of has an operator for this (since 5.3 I think) which would compress your example to:
$myFruit = $_REQUEST['myfruit'] ?: "apple";
However, I say "kind of" because it only tests if the first operand evaluates to false, and won't suppress notices if it isn't set. So if (as in your example) it might not be set then your original code is best.
The function analogous to dictionary.get is trivial:
function dget($dict, $key, $default) {
return isset($dict[$key]) ? $dict[$key] : $default;
}
For clarity, I'd still use your original code.
Edit: The userland implementation #2 of ifsetor() at http://wiki.php.net/rfc/ifsetor is a bit neater than the above function and works with non-arrays too, but has the same caveat that the default expression will always be evaluated even if it's not used:
function ifsetor(&$variable, $default = null) {
if (isset($variable)) {
$tmp = $variable;
} else {
$tmp = $default;
}
return $tmp;
}
As far as i know there exists nothing like this in PHP.
You may implement something like this yourself like
$myVar = "Using a variable as a default value!";
function myFunction($myArgument=null) {
if($myArgument===null)
$myArgument = $GLOBALS["myVar"];
echo $myArgument;
}
// Outputs "Hello World!":
myFunction("Hello World!");
// Outputs "Using a variable as a default value!":
myFunction();
// Outputs the same again:
myFunction(null);
// Outputs "Changing the variable affects the function!":
$myVar = "Changing the variable affects the function!";
myFunction();
You could also create a class implementing the ArrayAccess, which you pass 2 arrays during construction ($_REQUEST and an array with defaults) and make it choose the default value transparently.
Btw., relying on $_REQUEST is not a wise idea. See the manual on $_REQUEST for further information.
Instead of testing, if a key not exists and then return a default value, you can also fill your array with this values, before accessing it.
$expectedKeys = array('myfruit');
$requestData = array_merge (
array_combine(
$expectedKeys,
array_fill(0, count($expectedKeys), null)),
$_REQUEST);
$postData is now an array with all keys you expect (specified by $expectedKeys), but any entry, that is missing in $_REQUEST is null.
$myFruit = $requestData['myfruit'];
if (is_null($myFruit)) {
// Value not exists
}
But I also recommend to just stay with the ternary operator ?:.
There is a function called ife() in the CakePHP framework, you can find it here http://api13.cakephp.org/view_source/basics.php/, it is the last function!
You can use it like this:
echo ife($variable, $variable, 'default');

create_function with default parameter values?

Ok, I'm looking into using create_function for what I need to do, and I don't see a way to define default parameter values with it. Is this possible? If so, what would be the best approach for inputting the params into the create_function function in php? Perhaps using addslashes?
Well, for example, I have a function like so:
function testing($param1 = 'blah', $param2 = array())
{
if($param1 == 'blah')
return $param1;
else
{
$notblah = '';
if (count($param2) >= 1)
{
foreach($param2 as $param)
$notblah .= $param;
return $notblah;
}
else
return 'empty';
}
}
Ok, so how would I use create_function to do the same thing, adding the parameters and their default values?
The thing is, the parameters are coming from a TEXT file, as well as the function itself.
So, wondering on the best approach for this using create_function and how exactly the string should be parsed.
Thanks :)
Considering a function created with create_function this way :
$func = create_function('$who', 'echo "Hello, $who!";');
You can call it like this :
$func('World');
And you'll get :
Hello, World!
Now, having a default value for a parameter, the code could look like this :
$func = create_function('$who="World"', 'echo "Hello, $who!";');
Note : I only added the default value for the parameter, in the first argument passed to create_function.
And, then, calling the new function :
$func();
I still get :
Hello, World!
i.e. the default value for the parameter has been used.
So, default values for parameters work with create_function just like they do for other functions : you just have to put the default value in the list of parameters.
After that, on how to create the string containing the parameters and their values... A couple of string concatenations, I suppose, without forgetting to escape what should be escaped.
Do you want to create an anonymous function? The create_function is used to create the anonymous functions. Otherwise you need to create function normally like:
function name($parms)
{
// your code here
}
If you want to use the create_function, here is the prototype:
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
// outputs
// New anonymous function: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599
I'm having the same problem, trying to pass an array to a created callback function... I think I'll create a temporary variable... It's ugly but I have better to do then torture myself with slashes, my code is already cryptic enough the way it is now.
So, to illustrate:
global $tmp_someArray;
$tmp_someArray = $someArray;
$myCallback = create_function(
'$arg1',
'
global $tmp_someArray;
// do stuff with $tmp_someArray and $arg1....
return($something);
'
);

PHP Returning References

Returning by reference is useful when
you want to use a function to find to
which variable a reference should be
bound. Do not use return-by-reference
to increase performance. The engine
will automatically optimize this on
its own. Only return references when
you have a valid technical reason to
do so.
whats does the bolded mean?
does it refer to something like
public function &getHellos() {
$sql = 'SELECT id, greeting FROM #__hello';
$data = $this->_getList($sql);
return $data;
}
where i am not binding to any variable?
We return by reference when we want the function GetRef() to decide which variable, $foo or $bar, the reference $foo_or_bar should be bound:
$foo = "foo";
$bar = "bar";
function &GetRef(){
global $foo, $bar;
if(rand(0, 1) === 1){
return $foo;
}else{
return $bar;
}
}
$foo_or_bar =& GetRef();
$foo_or_bar = 'some other value';
var_dump($foo); // either one of this will be 'some other value'
var_dump($bar); // either one of this will be 'some other value'
Derick Ethans also elaborated on this in "References in PHP: An In-Depth Look":
This [returning by reference] is useful, for example, if you want to
select a variable for modification with a function, such as selecting
an array element or a node in a tree structure.
Example code demonstrating selecting array element via return-by-reference:
function &SelectArrayElement(&$array, $key){
return $array[$key];
}
$array = array(0, 1, 2);
$element =& SelectArrayElement($array, 0);
$element = 10;
var_dump($array); // array(10, 1, 2)
Na. You can't pass a reference to a function name.
When passing a variable by reference, if you change it's value in your function, it's value will also be changed outside of the function.
For example :
function test(&$var) {
$var = strtolower($var);
}
function second_test($var) {
$var = strtolower($var);
}
$var = 'PHP';
second_test($var);
echo $var;
echo "\r\n";
test($var);
echo $var;
This will display :
PHP
php
As the second_test method doesn't have the variable passed by reference, it's updated value is only updated inside the function.
But the test method as the variable passed by reference. So it's value will be updated inside and outside of this function.
I believe it's referring to byref arguments not functions. For example this:
function doStuff(&$value1, &$value2) {
...
}
is an acceptable use of byref because the doStuff() function has to return 2 values. If it only doStuff() only needed to affect one value, it would be more elegant to have the function return it, by value, of course.
The bolded part means it's useful if you want to keep a reference to a variable, instead of the value of this variable.
The example about returning references, on php.net, explains it pretty well, IMO.

Categories