Recursive function acts weird in php - php

I got stuck when I learned about recursive functions in PHP. I know recursive function are those which are being called by itself. My code is:
function addition_no($x,$y) {
if($x==0) {
return $x;
}
return addition_no($x+$y);
}
echo addition_no(1,2);
When I tried executing this code I get:
Warning: Missing argument 2 for addition_no(), called in
/web/com/13978781902261/main.php on line 6 and defined in
/web/com/13978781902261/main.php on line 2
What i need is to add two numbers via recursion.

I created this code in order to summarize values in an array using recursivity is:
<?php
//values to add
$add = array(5,4,4,6,7);
function addval($add,$pos) {
if($pos == 0) {
return $add[0];
}
else {
return $add[$pos] + addval($add,$pos-1);
}
}
//last position in vector
$last_position = count($add)-1;
echo addval($add, $last_position);
?>

You can try this
return addition_no($x,$y);
You have to check any condition for recursive function otherwise it will be infinite recursion..

The warning is appropriate as you call the function inside it self with a different argument structure.
Try the factorial recursive function to learn how it works:
<?php
// Initiating Recursion
echo factorial(5);
//Recursive Function Definition with 1 parameter
function factorial($number)
{
//Break condition for recursion
if($number==1)
return $number;
//Fetch and Stack Recursion
return $number*factorial($number-1);
}
So, you get the basic recursion, in simple English, as :
factorial(n) = n x factorial(n-1) = n x (n-1) x factorial(n-2)
For You particular case, you actually don't need a recursion as your arguments are not relying on the previous argument result. However, for the sake of learning, you can do something like this:
<?php
//Summation
function summation($x) {
if($x==0) {
return $x;
}
return $x+summation($x-1);
}
echo summation(5);
//Summation with 2 step
function summation($x,$y) {
if($x<1) {
return $x;
}
return $x+summation($x-$y,$y);
}
echo summation(5,2);

Related

How to write a function that could be called like func(a)(b)(c) in php?

I need to realize function "calc" that works like that:
$sum = function($a, $b) { return $a + $b; };
calc(5)(3)(2)($sum); // 10
calc(1)(2)($sum); // 3
calc(2)(3)('pow'); // 8
I can write something like this:
function calc(){;
print_r(func_get_args());
return __FUNCTION__;
}
calc(3)(5)(2)('sum');
and it print Array ( [0] => 3 ) Array ( [0] => 5 ) Array ( [0] => 2 ) Array ( [0] => sum ).
So, when I get 'sum' in my function, i should have an array with all previous arguments.
But i have no idea, how can i pass current argument in next function call to manipulate all of them on last iteration. Or is there some sort of recursive solution?
What you're talking about is called Currying. The following code will require PHP 7, since it involves invoking a function returned from another one, which wasn't possible until PHP's Abstract Syntax Tree was implemented in that version.
First things first, you'll need a new sum() function that can operate on an arbitrary number of variables:
$sum = function(...$args) { return array_sum($args); };
Secondly, the important part. A function that returns a new anonymous function, accumulating the arguments as it goes. When you finally pass it something callable (either your $sum function, or a built-in function name like pow), it'll execute it, unpacking the arguments that it's built up.
function calc($x)
{
return function($y = null) use ($x)
{
if (is_callable($y)) {
return $y(...$x);
} else {
$args = (array) $x;
$args[] = $y;
return calc($args);
}
};
}
echo calc(5)(3)(2)($sum); // 10
echo calc(1)(2)($sum); // 3
echo calc(2)(3)('pow'); // 8
See https://3v4l.org/r0emm
(Note that internal functions will be limited to operating on the number of arguments they are defined to take - calc(2)(3)(4)('pow') will raise an error.)
This isn't a particularly common pattern to use (which is probably why you've found it hard to track down), so please for everyone who reads it's sake, think carefully about where you use it.
Credit to the curryAdd answer in this question for the starting blocks.
Edit: I stand corrected, you don't require globals it seems! Definitely use the #iainn's answer over this one.
So to achieve this you're going to have to use globals if you're not doing it within a class to maintain current state. You can see a working example of the below code here (note that it only works for PHP version 7 and above)
<?php
$sum = function(...$args) {
return array_sum($args);
};
function calc(...$args) {
global $globalArguments;
if (is_callable($args[0])) {
$callback = $args[0];
$arguments = array_map(function ($arg) {
return $arg[0];
}, $globalArguments);
return $callback(...$arguments);
}
$globalArguments[] = $args;
return __FUNCTION__;
}
echo calc(3)(2)($sum); // 5
I don't know why you want to do this, but I don't suggest it in production, globals aren't something that should really be used if you can avoid it.
function calc(int $value, Callable $function = null)
{
return function ($v) use ($value, $function) {
$f = function ($call) use ($value, $function) {
return (is_callable($call) && is_callable($function)) ? $call($function($call), $value) : $value;
};
return is_callable($v) ? $f($v) : calc($v, $f);
};
}

