How to pass variable to a function declared in another function - php

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) {

Related

Dynamic php function

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();

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));
}
}

Help with PHP array_filter function

Please see the following function to scan the files in a directory (Taken from here)
function scandir_only_files($dir) {
return array_filter(scandir($dir), function ($item) {
return is_file($dir.DIRECTORY_SEPARATOR.$item);
});
}
This does not work because the $dir is not in scope in the anonymous function, and shows up empty, causing the filter to return FALSE every time. How would I rewrite this?
You have to explicitly declare variables inherited from the parent scope, with the use keyword:
// use the `$dir` variable from the parent scope
function ($item) use ($dir) {
function scandir_only_files($dir) {
return array_filter(scandir($dir), function ($item) use ($dir) {
return is_file($dir.DIRECTORY_SEPARATOR.$item);
});
}
See this example from the anonymous functions page.
Closures may inherit variables from the parent scope. Any such variables must be declared in the function header. The parent scope of a closure is the function in which the closure was declared (not necessarily the function it was called from).

Categories