Initialize the function In the form of Variable in php - php

How can i set the function as a variable in php
Similar to list function
example: list($x,$y)=array(1,2); // this is okey ,but...
How do I create such a structure?

You are talking about variable function that if a variable name has parentheses appended to it, PHP will look for a function with the same name as whatever the variable evaluates to, and will attempt to execute it. Among other things, this can be used to implement callbacks, function tables, and so forth.
Here is the little example from PHP manual Variable Functions
function foo() {
echo "In foo()<br />\n";
}
function bar($arg = '')
{
echo "In bar(); argument was '$arg'.<br />\n";
}
// This is a wrapper function around echo
function echoit($string)
{
echo $string;
}
$func = 'foo';
$func(); // This calls foo()
$func = 'bar';
$func('test'); // This calls bar()
$func = 'echoit';
$func('test'); // This calls echoit()
and the other scenario is Anonymous functions, also known as closures, allow the creation of functions which have no specified name. They are most useful as the value of callback parameters, but they have many other uses.
$greet = function($name)
{
printf("Hello %s\r\n", $name);
};
$greet('World');
$greet('PHP');

<?php
$my_array = array("Dog","Cat","Horse");
list($a, $b, $c) = $my_array;
echo "I have several animals, a $a, a $b and a $c.";
?>
The list() function is used to assign values to a list of variables. Like array(), this is not really a function, but a language construct. list() is used to assign a list of variables in one operation.

Related

Why is the use language construct in php unable to see changes in the value of a variable?

I have got to the chapter of anonymous functions in php manuel. In the earlier chapter two methods of passing variables to a function are explained, namely, pass by value and pass by reference. Being a javascript developer, it was very unconfortable to see that functions do not have the access to the variables defined in the parent scope. Anyways, now they have come up with a third method to pass variables to a function -- by the use language construct. Please consider the following example:
$message = "hello";
$example = function () use ($message) {
var_dump($message);
};
$example(); //prints hello, as expected.
$message = 'world';
$example(); //prints hello -- not world.
The last call to $example should print "world", but it prints the older value of $message. Why is that? Instead if we had used either pass-by-value or pass-by-reference, the last function call would have printed world.
The use language construct captures/copies the passed variable at the time the anonymous function is defined. If you change that variable after the function definition, the function will not notice it:
$foo = 'baz';
$f1 = function() use ($foo) {
echo $foo;
};
$foo = 'boo';
$f1(); // baz
However, if the variable is an object, this rule doesn't apply, as PHP passes objects by reference*, always (* read Jeto's comment below for a more accurate description):
$foo = new StdClass();
$foo->bar = 'baz';
$f2 = function() use ($foo) {
echo $foo->bar;
};
$foo->bar = 'boo';
$f2(); // boo
I think the reason PHP has use is for partial function application:
function get_multiplier($factor) {
return function($num) use ($factor) {
return $num * $factor;
};
}
$multiply_by_4 = get_multiplier(4);
echo $multiply_by_4(5); // 20

use() statement on anonymous functions

