Dynamic php function - php

How can we declare the function name dynamically?
For example :
$function = 'test'
public $function(){
}

You could use a callback for this:
https://stackoverflow.com/a/2523807/3887342
function doIt($callback) { $callback(); }
doIt(function() {
// this will be done
});

Declaring a function with a variable but arbitrary name like this is not possible without getting your hands dirty with eval() or include().
I think based on what you're trying to do, you'll want to store an anonymous function in that variable instead (use create_function() if you're not on PHP 5.3+):
$variableA = function() {
// Do stuff
};
You can still call it as you would any variable function, like so:
$variableA();

Related

How to pass variable to a function declared in another function

When trying to return a stream download in laravel, I need to pass a variable to the function that's declared in streamDownload. I must be missing something very basic here.
return response()->streamDownload(function () {
echo base64_decode(DNS1D::getBarcodePNG($VARIABLE_TO_PASS, 'C128'));
}, 'barcode.png');
Thanks!
What is when you put your output in your function with use? So when you have an external variable.
$VARIABLE_TO_PASS = "mystring";
return response()->streamDownload(function () use ($VARIABLE_TO_PASS) {
echo base64_decode(DNS1D::getBarcodePNG($VARIABLE_TO_PASS, 'C128'));
}, 'barcode.png');
https://secure.php.net/manual/en/functions.anonymous.php
The variable is out of scope when using an anonymous function.
You simply pass the variable into the function with the use keyword to make it available inside the anonymous function.
return response()->streamDownload(function() use ($VARIABLE_TO_PASS) {

PHP using variable in an included function

Main File;
$opid=$_GET['opid'];
include("etc.php");
etc.php;
function getTierOne() { ... }
I can use $opid variable before or after function but i can't use it in function, it returns undefined.
What should i do to use it with a function in an included file?
$getTierOne = function() use ($opid) {
var_dump($opid);
};
Its because the function only has local scope. It can only see variables defined within the function itself. Any variable defined outside the function can only be imported into the function or used globally.
There are several ways to do this, one of which is the global keyword:
$someVariable = 'someValue';
function getText(){
global $someVariable;
echo $someVariable;
return;
}
getText();
However, I'd advise against this approach. What would happen if you changed $someVariable to another name? You'd have to go to each function you've imported it into and change it as well. Not very dynamic.
The other approach would be this:
$someVariable = 'someValue';
function getText($paramater1){
return $parameter1;
}
echo getText($someVariable);
This is more logical, and organised. Passing the variable as an argument to the function is way better than using the global keyword within each function.
Alternatively, POST, REQUEST, SESSION and COOKIE variables are all superglobals. This means they can be used within functions without having to implicitly import them:
// Assume the value of $_POST['someText'] is someValue
function getText(){
$someText = $_POST['someText'];
return $someText;
}
echo getText(); // Outputs someValue
function getTierOne()
{
global $opid;
//...
}

How can I use a callback function which is stored as a class member in PHP?

Consider the following code, which is a scheme of storing a callback function as a member, and then using it:
class MyClass {
function __construct($callback) {
$this->callback = $callback;
}
function makeCall() {
return $this->callback();
}
}
function myFunc() {
return 'myFunc was here';
}
$o = new MyClass(myFunc);
echo $o->makeCall();
I would expect myFunc was here to be echoed, but instead I get:
Call to undefined method MyClass::callback()
Can anyone explain what's wrong here, and what I can do in order to get the desired behaviour?
In case it matters, I am using PHP 5.3.13.
You can change your makeCall method to this:
function makeCall() {
$func = $this->callback;
return $func();
}
Pass it as a string and call it by call_user_func.
class MyClass {
function __construct($callback) {
$this->callback = $callback;
}
function makeCall() {
return call_user_func($this->callback);
}
}
function myFunc() {
return 'myFunc was here';
}
$o = new MyClass("myFunc");
echo $o->makeCall();
One important thing about PHP is that it recognises the type of a symbol with the syntax rather than the contents of it, so you need to state explicitly what you refer to.
In many languages you just write:
myVariable
myFunction
myConstant
myClass
myClass.myStaticMethod
myObject.myMethod
And the parser/compiler knows what each of the symbols means, because it's aware of what they refer to simply by knowing what's assigned to them.
In PHP, however, you need to use the syntax to let the parser know what "symbol namespace" you refer to, so normally you write:
$myVariable
myFunction()
myConstant
new myClass
myClass::myStaticMethod()
$myObject->method()
However, as you can see these are calls rather than references. To pass a reference to a function, class or method in PHP, combined string and array syntax is used:
'myFunction'
array('myClass', 'myStaticMethod')
array($myObject, 'myMethod')
In your case, you need to use 'myFunc' in place of myFunc to let PHP know that you're passing a reference to a function and not retrieving the value the myFunc constant.
Another ramification is that when you write $myObject->callback(), PHP assumes callback is a method because of the parentheses and it does not attempt to loop up a property.
To achieve the expected result, you need to either store a copy of/reference to the property callback in a local variable and use the following syntax:
$callback = $this->callback;
return $callback();
which identifies it as a closure, because of the dollar sign and the parentheses; or call it with the call_user_func function:
call_user_func($this->callback);
which, on the other hand, is a built-in function that expects callback.

Declaring a function in a function in php

The code:
public function couts_complets($chantier,$ponderation=100){
function ponderation($n)
{
return($n*$ponderation/100); //this is line 86
}
...
}
What I'm trying to do: to declare a function B inside a function A in order to use it as a parameter in
array_map().
My problem: I get an error:
Undefined variable: ponderation [APP\Model\Application.php, line 86]
Try this:
public function couts_complets($chantier,$ponderation=100){
$ponderationfunc = function($n) use ($ponderation)
{
return($n*$ponderation/100);
}
...
$ponderationfunc(123);
}
As of php 5.3 you can use anonymous functions. Your code would look like this (untested code warning):
public function couts_complets($chantier,$ponderation=100) {
array_map($chantier, function ($n) use ($ponderation) {
return($n*$ponderation/100); //this is line 86
}
}
In your current code, $ponderation is not covered by the scope of the function, hence the "undefined" error.
To pass a variable to an "internal" function, use the use statement.
function ponderation($n) use($ponderation) {
Using a callback function:
In order to use a function as a parameter in PHP it is enough to pass the function's name as a string as such:
array_map('my_function_name', $my_array);
If the function is actually a static method in a class you can pass it as a parameter as such:
array_map(array('my_class_name', 'my_method_name'), $my_array);
If the function is actually a non-static method in a class you can pass it as a parameter as such:
array_map(array($my_object, 'my_method_name'), $my_array);
Declaring a callback function:
If you declare in the global space all is good and clear in the world - for everybody.
If you declare it inside another function it will be global but it won't be defined until the parent function runs for the first time and it will trigger an error Cannot redefine function my_callback_function if you run the parent function again.
If you declare it as a lambda function / anonymous function you will need to specify which of the upper level scope variables it is allowed to see/use.
Calling a callback:
function my_api_function($callback_function) {
// PHP 5.4:
$callback_function($parameter1, $parameter2);
// PHP < 5.3:
if(is_string($callback_function)) {
$callback_function($parameter1, $parameter2);
}
if(is_array($callback_function)) {
call_user_func_array($callback_function, array($parameter1, $parameter2));
}
}

Using `$this` in an anonymous function in PHP pre 5.4.0

The PHP manual states
It is not possible to use $this from anonymous function before PHP
5.4.0
on the anonymous functions page. But I have found I can make it work by assigning $this to a variable and passing the variable to a use statement at the function definition.
$CI = $this;
$callback = function () use ($CI) {
$CI->public_method();
};
Is this a good practice?
Is there a better way to access $this inside an anonymous function using PHP 5.3?
It will fail when you try to call a protected or private method on it, because using it that way counts as calling from the outside. There is no way to work around this in 5.3 as far as I know, but come PHP 5.4, it will work as expected, out of the box:
class Hello {
private $message = "Hello world\n";
public function createClosure() {
return function() {
echo $this->message;
};
}
}
$hello = new Hello();
$helloPrinter = $hello->createClosure();
$helloPrinter(); // outputs "Hello world"
Even more, you will be able to change what $this points to at runtime, for anonymus functions (closure rebinding):
class Hello {
private $message = "Hello world\n";
public function createClosure() {
return function() {
echo $this->message;
};
}
}
class Bye {
private $message = "Bye world\n";
}
$hello = new Hello();
$helloPrinter = $hello->createClosure();
$bye = new Bye();
$byePrinter = $helloPrinter->bindTo($bye, $bye);
$byePrinter(); // outputs "Bye world"
Effectively, anonymus functions will have a bindTo() method, where the first parameter can be used to specify what $this points to, and the second parameter controls what should the visibility level be. If you omit the second parameter, the visibility will be like calling from the "outside", eg. only public properties can be accessed. Also make note of the way bindTo works, it does not modify the original function, it returns a new one.
Don't always rely on PHP to pass objects by reference, when you are assigning a reference itself, the behavior is not the same as in most OO languages where the original pointer is modified.
your example:
$CI = $this;
$callback = function () use ($CI) {
$CI->public_method();
};
should be:
$CI = $this;
$callback = function () use (&$CI) {
$CI->public_method();
};
NOTE THE REFERENCE "&" and $CI should be assigned after final calls on it has been done, again else you might have unpredictable output, in PHP accessing a reference is not always the same as accessing the original class - if that makes sense.
http://php.net/manual/en/language.references.pass.php
That is the normal way it was done.
b.t.w, try to remove the & it should work without this, as objects pass by ref any way.
That seems alright if your passing by reference it's the correct way to do it. If your using PHP 5 you don't need the & symbol before $this as it will always pass by reference regardless.
This is fine. I should think you could do this also:
$CI = $this;
... since assignations involving objects will always copy references, not whole objects.

Categories