php: issue with pass values to parameter - php

option 1:
<?php
function hookRequest($func, $params = array()){
var_dump($func);
var_dump($params);
}
hookRequest('func1', array('param1', 'param2'));
option 2:
<?php
function hookRequest($func, $params){
var_dump($func);
var_dump($params);
}
hookRequest('func1', array('param1', 'param2'));
Question:
Both of above scripts can work. But I saw some scripts use this way: $params = array(), so just want to find out what is the difference between $params = array() and $params ?

If you don't pass anything into option1
hookRequest('func1');
then the $params is now an empty array.
function foobar($something,$foo = 'var')
{
var_dump($something,$foo);
}
foobar('something');
Output:
string(9) "something" string(3) "var"

Have a look on the "Function Arguments" basics in
http://php.net/manual/en/functions.arguments.php

The difference is that option 1 makes the second parameter optional, so that you can leave out the second option and the default value will be given to $param.
Option 2 makes the second parameter required, and will return a warning if you don't provide at least two parameters, e.g.
Warning: Missing argument 2 for hookRequest

It's called default parameters in PHP.
When you declare your function, hookRequest($func, $params = array()){... the $paramas = array() tell it to set it as an array when the passed parameter is blank.

Related

Looking for function similar to array_map but which the same arg each time to the callback

As someone who is learning PHP I was experimenting with the arrap_map function. I was hoping that it would pass the same 3rd arg each time through to the called function. As below, this is not the behaviour of array_map. Is there an alternative function I can use to achieve this?
$arr = [['a'], ['b'], ['c']];
$args = ['set'];
function mapper($item, $arg){
return $item[] = $arg;
}
$result = array_map('mapper', $arr, $args);
only the first element has 'set' as a value
$arr = [['a'], ['b'], ['c']];
$args = ['set', 'set', 'set'];
function mapper($item, $arg){
return $item[] = $arg;
}
$result = array_map('mapper', $arr, $args);
all three elements have 'set' as a value
Your code is incorrect, $a[$b] doesn't make any sense. Both variables are strings.
Your output also doesn't make sense, quoting from the manual:
If more than one argument is passed then the returned array always has
integer keys.
To answer your question, it's a language design choice.
It could
pass NULL for missing elements (that was PHP does).
throw an error if the inputs don't have the same size.
cycle the smaller inputs.
All these have valid applications and their own problems.

how arguments are passed to codeigniter method

I have a method in a codeigniter controller which is sometimes called through the url and sometimes called internally from another method of the controller. When I call it internally I pass an array of arguments. Simplified version of method:
(within a controller)
function get_details($args='') {
if (isset($args['first_name']))
{
$first_name = $args['first_name'];
}
else
{
$first_name = $this->uri->segment(3);
}
... do some other stuff ...
}
The method is either called as:
<domain>/<controller>/get_details/abcd/efgh
or from another function of the controller as:
$this->get_details(array('first_name'=>'abcd', 'last_name'=>'efgh'));
I was expecting that when the method was called through the url, isset($args['first_name']) would be false, however it seems that called in this way the argument is there. I tried printing a couple of things and this is what I got:
print_r($args) ----> abcd
echo($args['first_name']) ----> a
echo($args['whatever_index_I_use']) ----> a
It seems like the third parameter of the url is being passed into the method (by codeigniter?), but can't work out why the array indexes seem to be set, all I can think is that php is converting the string to an int, so $args['whatever_index_I_use'], becomes $args[0]??
Not sure if this is a codeigniter thing or me missing a subtlety of php.
Much appreciate anyone who can explain what's going on.
Thanks.
I don't know if this is a bug or a expected behavior, but in the Strings docs there's a comment that show exactly what are you experiencing. If you use a text and index of the string it will return the first char. To avoid it, check first if the argument is an array or a string:
if(is_array($args)) {
echo($args['first_name']);
}
To complete #SérgioMichels answer, the reason for that is because PHP is expecting an integer as the given index. When you give it a string, PHP will cast the string into an integer, and assuming that the string does not start with a number, type casting will return 0 otherwise, it will return the leading number.
$str = 'abcdefghi';
var_dump($str['no_number']); // Outputs: string(1) "a"
var_dump($str['3something']); // Outputs: string(1) "d"
To specifically answer your question - this will solve your bug:
function get_details($args='')
{
if (is_array($args))
{
$first_name = $args['first_name'];
}
else
{
$first_name = $this->uri->segment(3);
}
... do some other stuff ...
}
But you have some issues with your code. Firstly you state that you call the method as
<domain>/<controller>/get_details/abcd/efgh
but you dont accept the "efgh" variable in your controller. To do this, you need to change the function to
function get_details($first, $last)
in which case you can now just call the function as
$this->get_details('abcd', 'efgh');
and now you dont even need to test for arrays etc, which is a better solution IMO.
If you decide to stick with arrays, change:
$first_name = $this->uri->segment(3);
to
$first_name = $args;
because by definition - $args IS The 3rd URI segment.

PHP function's parameter is unclear

function test($param=null) {
if ($param===null)
.....
}
Since $param is set to null at function header, why even bother test if $param===null? If there a case $param wouldn't be null?
Since $param is set to null at function header, why even bother test
if $param===null? if there a case $param wouldn't be null?
That is optional argument because you define default value of null to it.
As for why bother checking it, you want to make sure a parameter was indeed specified which is NOT null.
Let's assume you wanted to echo it:
function test($param=null) {
echo $param;
}
When you call the function, nothing would happen and you don't want to do that, right. For that reason, you want to make sure that value of argument is NOT null so that you could manipulate it however you like.
Tests:
function test($param=null) {
echo $param;
}
test(); // no output
test('hello there'); // output: hello there
That is an optional/default argument.
If you call that function, then you can call it one of two ways:
test($value);
or
test();
In the first case, $param holds the value of $value. In the second case, $param is always null.
$param will only be null if no value is passed to the function. This is an example of optional parameters.
You could call the function by passing a value
test(10); //$param inside the method will be 10;
test(); //$param will be null
$param=null is a default variable only, overwritten when the function is called with a variable.
if you call the function using
$helloworld = test('notnull');
then $param will equal 'notnull' in the function.
A case $param wouldn't be null:
test("ok");
In this case, $param = "ok".

How do i set an optional parameter in PHP after the first optional parameter

I'm fairly new to php and I am trying to figure how do I set an optional parameter after the first optional parameter?
For example I have the following code:
function testParam($fruit, $veg='pota',$test='default test'){
echo '<br>$fruit = '.$fruit;
echo '<br>$veg = '.$veg;
echo '<br>Test = '.$test;
}
If i make the following calls:
echo 'with all parama';
testParam('apple','carrot','some string');
//we get:
//with all parama
//$fruit = apple
//$veg = carrot
//Test = some string
echo '<hr> missing veg';
testParam('apple','','something');
//we get:
//missing veg
//$fruit = apple
//$veg =
//Test = something
echo '<hr> This wont work';
testParam('apple',,'i am set');
I want to try make a call so that in the last example I show 'pota' as the default $veg parameter but pass into $test 'i am set'.
I guess I can pass 0 into $veg then branch it in the code to say if $veg =0 then use 'pota' but just wondered if there's some other syntax as i cant find anything in php.net about it.
You can't do what you want with just default parameters. The defaults only apply to missing arguments, and only the last argument(s) can be missing.
You can either add lines like
$vega = $vega ? $vega : 'carrot';
and call the function as
testParam('apple',false,'something');
or use the more general technique of passing the parameters in an array with the parameter names as keys. Something like
function testparam($parms=false) {
$default_parms = array('fruit'=>'orange', 'vega'=>'peas', 'starch'=>'bread');
$parms = array_merge($default_parms, (array) $parms);
echo '<br>fruit = $parms[fruit]';
echo '<br>vega = $parms[vega]';
echo '<br>starch = $parms[starch]';
}
testparm('starch'=>'pancakes');
//we get:
//fruit = orange
//vega = peas
//starch = pancakes
This is a little more verbose but it is also more flexible. You can add parameters and defaults without changing the existing callers.
Unfortunately, you cannot do that in PHP.
You have to pass in 0, or null, or some other value and then if the value is 0 or null, change it to the default value.
Here is another question that should give you more information.
This is the technique I use:
function testParam($fruit, $veg='pota', $test='default test') {
/* Check for nulls */
if (is_null($veg)) { $veg = 'pota'; }
if (is_null($test)) { $test = 'default test'; }
/* The rest of your code goes here */
}
Now to use the default value of any optional parameter, just pass NULL like so.
testParam('apple', null, 'some string');
In this example, $veg will equal 'pota'
The downside of this code example is that you have to code the default values twice. You could just as easily set the default value to null in the parameter declaration so you don't have to code the default value twice, but, I like to set it twice because my IDE gives me parameter hinting that instantly shows me the default values in the function signature.

Is it possible to pass parameters by reference using call_user_func_array()?

When using call_user_func_array() I want to pass a parameter by reference. How would I do this. For example
function toBeCalled( &$parameter ) {
//...Do Something...
}
$changingVar = 'passThis';
$parameters = array( $changingVar );
call_user_func_array( 'toBeCalled', $parameters );
To pass by reference using call_user_func_array(), the parameter in the array must be a reference - it does not depend on the function definition whether or not it is passed by reference. For example, this would work:
function toBeCalled( &$parameter ) {
//...Do Something...
}
$changingVar = 'passThis';
$parameters = array( &$changingVar );
call_user_func_array( 'toBeCalled', $parameters );
See the notes on the call_user_func_array() function documentation for more information.
Directly, it may be impossible -- however, if you have control both over the function you are implementing and of the code that calls it - then there is one work-around that you might find suitable.
Would you be okay with having to embed the variable in question into an object? The code would look (somewhat) like this if you did so.
function toBeCalled( $par_ref ) {
$parameter = $par_ref->parameter;
//...Do Something...
$par_ref->parameter = $parameter;
}
$changingVar = 'passThis';
$parembed = new stdClass; // Creates an empty object
$parembed->parameter = array( $changingVar );
call_user_func_array( 'toBeCalled', $parembed );
You see, an object variable in PHP is merely a reference to the contents of the object --- so if you pass an object to a function, any changes that the function makes to the content of the object will be reflected in what the calling function has access to as well.
Just make sure that the calling function never does an assignment to the object variable itself - or that will cause the function to, basically, lose the reference. Any assignment statement the function makes must be strictly to the contents of the object.
This works by double referencing,the original variable is modified when the $parameter variable is modified.
$a = 2;
$a = toBeCalled($a);
echo $a //50
function toBeCalled( &$par_ref ) {
$parameter = &$par_ref;
$parameter = $parameter*25;
}
Except you are using deprecated functionality here. You'll generate a warning in PHP5 making it less than perfect.
Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of runtime function name. If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file in ...
Unfortunately, there doesn't appear to be any other option as far as I can discover.

Categories