Is it a bad practice to use it?
Because people say that global variables are bad practice and the use thing brings variables from outside into the functions, so it's like global
This is how it looks
$a = 1;
$func = function() use($a){
print $a;
};
Any arguments defined in the "use" arguments for an anonymous function use the value at the time when the anonymous function is defined; so they must exist at that point; but they don't need to be passed (or even exist in the caller scope) when the function is called.
function myFunctionCreator() {
$a = 1; // Must exist for the `use` clause
$func = function() use($a){
echo $a, PHP_EOL;
};
return $func;
}
$myFunc = myFunctionCreator();
$a = 2;
$myFunc(); // echoes 1 (value of $a at the point where the function was created)
As you can see from the above example, $a has a value of 1 at the point where the function is defined, and even though a variable with the same name exists at the point when the function called, it is the original $a (with the value 1) that is used in the function call.
Arguments defined in the main argument definition need not exist when the function is defined, but the values must be passed as arguments to the function at the point when it is called.
function myFunctionCreator() {
$a = 1; // Need not exist, and will be ignored
$func = function($a) {
echo $a, PHP_EOL;
};
return $func;
}
$myFunc = myFunctionCreator();
$value = 2;
$myFunc($value); // echoes 2 (value of $a explicitly passed to the function call
// at the time it is executed)
So the behaviour of the two types is quite different, and their purpose when combined provides a degree of flexibility that is quite different
As Rizier123 has mentioned in his comment, arguments passed to an anonymous function as "standard" can have defaults, typehints, etc, whereas "use" arguments cannot.
function myFunctionCreator() {
$func = function(array $dataset = [1,2,3]) {
foreach($dataset as $value) {
echo $value, PHP_EOL;
}
};
return $func;
}
$myFunc = myFunctionCreator();
$value = ['a','b','c'];
$myFunc($value);
$myFunc();
$myFunc(['x','y','z']);
Or (as the third call shows, arguments can be passed directly.
Andy of these applied to a "use" argument will result in a parse error

how to call anonymous functions stored in a static array?

I'm trying to store anonymous functions in a static array property of my class. These functions should be invoked later by their index, but calling
self::$arr['index']()
just doesn't work, while
$a = self::$arr['index'];
$a();
does!
This doesn't work:
class A {
private static $func = array('a' => '');
public function __construct() {
self::$func['a'] = create_function('$str', 'echo "$str";');
}
public function go($str) {
self::$func['a']($str); // Call the function directly
}
}
$a = new A();
$a->go("hooray"); // Outputs "Undefined variable: func"
But this does:
class A {
private static $func = array('a' => '');
public function __construct() {
self::$func['a'] = create_function('$str', 'echo "$str";');
}
public function go($str) {
$a = self::$func['a']; // Pass the function name to a variable
$a($str); // Call the function via the variable
}
}
$a = new A();
$a->go("hooray"); // Outputs "hooray"
Why?
I'm using PHP Version 5.4.3
this is the behavior of php's parser
$functionName['a'] = "hello";
self::$functionName['a']();
calls
self::hello();
... the very sad thing is that in php you can't do this:
(self::$functionName['a'])(); // doesn't work in php :(
as you can do in javascript, for example
what you can do is... use a temporary variable like you said
$a = self::$func['a'];
$a($parameter);
or
call_user_func(self::$func['a'], $parameter);
hope this helps...
in latest phps these features were added
$a['sss'] = function(){ echo 'bla'; };
$a['sss']();
class Bla
{
private $a;
function test()
{
$this->a['sss'] = function(){ echo 'bla2'; };
$this->a['sss']();
}
}
$c = new Bla();
$c->test();
and they work properly... so for some reason, this syntax doesn't work only when using the scope resolution operator ( ClassName:: self:: etc)
Well, in php you simply can not do that, it is a php feature. But you can use call_user_func or its relatives:
return call_user_func(self::$func['$a'], $str);
This is a consequence of how the PHP parser currently works. Since the function call () is evaluated before the static operator ::, you end up with the parser attempting to reference the local variable $func instead, and then giving you the error about $func being undefined (which it is, since there is no variable named $func in the method).
As you've discovered, you can solve this by doing two separate statements.

returning variable from function

This is probably not the wisest question, but is it possible to return a variable from a function without redeclaring it?
function test(){
$a = 1;
return $a;
}
Would it somehow be possible to access $a with just calling the function? test();
not $a = test();
Is that the only way? I want to make $a available after calling the function.
You have to put the variable into the global scope:
http://codepad.org/PzKxWGbU
function test()
{
$GLOBALS['a'] = 'Hello World!';
}
test();
echo $a;
But it would be better to use a return value or references:
function test(&$ref)
{
$ref = 'Hello World!';
}
$var = '';
test($var);
I assume you want to change some context when you call the function.
This is possible. For example, all global variables share the same context across your application. If a function set's a global variable, its available in the global scope:
function change_global_variable($name, $value)
{
$GLOBALS[$name] = $value;
}
change_global_variable('a', 1);
echo $a;
However, whenever you do something like this, take care that you're destroying the modularity of your code. For example, if you have 50 functions like this and 80 variables, and then you need to change something, you need to change many, many places. And even harder, you don't remember which places you need to change and how they belong to each other.
It's normally better to make the context an object and pass it to the function that changes it, so it's more clear what the function does:
class Context extends ArrayObject {}
$context = new Context;
function change_context(Context $context, $name, $value)
{
$context[$name] = $value;
}
change_context($context, 'b', 2);
echo $context['b'], "\n";
This example demonstrates something that's called dependency injection. Instead of modifying the only one (global) context that exists in PHP, you are telling the function what it should modify, instead that it modifies hard-encoded global variables
There is a mix form of it, using the global variable scope to contain the context, so you spare to pass it as an additional parameter, however I only show it here for completeness, because it's not helping to retain modularity that well (however it's better than using more than one global variable):
class Context extends ArrayObject {}
$context = new Context;
function change_global_context($name, $value)
{
global $context;
$context[$name] = $value;
}
change_global_context('c', 3);
echo $context['c'], "\n";
Rule of thumb: Avoid global variables. Consider them of being very expensive and you don't want your code to be expensive.
No, it is not due to the scoping.
An option would be to declare $a before and then making it a global. It will then be available inside test:
$a = '';
function test(){
global $a;
$a = 1;
return $a;
}
echo $a; // 1
But may I ask why you want to do this? Are you just playing around or do you have a use case? You're most probably doing it wrong if you need this.
Maybe if you just want to show the variable you can use
function test(){
$a = 1;
echo $a;
return $a;
}
in this way if you want you can save the variable $a in a variable if not you can just show it calling the test function.
Hope it helps.
Nicola.

