i am trying to use this code:
$arr = [
function ($a) {
return $a + $a;
},
function ($b) {
return $b * $b;
},
function ($c,$cc) {
return $c % $cc - $c;
},
function ($d) {
return $d + 4 / $d;
}
];
how can i pass parameters to this functions?
i have already learned this statment for function with no arguments. for example:
function () { echo 'somethings'; } that's mean this function in an array don't have incoming arguments.
$test = rand (0,1);
echo $myarr[$test]();
In addition
can i change (rand) statment with other statment in the above code snippet?
You can do the following:
Your array:
$arr = [
function ($a) {
return $a + $a;
},
function ($b) {
return $b * $b;
},
function ($c,$cc) {
return $c % $cc - $c;
},
function ($d) {
return $d + 4 / $d;
}
];
Your rand
$test = rand(0,1);
---- note ----
you can change your rand() to any other statement provided that it an existing index of the $arr array. in order to know if $test value is an index which exists in the $arr array, you can do
if (isset($arr[$test])) {}
---- end note ---
to call the functions
$returnedValue = call_user_func($arr[$test], 10);
echo $returnedValue;
Related
I'm new using PHP, and I'm trying to store functions in an array to call them later using an if statement.
I've tried but, functions are called before if statement, so this is an example of what I need:
function a() {
return 'a';
}
function b() {
return 'b';
}
$array = [a(), b()];
if($condition === 'a') {
$array[0];
}
What I want to achieve is to use a specific function depending on if validation.
Just store the function name as a string and call call_user_func.
function a() {
return 'a';
}
function b() {
return 'b';
}
$array = ['a', 'b'];
if($condition === 'a') {
call_user_func($array[0]);
}
Example:
<?php
$funcArray = [
'a' => function($in) {
print("$in\n");
},
'b' => function($in) {
print("$in\n");
}
];
foreach(array_keys($funcArray) as $key)
{
$funcArray[$key]($key);
}
You'd either have to use call_user_func or use a anonymous function like so:
$array = [
function() { return 'a'; },
function() { return 'b'; }
];
I'm try to solve a task which uses new functions php7 uniform variable syntax nested () support foo()() (https://wiki.php.net/rfc/uniform_variable_syntax).
I need write function test for this code:
$sum = function($a, $b) { return $a + $b; };
test(6)(2)(3)($sum); // 11
test(3)(1)($sum); // 4
test(3)(3)('pow'); // 27
I don't found any explanation for this feature. Where can I find how to use it? I see that I must return function name in function test, but how to pass argument?
Thanks all for help. It's something like this:
<?php
function test($a) {
echo '<br/>';
$arr[] = $a;
return $mf = function($b) use(&$mf, &$a, &$arr) {
if(gettype($b) == 'object') {
echo(array_reduce($arr, $b));
} elseif (gettype($b) == 'string') {
if($b == 'pow') {
echo array_reduce($arr, function ($carry, $a) {
return !empty($carry) ? pow($carry, $a) : $a;
});
}
} elseif (gettype($b) == 'integer') {
$arr[] = $b;
}
return $mf;
};
}
$sum = function($a, $b) { return $a + $b; };
test(6)(2)(3)($sum); // 11
test(3)(1)($sum); // 4
test(3)(3)('pow'); // 27
This is more about nested recursive functions, or currying, than that rfc. That rfc just enabled the syntax that supported it.
This uses recursion until you pass a callable:
function test($var) {
$values = [$var];
$function = function($callback) use (&$values, &$function) {
if (is_callable($callback)) {
return array_reduce(array_slice($values, 1), $callback, $values[0]);
}
$values[] = $callback;
return $function;
};
return $function;
}
Because your functions expect two parameters but your nesting could have unlimited parameters, it's best to use an array and array reduce.
However, since multiplication functions like pow won't work with a null initial value, you can specify the initial value as the first passed parameter from the array.
I use multiple construct from this site.
I modified it for my needs.
I get fatal errors:
Missing argument 3 for ChildClass::__construct2()
and chained errors...
Missing argument 4 for ChildClass::__construct2()
Missing argument 5 for ChildClass::__construct2()
Undefined variable: c
Undefined variable: d
And both constructors have part of identical code. How can I put it in common __construct.
$arr = array (
"key1" => "val1",
"key2" => "val2"
);
$demo = new Demo("stack", $arr );
class ParentClass {
function __construct($var1 = "1", $var2 = "2"){
// distinctly different code
}
}
class ChildClass extends ParentClass {
function __construct(){
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
function __construct1( $a, array $e ) {
$this->ex = $a;
$this->ex3 = $e['key1'];
$this->ex4 = $e['key2'];
}
function __construct2( $a, $b, $c, $d, array $e ) {
$this->ex = $a + 1 - $v + $c; //example
$this->ex2 = $d;
$this->ex3 = $e['key1'];
$this->ex4 = $e['key2'];
}
}
And both constructors have part of identical code. How can I put it in common __construct.
thanks.
The number specified after __construct tells how many parameter it will except . You specified 2 after __construct but you are giving it 5 parameters because of which it is giving the error. Change 2 to 5.Also rename __construct1 to __construct2 Use the code below
$arr = array (
"key1" => "val1",
"key2" => "val2"
);
$demo = new Demo("stack", $arr );
class ParentClass {
function __construct($var1 = "1", $var2 = "2"){
// distinctly different code
}
}
class ChildClass extends ParentClass {
function __construct(){
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
function __construct2( $a, array $e ) {
$this->ex = $a;
$this->setE($e);
}
function __construct5( $a, $b, $c, $d, array $e ) {
$this->ex = $a + 1 - $v + $c; //example
$this->ex2 = $d;
$this->ex3 = $e['key1'];
$this->ex4 = $e['key2'];
}
}
Hope this helps you
It's because the 2 in __construct2 tells it expects 2 parameters, but it expects 5. Change the name to __construct5.
To put the identical code to one place, make it separate method that will be called from both constructors, full code:
class ChildClass extends ParentClass {
function __construct(){
$a = func_get_args();
$i = func_num_args();
if (method_exists($this,$f='__construct'.$i)) {
call_user_func_array(array($this,$f),$a);
}
}
function __construct2( $a, array $e ) { // rename method: 1 => 2
$this->ex = $a;
$this->setE($e);
}
function __construct5( $a, $b, $c, $d, array $e ) { // rename method: 2 => 5
$this->ex = $a + 1 - $v + $c; //example
$this->ex2 = $d;
$this->setE($e);
}
private function setE(array $e) {
$this->ex3 = $e['key1'];
$this->ex4 = $e['key2'];
}
}
Here is what I want to do:
$newArray = array();
foreach($student as $s){
$newArray[$s->id][$s->grade] = $s;
}
I want to sort the students by their grades (more of a group than a sort) but I just want the grades to be sorted not the id. I could have don't this:
$newArray[$s->id] = $s->grade
asort($newArray)
but I need the remaining data in $s. Also, there is huge chunk of data associated with each student which I want to maintain.
How can I achieve such a sorting?
Edit:
Sine you're working in a framework, best declare your sort callback as a member function (inside the same class as where you'll be needing it, of course):
private function sortCB(array $a, array $b)
{//the array type hinting in arguments is optional
$i = array_keys($a);//but highly recommended
$j = array_keys($b);
if (end($i) === end($j))
{
return 0;
}
//replace '>' with '<' if you want to sort descending
return (end($i) > end($j) ? 1 : -1);//this is ascending
}
Then, in the method where the actual sorting is needed:
uasort($theArray,array($this,'sortCB'));
For more examples, see the docs. I've added a full class example at the end of this (bulky) answer
I've tried this on writecodeonline, which isn't all too good at this kind of stuff, but this did work:
$foo = array_fill_keys(array('foo','bar','q','Bond'),array());
$i = '256';
foreach($foo as $k=>$v)
{
$foo[$k][$i] = $k;
$i = (string)((int)$i%2 === 0 ? ((int)$i/2)+1 : (int)$i*3);
}
function sortCB($a,$b)
{
$i = array_keys($a);
$j = array_keys($b);
if (end($i) === end($j))
{
return 0;
}
return (end($i) > end($j) ? 1 : -1);
}
uasort($foo,'sortCB');
var_dump($foo);
But since you're using a framework, you might do well declaring that function as a member function private function sortCB(array $a,array $b), and use it like so:
uasort($foo,array($this, 'sortCB'));
There might be some more info on how best to use this callback function in a class context here
Full example + usage (tested and working):
class test
{
public $foo = null;
public function __construct()
{
$this->foo = array_fill_keys(array('foo','bar','q','Bond'),array());
$i = '256';
foreach($this->foo as $k=>$v)
{
$this->foo[$k][$i] = $k;
$i = (string)((int)$i%2 === 0 ? ((int)$i/2)+1 : (int)$i*3);
}
}
private function sortCB($a,$b)
{
$i = array_keys($a);
$j = array_keys($b);
if (end($i) === end($j))
{
return 0;
}
return (end($i) > end($j) ? 1 : -1);
}
public function sortFoo()
{
uasort($this->foo,array($this,'sortCB'));
print_r($this->foo);
return $this->foo;
}
}
$bar = new test();
$arr = $bar->sortFoo();
You can do something like:
foreach($student as $s){
$newArray[$s->id] = $s;
}
usort($newArray, function ($a, $b) { return $a->grade - $b->grade; });
Edit
For later versions that don't support anonymous functions you can define comparison function first:
function sortByGrade($a, $b)
{
return $a->grade - $b->grade;
}
usort($newArray, 'sortByGrade');
But if you get this data from db it would be easier to order it in your sql query. If you use ORM you can use its associated method.
suppose i have two nested function like this :
$a = 1;
$b = 2;
function test(){
$b = 20;
function Sum()
{
$b = $GLOBALS['a'] + $b;
}
}
test();
Sum();
echo $b;
now i want in function Sum() access to $b variable declared in function test();
How do you do?
Wild-Guessing-mode:
Your function Sum() would "normaly" take two parameters/operands like
function Sum($a, $b) {
return $a+$b;
}
echo Sum(1, 20);
Now you have the function Test() and you want it to return a function fn that takes only one parameter and then calls Sum($a, $b) with one "pre-defined" parameter and the one passed to fn.
That's called either currying or partial application (depending on what exactly you implement) and you can do something like that with lambda functions/closures since php 5.3
<?php
function Sum($a, $b) {
return $a + $b;
}
function foo($a) {
return function($b) use ($a) {
return Sum($a, $b);
};
}
$fn = foo(1) // -> Sum(1, $b);
$fn = foo(2) // -> Sum(2, $b);
echo $fn(47);
Why not use this?
$a = 1;
$b = 2;
function test(){
$b = Sum(20);
}
function Sum($value)
{
$value = $GLOBALS['a'] + $value;
return $value;
}
test();
// Sum(); // Why do you need this here??
echo $b;
Edit: Better without globals
$a = 1;
$b = 2;
function Sum($value1, $value2)
{
return $value1 + $value2;
}
$b = 20; // you could call Sum($a, 20); instead
$b = Sum($a, $b);
echo $b;
According to the Context best way is to pass the variable to the function like this
Sum($b)
But if you are looking for an alternative then you can use closures
but REMEMBER PHP<5.3 does not support closures
You can do
$a = 1;
$b = 2;
function test() {
$b = 20;
function Sum() use($b)
{
$b = $GLOBALS['a'] + $b;
}
}
test();
Sum();
echo $b;