How to call a closure that is a class variable?
In PHP, methods and properties are in a separate namespace (you can have a method and a property with the same name), and whether you are accessing a property or a method depends of the syntax you are using to do so.
$expr->something()
is a method call, so PHP will search something
in the class' list of methods.
$expr->something
is a property fetch, so PHP will search something
in the class' list of properties.
$myInstance->lambda();
is parsed as a method call, so PHP searches for a method named lambda
in your class, but there is no such method (hence the Call to undefined method error).
So you have to use the fetch property syntax to fetch the lambda, and then call it.
Since PHP 7.0, you can do this with
($obj->lambda)()
:($obj->lambda)();
The parentheses make sure that PHP parses
($obj->lambda)
as fetch the property named lambda. Then,()
calls the result of fetching the property.or you can do this with
->lambda->__invoke()
:$myInstance = new MyClass();
$myInstance->lambda->__invoke();__invoke
is one of PHP's magic methods. When an object implements this method, it becomes invokable: it can be called using the$var()
syntax. Anonymous functions are instances ofClosure
, which implements__invoke
.Or assign it to a local variable:
$lambda = $myInstance->lambda;
$lambda();Or call it using call_user_func:
call_user_func($myInstance->lambda);
call_user_func
can call anycallable
, including anonymous functions.Alternatively, if this is a common pattern in your code, you can setup a
__call
method to forward calls to your lambda:class MyClass
{
private $lambda;
public function __construct()
{
$this->lambda = function() {
echo "Hello world!\n";
};
}
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
}Now this works:
$myInstance = new MyClass();
$myInstance->lambda();Since PHP 5.4 you can even do that in a trait:
trait LambdasAsMethods
{
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
}
class MyClass
{
use LambdasAsMethods;
private $lambda;
public function __construct()
{
$this->lambda = function() {
echo "Hello World!\n";
};
}
}
$myInstance = new MyClass();
$myInstance->lambda();
How to access a class's variable inside a closure?
If you need to use global variable/method in closure put self.
before your variable/method
So you can replace this
saleOrder = saleEdited
with
self.saleOrder = saleEdited
but it looks that problem is also somewhere else. You just need to pass saleOrder from first to second ViewController where you edit it and then pass data back to first view controller
So, first delete unneccessary code from ViewControllerData:
let funcReturnFromEdit = { (saleEdited : SaleOrder) -> () in
saleOrder = saleEdited // I can't do this.
}
and to fix completion handler in ViewControllerEdit
replace
var funcReturn = { (SaleOrder) -> Void in {} }
with
var funcReturn : ((SaleOrder) -> ())?
also edit your endEditions method because funcReturn is optional
func endEditions() {
funcReturn?(saleOrderToEdit)
}
Now just in your ViewControllerData fix prepare
method to set what should be done when user call funcReturn
from ViewControllerEdit
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueEditOrder" {
let editVc = segue.destination as! ViewControllerEdit
if let saleOrderToPass = saleOrder {
editVc.saleOrderToEdit = saleOrderToPass
editVc.funcReturn = { saleEdited in
self.saleOrder = saleEdited //This code is executed when you call funcReturn?(saleOrderToEdit) from ViewControllerEdit
}
}
}
}
How do I bind a closure to a static class variable in PHP?
- Change your property to be static
static $closure;
- Wrap your callable in brackets
(self::$closure)(2);
http://sandbox.onlinephpfunctions.com/code/d41490759cac39b8459e396b3acf99bf22c65a68
<?php
class A
{
static $closure;
public static function myFunc($input): string
{
$output = $input . ' is Number';
return $output;
}
public static function closure(): Closure
{
return function ($input) {
return self::myFunc($input);
};
}
public static function run()
{
$closure = self::closure();
echo $closure(1); // 1 is Number
self::$closure = $closure;
// Wrap your callable in brackets
echo (self::$closure)(2);
}
}
A::run();
How to invoke a PHP closure which is assigned to a class variable?
You need to use __invoke()
to call a closure with the $foo()
syntax.
A simple example:
class MyClass {
public static $closure;
function myFunction() {
self::$closure = function($a) { echo $a; };
self::$closure->__invoke(123);
}
}
$class = new MyClass;
$class->myFunction();
This will print out 123
:)
PHP: Using globally defined closure in a class method
Because $this->globalfunction
is a variable, not a method, you need to wrap it in parentheses to force PHP to evaluate $this->globalfunction
before attempting to call it as a function i.e.
function testFunc(){
($this->globalFunction)('a');
}
Output:
works a
Demo on 3v4l.org
How to access a class variable inside a closure in nodejs?
You can use an arrow function, this will preserve the reference to 'this' of run()
inside the callback
const { EventEmitter } = require("events");
const b = new EventEmitter()
class A {
constructor() {
this.a = "hello i am a"
}
run() {
b.on("event", (data) => {
console.log(this.a)
})
}
}
const classA = new A();
classA.run()
b.emit("event");
Swift: Closure as a init argument in a class variable
Here is as close as I could get to what you wanted by fiddling around in a playground. I had to change the types to match what you were passing to Calculator
class Calculator {
private let estimateChanged:() -> Void
init(_ estimateChanged:() -> Void) {
self.estimateChanged = estimateChanged
}
}
class AnotherClass {
lazy var callback: () -> Void = { [unowned self] in
self.loadEstimate()
}
var calculator: Calculator?
// viewDidLoad in the case of a view controller
init() {
calculator = Calculator(callback)
}
func loadEstimate() {}
}
It is obviously not exactly what you wanted but it compiles. There seem to be issues when trying to refer to self in an un-initialized object (even when it seems you should be able to because you specify lazy and weak or unowned etc)
Creation of a closure as class variable in constructor of Eloquent Model
Override setAttribute
and getAttribute
on your model:
protected $closures = [];
public function setAttribute($key, $value)
{
if ($value instanceof \Closure)
{
$this->setClosureProperty($key, $value);
}
parent::setAttribute($key, $value);
}
public function getAttribute($key)
{
if (array_key_exists($key, $this->closures)
{
return $this->closures[$key];
}
return parent::getAttribute($key);
}
public function setClosureProperty($key, \Closure $value)
{
$this->closures[$key] = $value;
}
This way the cloures won't be saved in the attributes
array, thus won't be saved and cast to string.
Related Topics
When to Use HTMLspecialchars() Function
Populate a Drop Down Box from a MySQL Table in PHP
PHP Creating Zips Without Path to Files Inside the Zip
PHP Default Function Parameter Values, How to 'Pass Default Value' for 'Not Last' Parameters
How to Use Curl Instead of File_Get_Contents
Convert PDF to Jpeg with PHP and Imagemagick
PHP - Convert Multidimensional Array to 2D Array with Dot Notation Keys
Search for PHP Array Element Containing String
Jquery Ajax Request with JSON Response, How To
Simplest Way to Increment a Date in PHP
Smtp Configuration for PHP Mail
Access Query String Values from Laravel
Convert Jpg Image to Gif, Png & Bmp Format Using PHP