Is it possible to access outer local variable in PHP?

Is it possible to access outer local varialbe in a PHP sub-function?
In below code, I want to access variable $l in inner function bar. Declaring $l as global $l in bar doesn't work.
function foo()
{
$l = "xyz";
function bar()
{
echo $l;
}
bar();
}
foo();
You could probably use a Closure, to do just that...
Edit : took some time to remember the syntax, but here's what it would look like :
function foo()
{
$l = "xyz";
$bar = function () use ($l)
{
var_dump($l);
};
$bar();
}
foo();
And, running the script, you'd get :
$ php temp.php
string(3) "xyz"
A couple of note :
You must put a ; after the function's declaration !
You could use the variable by reference, with a & before it's name : use (& $l)
For more informations, as a reference, you can take a look at this page in the manual : Anonymous functions
You must use the use keyword.
$bar = function() use(&$l) {
};
$bar();
In the very very old PHP 5.2 and earlier this didn't work. The syntax you've got isn't a closure, but a definition of a global function.
function foo() { function bar() { } }
works the same as:
function foo() { include "file_with_function_bar.php"; }
If you execute function foo twice, PHP will complain that you've tried to re-define a (global) function bar.
You can read default value by:
function(){
return preg_match(
"yourVar = \d+"
, str_file_get_contents(functionFile)
, arrayToPutFieldsValue
);
}
If You would use two functons in the same time - it's like someone's using a spoon and You want to take a food from that spoon - You'll waste a food or some of You will starv.
Anyway - You would have to set a pointer somehow in a hard way.
It's impossible to get any field from other function or class without calling it to life.
Functions/methods are instance-like - they need to be called.
Share the common fields by accessing a global fields with synchronized functions.
function a()
{
function val1($arg=null)
{
static $a;
if ($arg !== null) $a = $arg;
else return $a;
}
function b()
{
val1('1234');
echo val1() . '<br>'; // shows: 1234
val1('my custom data');
echo val1() . '<br>'; // shows: my custom data
}
b();
}
a();
Used val1('my custom data') to set my value
Used val1() to get my value

Categories