34
loading...
This website collects cookies to deliver better user experience
$rectangle
is a constructor function, which returns $rectangle0
- an array representing newly created object instance with public properties and functions on it. Local variables inside $rectangle
functions on the other hand act like private members.<?php
$rectangle = function (int $a, int $b) {
$name = "rectangle";
$is_square = function () use (&$a, &$b) {
return $a === $b;
};
$rectangle0 = [
"get_area" => function () use (&$a, &$b) {
return $a * $b;
},
"get_perimeter" => function () use (&$a, &$b, $is_square) {
return $is_square() ? (4 * $a) : (2 * ($a + $b));
},
"set_a" => function (int $a1) use (&$a) { $a = $a1; },
"set_b" => function (int $b1) use (&$b) { $b = $b1; },
"get_name" => fn() => $name,
"to_string" => function () use (&$rectangle0, &$a, &$b) {
return sprintf("%s: %s x %s", $rectangle0["get_name"](), $a, $b);
},
];
return $rectangle0;
};
$rectangle1 = $rectangle(2, 3);
$rectangle1["get_perimeter"](); // result: 10
$rectangle1["get_area"](); // result: 6
$rectangle2 = $rectangle(4, 4);
$rectangle2["get_perimeter"](); // result: 16
$rectangle2["set_a"](5);
$rectangle2["get_perimeter"](); // result: 18
// 1) $obj is function acting as CONSTRUCTOR
// - passed parameters $param1, $param2 can be later accessed by any private or public properties/functions defined in constructor
$obj = function ($param1, $param2) {
// 2) PRIVATE properties/functions are implemented as local variables
$private_prop1 = 10;
$private_func1 = function () use (&$obj0, &$private_prop1, &$param1, &$private_func1) {
// private function $private_func1 can access other private properties/functions
$private_prop1++;
// private function $private_func1 can access public properties/functions via $obj0 reference (see below)
$obj0["public_prop1"] += $param1;
// function $private_func1 is also able to call itself recursively via $private_func1 reference
if (false) $private_func1();
};
// 3) PUBLIC properties/functions are implemented as values in $obj0 array
// - $obj0 itself represents newly created object instance and is returned from constructor function
$obj0 = [
"public_prop1" => 20,
"public_func1" => function () use (&$obj0, &$private_func1, &$param2) {
// public function public_func1 can access other public properties/functions via $obj0 reference
$obj0["public_prop1"] += $param2;
// public function public_func1 can access private properties/functions
$private_func1();
},
];
return $obj0;
};
// 5) INSTANCE $obj1 will be created by calling constructor function $obj
$obj1 = $obj(10, 20);
$obj1["public_func1"]();
use (...)
construct, which needs to declare all variables from the outer scope that your function needs to use. Especially ensure you declare variables by reference (use (&$private_prop1)
) instead of by value (use ($private_prop1)
), otherwise the variable value in the inner scope will not match future changes of the variable in outer scope and it also won't be possible to edit the variable from the inner scope.$obj1["functions_group1"]["function1"]();
: member function function1
has been placed into functions_group1
, which is just a nested array of functions).Constructor function is standard variable (Closure
object) and can be manipulated easily.
$foo = fn($rectangle) => $rectangle(4,5);
$foo($rectangle);
::class
constant:
$foo = fn($className) => new $className(4,5);
$foo(Rectangle::class);
instanceof
or get_class()
is not possible.include
it manually.use (...)
construct is annoying and causes code bloat.