why pass-by-reference doesn't change the value of a variable? - php

$string='string';
function change(&$str){
$str='str';
}
call_user_func('change',$string);
echo $string;
output is 'string'. but $str refer to the $string , so change in $str should also change $string? why the value is still same?

It's not possible with call_user_func():
From the PHP documentation:
Note that the parameters for call_user_func() are not passed by reference.
That said you still can use call_user_func_array(). Using the reference becomes now possible. Here's the code you want:
function change(&$str)
{
$str='str';
}
$string='string';
$parameters = array(&$string);
call_user_func_array('change',$parameters);
echo $string;
However this solution is now Deprecated.
You still can get rid of call_user_func(), and simply do:
function change(&$str)
{
$str='str';
}
$string='string';
change($string);
echo $string;

http://php.net/manual/en/function.call-user-func.php
It clearly mention that the parameters for call_user_func() are not passed by reference.

Here's your error message:
<br />
<b>Warning</b>: Parameter 1 to change() expected to be a reference, value given on line <b>5</b>
because call_user_func does not pass parameters by reference.
Try run it like this:
$string='string';
function change(&$str){
$str='str';
}
change($string);
echo $string;

call_user_func doesn't pass by reference. From the PHP docs:
Note that the parameters for call_user_func() are not passed by reference.
(change($string), on the other hand, gives "str" as you would expect).
Further reading: Why does PHP's call_user_func() function not support passing by reference?

Related

implode() :invalid argument passed

function submit_data()
{
$st_value='';
$ft_value='';
$mt_value='';
$otr_value='';
$st_details= $this->input->post('check_list');
$ft_details= $this->input->post('ft_check_list');
$mt_details= $this->input->post('mt_check_list');
$otr_details= $this->input->post('otr_check_list');
//print_r($st_details);
$st_value=implode(",",$st_details);
$ft_value=implode(",",$ft_details);
$mt_value=implode(",",$mt_details);
$otr_value=implode(",",$otr_details);
$index= $this->register->insert_details($st_value,$ft_value,$mt_value,$otr_value);
//$this->register->update_details($st_value,$ft_value,$mt_value,$otr_value);
$this->session->set_flashdata('success_message',$success_message);
redirect(base_url().'new_register/index/'.$index);
}
Here is my controller function and i am getting an error message of implode(): invalid argument passed while submiting,How can i intercept the error.
implode() method accept second parameter as array. I think you are providing it a string.
Check by var_dump($st_details);
As others said, implode() uses second parameter as array. You can test your varriable to see if it's an array using is_array() or using var_dump() to see its details.
implode()
is_array()
var_dump()

What does the parameter $something=null mean in PHP?