php missing argument error for a function

hi guys i am Currently Confused why do i get this error about missing argument when i compile the code it gives me this error Warning: Missing argument 5 for print_LCS(), here is my code:
this is the function
function print_LCS($b,$x,$i,$j,$k){
$fLCS=array();
if ($i==0||$j==0)
{
return 0;
}
if ($b[$i][$j]=='c')
{
print_LCS($b,$x,$i-1,$j-1);
$fLCS[$k] = $x[$i-1]." ";
$k++;
}
elseif ($b[$i][$j]=='u')
{
print_LCS($b,$x,$i-1,$j);
}
else
{
print_LCS($b,$x,$i,$j-1);
}
return array($fLCS);
}
and this is the function call:
list($final)=print_LCS($var2,$first,$var3,$var4,$var5);
hoping for your quick response guys. thank you So much.
The problem is the nested calls to the same function ( presumably for recursion ) as it only has 4 values passed to it.
function print_LCS($b,$x,$i,$j,$k){
$fLCS=array();
if ($i==0||$j==0) {
return 0;
}
if ($b[$i][$j]=='c'){
print_LCS($b,$x,$i-1,$j-1, $XXXXX );/* you need another parameter here or a default value */
$fLCS[$k] = $x[$i-1]." ";
$k++;
} elseif ($b[$i][$j]=='u') {
print_LCS($b,$x,$i-1,$j,$XXXXX);/* you need another parameter here or a default value */
} else {
print_LCS($b,$x,$i,$j-1,$XXXXX);/* you need another parameter here or a default value */
}
return array($fLCS);
}
Not knowing what the funtion is doing it is hard to say whether this might work or cause more issues but you could supply the fifth parameter with a default value in the initial declaration, like:
function print_LCS($b,$x,$i,$j,$k=false){/* rest of function */}
That way it would happily continue at the points it failed - though what the 5th parameter brings to the table is unknown.

Unexpected Result from User Defined Function - PHP

I'm trying to write a simple function which takes two arguments, adds them together and returns the result of the calculation.
Before performing the calculation the function checks whether either of the two arguments are undefined and if so, sets the argument to 0.
Here's my function:
Function - PHP
function returnZeroAdd ($arg, $arg2)
{
if(!isset($arg))
{
$arg = 0;
}
if(!isset($arg2))
{
$arg2 = 0;
}
echo $arg + $arg2;
}
I've tried to execute it like so :
returnZeroAdd($bawtryReturnCount, $bawtryFReturnCount);
But this throws up an undefined variable $bawtryFReturnCount error.
I do not know why the function isn't setting $bawtryFReturnCount) to 0 before performing the calculation thereby negating the 'undefined variable' error.
Can anybody provide a solution?
You cannot do this the way you want. As soon as you use an undefined variable, you will get this error. So the error doesn't occur inside your function, but already occurs in the call to your function.
1. Optional parameters
You might make a parameter optional, like so:
function returnZeroAdd ($arg = 0, $arg2 = 0)
{
return $arg + $arg2;
}
This way, the parameter is optional, and you can call the function like this:
echo returnZeroAdd(); // 0
echo returnZeroAdd(1); // 1
echo returnZeroAdd(1, 1); // 2
2. By reference
But I'm not sure if that is what you want. This call will still fail:
echo returnZeroAdd($undefinedVariable);
That can be solved by passing the variables by reference. You can then check if the values are set and if so, use them in the addition.
<?php
function returnZeroAdd (&$arg, &$arg2)
{
$result = 0;
if(isset($arg))
{
$result += $arg;
}
if(isset($arg2))
{
$result += $arg2;
}
return $result;
}
echo returnZeroAdd($x, $y);
Note that you will actually change the original value of a by reference parameter, if you change it in the function. That's why I changed the code in such a way that the parameters themselves are not modified. Look at this simplified example to see what I mean:
<?php
function example(&$arg)
{
if(!isset($arg))
{
$arg = 0;
}
return $arg;
}
echo example($x); // 0
echo $x // also 0
Of course that might be your intention. If so, you can safely set $arg and $arg2 to 0 inside the function.
The error is not thrown by the function itself, as the function is not aware of the global scope. The error is thrown before even the function is executed, while the PHP interperter is trying to pass $bawtryFReturnCount to the function, one does not find it, and throws error, however, it's not a fatal one and the execution is not stopped. THerefore, the function is executed with a non-set variable with default value of null, where I guess, isset will not work, as the arguments are mandatory, but not optional. A better check here will be empty($arg), however the error will still be present.
Because the functions are not and SHOULD NOT be aware of the global state of your application, you should do these checks from outside the functions and then call it.
if (!isset($bawtryReturnCount)) {
$bawtryReturnCount = 0
}
returnZeroAdd($bawtryReturnCount);
Or assign default values to the arguments in the function, making them optional instead of mandatory.
Your function could be rewritten as:
function returnZeroAdd ($arg = 0, $arg2 = 0)
{
echo $arg + $arg2;
}
You missunderstand how variables work. Since $bawtryFReturnCount isn't defined when you call the function; you get a warning. Your isset-checks performs the checks too late. Example:
$bawtryReturnCount = 4;
$bawtryFReturnCount = 0;
returnZeroAdd($bawtryReturnCount, $bawtryFReturnCount);
Will not result in an error.
If you really want to make the check inside the function you could pass the arguments by reference:
function returnZeroAdd (&$arg, &$arg2)
{
if(!isset($arg))
{
$arg = 0;
}
if(!isset($arg2))
{
$arg2 = 0;
}
echo $arg + $arg2;
}
However this will potentially modify your arguments outside the function, if it is not what you intend to do then you need this:
function returnZeroAdd (&$arg, &$arg2)
{
if(!isset($arg))
{
$localArg = 0;
}
else
{
$localArg = $arg;
}
if(!isset($arg2))
{
$localArg2 = 0;
}
else
{
$localArg2 = $arg2;
}
echo $localArg + $localArg2;
}
You can now pass undefined variables, it won't throw any error.
Alternatively you might want to give a default value to your arguments (in your case 0 seems appropriate):
function returnZeroAdd ($arg = 0, $arg2 = 0)
{
echo $arg + $arg2;
}
You have to define the variable before pass it to an function. for example
$bawtryReturnCount=10;
$bawtryFReturnCount=5;
define the two variable with some value and pass it to that function.
function returnZeroAdd ($arg=0, $arg2=0)
{
echo $arg + $arg2;
}
if you define a function like this means the function takes default value as 0 if the argument is not passed.
for example you can call the functio like this
returnZeroadd();// print 0
returnZeroadd(4);// print 4
returnZeroadd(4,5);// print 9
or you can define two variables and pass it as an argument and call like this.
$bawtryReturnCount=10;
$bawtryFReturnCount=5;
returnZeroadd($bawtryReturnCount, $bawtryFReturnCount);

Recursive function in php storing results without using static

I wrote the following recursive function to keep looping through result looking for $result->pages->next and calling out to curl fetching the next page and aggregating the results. Finally it returns all results as a single object.
private function pager($result) {
static $all_results;
if(isset($result->pages->next) && !empty($result->pages->next)) {
$all_results[] = $this->get_curl_request($result->pages->next);
$this->pager(end($all_results));
} else {
return $all_results;
}
}
However I really don't like using static and it feels poorly implemented and a source of technical debt. What is a more elegant way to do this?
Update
Being called with:
return $this->pager($this->get_curl_request("https://api/request/here"));
Open to changing how it is called.
Try putting $all_result as second parameter like this and add return for this line: $this->pager(end($all_results), $all_results);
Code
private function pager($result, $all_results) {
if(isset($result->pages->next) && !empty($result->pages->next)) {
$all_results[] = $this->get_curl_request($result->pages->next);
return $this->pager(end($all_results), $all_results);
} else {
return $all_results;
}
}
The above code function will return the last updated array $all_results.
Example of use:
$pager_array = $this->pager($result, array());

Calling a PHP function by reference behaving unexpectedly

Iwonder why the out put is 0(zero) for below code snippet? Can anyone please clarify why below code output is zero.
<?php
function a($number)
{
return (b($number) * $number);
}
function b(&$number)
{
++$number;
}
echo a(5); // output 0(zero) ?
?>
You never return any value from the function, and you're trying to echo the return value.
function b(&$number)
{
return ++$number;
}
Note that this is a silly example for a function that takes its parameter by reference, since you don't have a reference to the original value 5. Something like this would be more appropriate:
function b( &$number) {
++$number;
}
$num = 5;
b( $num);
echo $num; // Prints 6
The function name is b, but you are calling a...
Also, you are echoing a function, that doesn't return a value. This means you are echoing a non-initialize variable.
You must either return a value:
return ++$number;
or echo the variable directly:
$number = 5;
b($number);
echo $number;

Categories