We got a PHP file in school with some functions and one of them is the following:
function serviceRec($db,$table,$afields=null,$avalues=null){ .... }
My question: What does the $afields=null and $avalues=null mean?
Thank you!
function serviceRec($db,$table,$afields=null,$avalues=null){ .... }
It means that, when you call your function and don't pass those parameters then it'll by default place value as null
Example :
function hello($name = "anonymous"){
return "Hello $name \n";
}
echo hello();//Hello anonymous
echo hello("BigSeeProduction");//Hello BigSeeProduction
DOCS
These assignments are default values. If you were to call the function as e.g.
serviceRec($a, $b)
the omitted parameters would be assumed to be null. If, on the other hand, you called the function as e.g.
serviceRec($a, $b, $c, $d)
$afields would be set to $c and $avalues to $d.
Of course, you could also call with 3 parameters.
It Means it's the default value. So when u don't fill this parameter it will be set as null.
See the man here :
PHP.net : default value function
That indicates, that if you leave that parameter out(Don't specify it at all), the value after the =, in this case null is used. So if you don't care about these parameters just leave them out. It has the same effect as just supllying null.

Trying to call unknow function

I have to dynamically try, if function is callable (not only if exists, but if is callable). This is my code:
try {
call_user_func($function, $arguments->arg);
} catch (Exception $e) {
$condition = $this->_object->getContent("phpCall", "return");
}
$function and $arguments->arg are dynamic variables, for example $function contains md5 and $arguments->arg contains 123.
I know that function md5 exists in PHP, but I get this error:
Warning: call_user_func() expects parameter 1 to be a valid callback, no array or string given in...
Any ideas?
Use is_callable
if (is_callable($function)){
//do stuff here
}
If you're going to pass it to call_user_func, make sure $function is a string.
Alternatively, you could just do:
$function($args);
Sounds like call_user_func expects a string with the name of the function to be called. Are you instead sending a function pointer?

PHP: Array passed by reference to a function?

I have this php function that has to perform some processing on a given array:
processArray($arrayToProcess) {
$arrayToProcess['helloStackOverflow'] = TRUE;
}
Later, the code invokes the following:
$niceArray = array('key' => 'value');
processArray($niceArray);
The key 'helloStackOverflow' isn't available outside the processArray function. I tried calling the following:
processArray(&$niceArray);
Using "&" helps, however it raises some warning:
Deprecated function: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of populateForm_withTextfields()
Tried the & in there, but that just stops the code.
How should I do this?
You have to define the reference in the function, not in the call to the function.
function processArray(&$arrayToProcess) {
processArray(&$arrayToProcess) {
$arrayToProcess['helloStackOverflow'] = TRUE;
}
implements the reference in PHP way.
See http://fi2.php.net/references for useful information about references.
processArray(&$arrayToProcess) {
$arrayToProcess['helloStackOverflow'] = TRUE;
}
Referencing passing now takes place at the function declaration, not when the function is called.
http://php.net/manual/en/language.references.pass.php
for full documentation.

Pass a function by reference in PHP

Is it possible to pass functions by reference?
Something like this:
function call($func){
$func();
}
function test(){
echo "hello world!";
}
call(test);
I know that you could do 'test', but I don't really want that, as I need to pass the function by reference.
Is the only way to do so via anonymous functions?
Clarification: If you recall from C++, you could pass a function via pointers:
void call(void (*func)(void)){
func();
}
Or in Python:
def call(func):
func()
That's what i'm trying to accomplish.
For what it's worth, how about giving something like this a shot? (Yes, I know it's an anonymous function which was mentioned in the post, but I was disgruntled at the abundance of replies that did not mention closures/function-objects at all so this is mostly a note for people running across this post.)
I don't use PHP, but using a closure appears to work in PHP 5.3 (but not PHP 5.2) as demonstrated here. I am not sure what the limitations, if any, there are. (For all I know the closure will eat your children. You have been warned.)
function doIt ($fn) {
echo "doIt\n";
return $fn();
}
function doMe () {
echo "doMe\n";
}
// I am using a closure here.
// There may be a more clever way to "get the function-object" representing a given
// named function, but I do not know what it is. Again, I *don't use PHP* :-)
echo doIt(function () { doMe(); });
Happy coding.
The problem with call_user_func() is that you're passing the return value of the function called, not the function itself.
I've run into this problem before too and here's the solution I came up with.
function funcRef($func){
return create_function('', "return call_user_func_array('{$func}', func_get_args());");
}
function foo($a, $b, $c){
return sprintf("A:%s B:%s C:%s", $a, $b, $c);
}
$b = funcRef("foo");
echo $b("hello", "world", 123);
//=> A:hello B:world C:123
ideone.com demo
No, functions are not first class values in PHP, they cannot be passed by their name literal (which is what you're asking for). Even anonymous functions or functions created via create_function are passed by an object or string reference.
You can pass a name of a function as string, the name of an object method as (object, string) array or an anonymous function as object. None of these pass pointers or references, they just pass on the name of the function. All of these methods are known as the callback pseudo-type: http://php.net/callback
function func1(){
echo 'echo1 ';
return 'return1';
}
function func2($func){
echo 'echo2 ' . $func();
}
func2('func1');
Result:
echo1 echo2 return1
In PHP 5.4.4 (haven't tested lower or other versions), you can do exactly as you suggested.
Take this as an example:
function test ($func) {
$func('moo');
}
function aFunctionToPass ($str) {
echo $str;
}
test('aFunctionToPass');
The script will echo "moo" as if you called "aFunctionToPass" directly.
A similar pattern of this Javascript first class function:
function add(first, second, callback){
console.log(first+second);
if (callback) callback();
}
function logDone(){
console.log('done');
}
function logDoneAgain(){
console.log('done Again');
}
add(2,3, logDone);
add(3,5, logDoneAgain);
Can be done in PHP (Tested with 5.5.9-1ubuntu on C9 IDE) in the following way:
// first class function
$add = function($first, $second, $callback) {
echo "\n\n". $first+$second . "\n\n";
if ($callback) $callback();
};
function logDone(){
echo "\n\n done \n\n";
}
call_user_func_array($add, array(2, 3, logDone));
call_user_func_array($add, array(3, 6, function(){
echo "\n\n done executing an anonymous function!";
}));
Result: 5 done 9 done executing an anonymous function!
Reference: https://github.com/zenithtekla/unitycloud/commit/873659c46c10c1fe5312f5cde55490490191e168
You can create a reference by assigning the function to a local variable when you declare it:
$test = function() {
echo "hello world!";
};
function call($func){
$func();
}
call($test);
You can say
$fun = 'test';
call($fun);
Instead of call(test);, use call_user_func('test');.
As of PHP 8.1, you can use First-class callables:
call(test(...));
You can even use methods:
call($obj->test(...));
As simple as it is.
It appears a bit unclear why do you want to pass functions by reference? Usually things are passed by reference only when the referenced data needs to be (potentially) modified by the function.
As PHP uses arrays or strings to refer functions, you could just pass an array or a string by reference and that would allow the function reference to be modified.
For example, you could do something like
<?php
$mysort = function($a, b) { return ($a < $b) ? 1 : -1; };
adjust_sort_from_config($mysort); // modifies $mysort
do_something_with_data($mysort);
where
<?php
function load_my_configuration(&$fun)
{
$sort_memory = new ...;
...
$fun = [$sort_memory, "customSort"];
// or simply
$fun = function($a, b) { return (rand(1,10) < 4 ? 1 : -1; };
}
This works because there are three ways to refer to function in PHP via a variable:
$name – the string $name contains the name of the function in global namespace that should be called
array($object, $name) – refers to method called string $name of object $object.
array($class, $name) – refers to static function string $name of class $class.
If I remember correctly, the methods and static functions pointed by these constructs must be public. The "First-class callable syntax" should improve this restriction given recent enough PHP version but it seems to be just some syntactic sugar around Closure::fromCallable().
Anonymous functions work the same behind the scenes. You just don't see the literal random names of those functions anywhere but the reference to an anonymous function is just a value of a variable, too.

Categories