Dynamic functions, variable inputs - php

Right now, lets say I have code much like this...
$some_var=returnsUserInput();
function funcA($a) {...}
function funcB($a,$b) {...}
function funcC($a,$b,$c) {...}
$list[functionA] = "funcA";
$list[functionB] = "funcB";
$list[functionC] = "funcC";
$temp_call = list[$some_var];
//Not sure how to do this below, just an example to show the idea of what I want.
$temp_call($varC1,varC2,$varC3);
$temp_call($varB1,varB2);
$temp_call($varA1);
My problem starts here, how can I specify the proper variables into the arguments depending on these? I have a few thoughts such as creating a list for each function that specifies these, but I would really like to see an elegant solution to this.

You need to use call_user_func or call_user_func_array.
<?php
// if you know the parameters in advance.
call_user_func($temp_call, $varC1, $varC2);
// If you have an array of params.
call_user_func_array($temp_call, array($varB1, $varB2));
?>

You want something like the following?
function test()
{
$num_args = func_num_args();
$args = func_get_args();
switch ($num_args) {
case 0:
return 'none';
break;
case 1:
return $args[0];
break;
case 2:
return $args[0] . ' - ' . $args[1];
break;
default:
return implode($args, ' - ');
break;
}
}
echo test(); // 'none'
echo test(1); // 1
echo test(1, 2); // 1 - 2
echo test(1, 2, 3); // 1 - 2 - 3
It'd act as some sort of delegation method.
Or what about just accepting an array rather than paramaters?
function funcA($params)
{
extract($params);
echo $a;
}
function funcB($params)
{
extract($params);
echo $a, $b;
}
function funcC($params)
{
extract($params);
echo $a, $b, $c;
}
$funcs = array('funcA', 'funcB', 'funcC');
$selected = $funcs[0];
$selected(array('a' => 'test', 'b' => 'test2'));
// or something like (beware of security issues)
$selected($_GET);

You can't and maybe that's good to. You can find the amount of arguments with if/else.
if($temp_call == "funcA") { .....} elseif(...)...

Related

Function doesn't save variable

I'm trying to add 1 to a number each time a function is called, but for some reason, the total number is always same.
Here is my current code:
<?php
$total;
function draw_card() {
global $total;
$total=$total+1;
echo $total;
}
draw_card();
draw_card();
?>
Personally, I would not use globals, but if I was forced at gunpoint I would handle state within the function, so outside variables did not pollute the value. I would also make an arbitrary long key name which I would not use anywhere else.
<?php
function draw_card($initial = 0) {
$GLOBALS['draw_card_total'] = (
isset($GLOBALS['draw_card_total']) ? $GLOBALS['draw_card_total']+1 : $initial
);
return $GLOBALS['draw_card_total'];
}
// optionally set your start value
echo draw_card(1); // 1
echo draw_card(); // 2
https://3v4l.org/pinSi
But I would more likely go with a class, which holds state by default, plus its more verbose as to whats happening.
<?php
class cards {
public $total = 0;
public function __construct($initial = 0)
{
$this->total = $initial;
}
public function draw()
{
return ++$this->total;
}
public function getTotal()
{
return $this->total;
}
}
$cards = new cards();
echo $cards->draw(); // 1
echo $cards->draw(); // 2
echo $cards->getTotal(); // 2
https://3v4l.org/lfbcL
Since it is global already, you can use it outside the function.
<?php
$total;
function draw_card() {
global $total;
$total=$total+1;
//echo $total;
}
draw_card();
draw_card();
draw_card();
echo "Current Count :", $total;
?>
Result :
Current Count :3
This will increment the number of times you call the function.
Since you echoed the result/total each time without a delimiter, you might have considered the output to be 12(Assumption)
Functions have a scope.. you just need to bring $total into the scope of the function... best to not do it globally but as an argument.
$total = 0;
function draw_card($total) {
return $total + 1;
}
$total = draw_card($total);
//Expected Output = 1
$total = draw_card($total);
//Expected Output = 2

How to overwrite php _() function [duplicate]

Coming from C++ background ;)
How can I overload PHP functions?
One function definition if there are any arguments, and another if there are no arguments?
Is it possible in PHP? Or should I use if else to check if there are any parameters passed from $_GET and POST?? and relate them?
You cannot overload PHP functions. Function signatures are based only on their names and do not include argument lists, so you cannot have two functions with the same name. Class method overloading is different in PHP than in many other languages. PHP uses the same word but it describes a different pattern.
You can, however, declare a variadic function that takes in a variable number of arguments. You would use func_num_args() and func_get_arg() to get the arguments passed, and use them normally.
For example:
function myFunc() {
for ($i = 0; $i < func_num_args(); $i++) {
printf("Argument %d: %s\n", $i, func_get_arg($i));
}
}
/*
Argument 0: a
Argument 1: 2
Argument 2: 3.5
*/
myFunc('a', 2, 3.5);
PHP doesn't support traditional method overloading, however one way you might be able to achieve what you want, would be to make use of the __call magic method:
class MyClass {
public function __call($name, $args) {
switch ($name) {
case 'funcOne':
switch (count($args)) {
case 1:
return call_user_func_array(array($this, 'funcOneWithOneArg'), $args);
case 3:
return call_user_func_array(array($this, 'funcOneWithThreeArgs'), $args);
}
case 'anotherFunc':
switch (count($args)) {
case 0:
return $this->anotherFuncWithNoArgs();
case 5:
return call_user_func_array(array($this, 'anotherFuncWithMoreArgs'), $args);
}
}
}
protected function funcOneWithOneArg($a) {
}
protected function funcOneWithThreeArgs($a, $b, $c) {
}
protected function anotherFuncWithNoArgs() {
}
protected function anotherFuncWithMoreArgs($a, $b, $c, $d, $e) {
}
}
To over load a function simply do pass parameter as null by default,
class ParentClass
{
function mymethod($arg1 = null, $arg2 = null, $arg3 = null)
{
if( $arg1 == null && $arg2 == null && $arg3 == null ){
return 'function has got zero parameters <br />';
}
else
{
$str = '';
if( $arg1 != null )
$str .= "arg1 = ".$arg1." <br />";
if( $arg2 != null )
$str .= "arg2 = ".$arg2." <br />";
if( $arg3 != null )
$str .= "arg3 = ".$arg3." <br />";
return $str;
}
}
}
// and call it in order given below ...
$obj = new ParentClass;
echo '<br />$obj->mymethod()<br />';
echo $obj->mymethod();
echo '<br />$obj->mymethod(null,"test") <br />';
echo $obj->mymethod(null,'test');
echo '<br /> $obj->mymethod("test","test","test")<br />';
echo $obj->mymethod('test','test','test');
It may be hackish to some, but I learned this way from how Cakephp does some functions and have adapted it because I like the flexibility it creates
The idea is you have different type of arguments, arrays, objects etc, then you detect what you were passed and go from there
function($arg1, $lastname) {
if(is_array($arg1)){
$lastname = $arg1['lastname'];
$firstname = $arg1['firstname'];
} else {
$firstname = $arg1;
}
...
}
<?php
// download example: https://github.com/hishamdalal/overloadable
#> 1. Include Overloadable class
class Overloadable
{
static function call($obj, $method, $params=null) {
$class = get_class($obj);
// Get real method name
$suffix_method_name = $method.self::getMethodSuffix($method, $params);
if (method_exists($obj, $suffix_method_name)) {
// Call method
return call_user_func_array(array($obj, $suffix_method_name), $params);
}else{
throw new Exception('Tried to call unknown method '.$class.'::'.$suffix_method_name);
}
}
static function getMethodSuffix($method, $params_ary=array()) {
$c = '__';
if(is_array($params_ary)){
foreach($params_ary as $i=>$param){
// Adding special characters to the end of method name
switch(gettype($param)){
case 'array': $c .= 'a'; break;
case 'boolean': $c .= 'b'; break;
case 'double': $c .= 'd'; break;
case 'integer': $c .= 'i'; break;
case 'NULL': $c .= 'n'; break;
case 'object':
// Support closure parameter
if($param instanceof Closure ){
$c .= 'c';
}else{
$c .= 'o';
}
break;
case 'resource': $c .= 'r'; break;
case 'string': $c .= 's'; break;
case 'unknown type':$c .= 'u'; break;
}
}
}
return $c;
}
// Get a reference variable by name
static function &refAccess($var_name) {
$r =& $GLOBALS["$var_name"];
return $r;
}
}
//----------------------------------------------------------
#> 2. create new class
//----------------------------------------------------------
class test
{
private $name = 'test-1';
#> 3. Add __call 'magic method' to your class
// Call Overloadable class
// you must copy this method in your class to activate overloading
function __call($method, $args) {
return Overloadable::call($this, $method, $args);
}
#> 4. Add your methods with __ and arg type as one letter ie:(__i, __s, __is) and so on.
#> methodname__i = methodname($integer)
#> methodname__s = methodname($string)
#> methodname__is = methodname($integer, $string)
// func(void)
function func__() {
pre('func(void)', __function__);
}
// func(integer)
function func__i($int) {
pre('func(integer '.$int.')', __function__);
}
// func(string)
function func__s($string) {
pre('func(string '.$string.')', __function__);
}
// func(string, object)
function func__so($string, $object) {
pre('func(string '.$string.', '.print_r($object, 1).')', __function__);
//pre($object, 'Object: ');
}
// func(closure)
function func__c(Closure $callback) {
pre("func(".
print_r(
array( $callback, $callback($this->name) ),
1
).");", __function__.'(Closure)'
);
}
// anotherFunction(array)
function anotherFunction__a($array) {
pre('anotherFunction('.print_r($array, 1).')', __function__);
$array[0]++; // change the reference value
$array['val']++; // change the reference value
}
// anotherFunction(string)
function anotherFunction__s($key) {
pre('anotherFunction(string '.$key.')', __function__);
// Get a reference
$a2 =& Overloadable::refAccess($key); // $a2 =& $GLOBALS['val'];
$a2 *= 3; // change the reference value
}
}
//----------------------------------------------------------
// Some data to work with:
$val = 10;
class obj {
private $x=10;
}
//----------------------------------------------------------
#> 5. create your object
// Start
$t = new test;
#> 6. Call your method
// Call first method with no args:
$t->func();
// Output: func(void)
$t->func($val);
// Output: func(integer 10)
$t->func("hello");
// Output: func(string hello)
$t->func("str", new obj());
/* Output:
func(string str, obj Object
(
[x:obj:private] => 10
)
)
*/
// call method with closure function
$t->func(function($n){
return strtoupper($n);
});
/* Output:
func(Array
(
[0] => Closure Object
(
[parameter] => Array
(
[$n] =>
)
)
[1] => TEST-1
)
);
*/
## Passing by Reference:
echo '<br><br>$val='.$val;
// Output: $val=10
$t->anotherFunction(array(&$val, 'val'=>&$val));
/* Output:
anotherFunction(Array
(
[0] => 10
[val] => 10
)
)
*/
echo 'Result: $val='.$val;
// Output: $val=12
$t->anotherFunction('val');
// Output: anotherFunction(string val)
echo 'Result: $val='.$val;
// Output: $val=36
// Helper function
//----------------------------------------------------------
function pre($mixed, $title=null){
$output = "<fieldset>";
$output .= $title ? "<legend><h2>$title</h2></legend>" : "";
$output .= '<pre>'. print_r($mixed, 1). '</pre>';
$output .= "</fieldset>";
echo $output;
}
//----------------------------------------------------------
In PHP 5.6 you can use the splat operator ... as the last parameter and do away with func_get_args() and func_num_args():
function example(...$args)
{
count($args); // Equivalent to func_num_args()
}
example(1, 2);
example(1, 2, 3, 4, 5, 6, 7);
You can use it to unpack arguments as well:
$args[] = 1;
$args[] = 2;
$args[] = 3;
example(...$args);
Is equivalent to:
example(1, 2, 3);
What about this:
function($arg = NULL) {
if ($arg != NULL) {
etc.
etc.
}
}
<?php
class abs
{
public function volume($arg1=null, $arg2=null, $arg3=null)
{
if($arg1 == null && $arg2 == null && $arg3 == null)
{
echo "function has no arguments. <br>";
}
else if($arg1 != null && $arg2 != null && $arg3 != null)
{
$volume=$arg1*$arg2*$arg3;
echo "volume of a cuboid ".$volume ."<br>";
}
else if($arg1 != null && $arg2 != null)
{
$area=$arg1*$arg2;
echo "area of square = " .$area ."<br>";
}
else if($arg1 != null)
{
$volume=$arg1*$arg1*$arg1;
echo "volume of a cube = ".$volume ."<br>";
}
}
}
$obj=new abs();
echo "For no arguments. <br>";
$obj->volume();
echo "For one arguments. <br>";
$obj->volume(3);
echo "For two arguments. <br>";
$obj->volume(3,4);
echo "For three arguments. <br>";
$obj->volume(3,4,5);
?>
Sadly there is no overload in PHP as it is done in C#. But i have a little trick. I declare arguments with default null values and check them in a function. That way my function can do different things depending on arguments. Below is simple example:
public function query($queryString, $class = null) //second arg. is optional
{
$query = $this->dbLink->prepare($queryString);
$query->execute();
//if there is second argument method does different thing
if (!is_null($class)) {
$query->setFetchMode(PDO::FETCH_CLASS, $class);
}
return $query->fetchAll();
}
//This loads rows in to array of class
$Result = $this->query($queryString, "SomeClass");
//This loads rows as standard arrays
$Result = $this->query($queryString);

in specific condition set and store a variable until another specific condition

Hello I'm pretty new in programming. I need to solve this problem in php but the solution in any different language will be great. I tryied to solve it with if statement but if condition is changed the variable is gone. Easy example for better understanding.
// possible conditions ( 'cond1', 'cond2', 'cond3', 'cond4','cond5' )
// conditions can be called randomly
I would like to have somethng like this:
$variable = 'off';
since ( $condition == 'cond2' )
$variable = 'on';
until ( $condition == 'cond4' )
The goal is to switch variable 'on' in the 'cond2' condition and hold it on when the others conditions are changing independently on their order until condition is changed to 'cond4' and variable is switched back to 'off'.
Thanks for any suggestions.
I don't think your current concept is realizable in PHP as you cannot listen to variables, you need to actively get notified. So one scenario with the same solution but a different concept would be
class Condition {
private $value;
private $variable = false;
public function setCondition($new_value) {
$this->value = $new_value;
}
public function getCondition() {
return $this->value;
}
public function isVariableSet() {
return ($this->variable === true); //TRUE if $this->variable is true
//FALSE otherwise
}
}
Now in the method setCondition(...) you can listen and actively set the variable.
public function setCondition($new_value) {
switch ($new_value) {
case 'cond2':
$this->variable = true;
break;
case 'cond4':
$this->variable = false;
break;
}
$this->value = $new_value;
}
With this you can use it like the following
$foo = new Condition();
$foo->setCondition('cond1');
var_dump( $foo->isVariableSet() ); //FALSE
$foo->setCondition('cond2');
var_dump( $foo->isVariableSet() ); //TRUE
$foo->setCondition('cond3');
var_dump( $foo->isVariableSet() ); //TRUE
$foo->setCondition('cond4');
var_dump( $foo->isVariableSet() ); //FALSE
Or in your case:
$conditions = array( 'cond1', 'cond2', 'cond3', 'cond4','cond5' );
$cond = new Condition();
foreach ($conditions as $i => $condition) {
$cond->setCondition($condition);
if ($cond->isVariableSet() == true) {
$toggle = 'on';
}
else {
$toggle = 'off';
}
$results[$condition] = $toggle.' ; ';
}
If you don't create the instance of Condition outside the loop, you gain nothing as you create a new object everytime and no state stays. However, exactly that is required.
You can also do this via array_map() and save the foreach()
$conditions = array( 'cond1', 'cond2', 'cond3', 'cond4','cond5' );
$cond = new Condition();
$results = array();
$setCondGetVariable = function($condition) use($cond) {
$cond->setCondition($condition);
if ($cond->isVariableSet() == true) {
$toggle = 'on';
}
else {
$toggle = 'off';
}
return $toggle.' ; ';
};
$results = array_map($setCondGetVariable, $conditions);

Detecting negative numbers

I was wondering if there is any way to detect if a number is negative in PHP?
I have the following code:
$profitloss = $result->date_sold_price - $result->date_bought_price;
I need to find out if $profitloss is negative and if it is, I need to echo out that it is.
if ($profitloss < 0)
{
echo "The profitloss is negative";
}
Edit: I feel like this was too simple an answer for the rep so here's something that you may also find helpful.
In PHP we can find the absolute value of an integer by using the abs() function. For example if I were trying to work out the difference between two figures I could do this:
$turnover = 10000;
$overheads = 12500;
$difference = abs($turnover-$overheads);
echo "The Difference is ".$difference;
This would produce The Difference is 2500.
I believe this is what you were looking for:
class Expression {
protected $expression;
protected $result;
public function __construct($expression) {
$this->expression = $expression;
}
public function evaluate() {
$this->result = eval("return ".$this->expression.";");
return $this;
}
public function getResult() {
return $this->result;
}
}
class NegativeFinder {
protected $expressionObj;
public function __construct(Expression $expressionObj) {
$this->expressionObj = $expressionObj;
}
public function isItNegative() {
$result = $this->expressionObj->evaluate()->getResult();
if($this->hasMinusSign($result)) {
return true;
} else {
return false;
}
}
protected function hasMinusSign($value) {
return (substr(strval($value), 0, 1) == "-");
}
}
Usage:
$soldPrice = 1;
$boughtPrice = 2;
$negativeFinderObj = new NegativeFinder(new Expression("$soldPrice - $boughtPrice"));
echo ($negativeFinderObj->isItNegative()) ? "It is negative!" : "It is not negative :(";
Do however note that eval is a dangerous function, therefore use it only if you really, really need to find out if a number is negative.
:-)
if(x < 0)
if(abs(x) != x)
if(substr(strval(x), 0, 1) == "-")
You could check if $profitloss < 0
if ($profitloss < 0):
echo "Less than 0\n";
endif;
if ( $profitloss < 0 ) {
echo "negative";
};
Don't get me wrong, but you can do this way ;)
function nagitive_check($value){
if (isset($value)){
if (substr(strval($value), 0, 1) == "-"){
return 'It is negative<br>';
} else {
return 'It is not negative!<br>';
}
}
}
Output:
echo nagitive_check(-100); // It is negative
echo nagitive_check(200); // It is not negative!
echo nagitive_check(200-300); // It is negative
echo nagitive_check(200-300+1000); // It is not negative!
Just multiply the number by -1 and check if the result is positive.
You could use a ternary operator like this one, to make it a one liner.
echo ($profitloss < 0) ? 'false' : 'true';
I assume that the main idea is to find if number is negative and display it in correct format.
For those who use PHP5.3 might be interested in using Number Formatter Class - http://php.net/manual/en/class.numberformatter.php. This function, as well as range of other useful things, can format your number.
$profitLoss = 25000 - 55000;
$a= new \NumberFormatter("en-UK", \NumberFormatter::CURRENCY);
$a->formatCurrency($profitLoss, 'EUR');
// would display (€30,000.00)
Here also a reference to why brackets are used for negative numbers:
http://www.open.edu/openlearn/money-management/introduction-bookkeeping-and-accounting/content-section-1.7
Can be easily achieved with a ternary operator.
$is_negative = $profitloss < 0 ? true : false;
I wrote a Helper function for my Laravel project but can be used anywhere.
function isNegative($value){
if(isset($value)) {
if ((int)$value > 0) {
return false;
}
return (int)$value < 0 && substr(strval($value), 0, 1) === "-";
}
}

PHP function overloading

Coming from C++ background ;)
How can I overload PHP functions?
One function definition if there are any arguments, and another if there are no arguments?
Is it possible in PHP? Or should I use if else to check if there are any parameters passed from $_GET and POST?? and relate them?
You cannot overload PHP functions. Function signatures are based only on their names and do not include argument lists, so you cannot have two functions with the same name. Class method overloading is different in PHP than in many other languages. PHP uses the same word but it describes a different pattern.
You can, however, declare a variadic function that takes in a variable number of arguments. You would use func_num_args() and func_get_arg() to get the arguments passed, and use them normally.
For example:
function myFunc() {
for ($i = 0; $i < func_num_args(); $i++) {
printf("Argument %d: %s\n", $i, func_get_arg($i));
}
}
/*
Argument 0: a
Argument 1: 2
Argument 2: 3.5
*/
myFunc('a', 2, 3.5);
PHP doesn't support traditional method overloading, however one way you might be able to achieve what you want, would be to make use of the __call magic method:
class MyClass {
public function __call($name, $args) {
switch ($name) {
case 'funcOne':
switch (count($args)) {
case 1:
return call_user_func_array(array($this, 'funcOneWithOneArg'), $args);
case 3:
return call_user_func_array(array($this, 'funcOneWithThreeArgs'), $args);
}
case 'anotherFunc':
switch (count($args)) {
case 0:
return $this->anotherFuncWithNoArgs();
case 5:
return call_user_func_array(array($this, 'anotherFuncWithMoreArgs'), $args);
}
}
}
protected function funcOneWithOneArg($a) {
}
protected function funcOneWithThreeArgs($a, $b, $c) {
}
protected function anotherFuncWithNoArgs() {
}
protected function anotherFuncWithMoreArgs($a, $b, $c, $d, $e) {
}
}
To over load a function simply do pass parameter as null by default,
class ParentClass
{
function mymethod($arg1 = null, $arg2 = null, $arg3 = null)
{
if( $arg1 == null && $arg2 == null && $arg3 == null ){
return 'function has got zero parameters <br />';
}
else
{
$str = '';
if( $arg1 != null )
$str .= "arg1 = ".$arg1." <br />";
if( $arg2 != null )
$str .= "arg2 = ".$arg2." <br />";
if( $arg3 != null )
$str .= "arg3 = ".$arg3." <br />";
return $str;
}
}
}
// and call it in order given below ...
$obj = new ParentClass;
echo '<br />$obj->mymethod()<br />';
echo $obj->mymethod();
echo '<br />$obj->mymethod(null,"test") <br />';
echo $obj->mymethod(null,'test');
echo '<br /> $obj->mymethod("test","test","test")<br />';
echo $obj->mymethod('test','test','test');
It may be hackish to some, but I learned this way from how Cakephp does some functions and have adapted it because I like the flexibility it creates
The idea is you have different type of arguments, arrays, objects etc, then you detect what you were passed and go from there
function($arg1, $lastname) {
if(is_array($arg1)){
$lastname = $arg1['lastname'];
$firstname = $arg1['firstname'];
} else {
$firstname = $arg1;
}
...
}
<?php
// download example: https://github.com/hishamdalal/overloadable
#> 1. Include Overloadable class
class Overloadable
{
static function call($obj, $method, $params=null) {
$class = get_class($obj);
// Get real method name
$suffix_method_name = $method.self::getMethodSuffix($method, $params);
if (method_exists($obj, $suffix_method_name)) {
// Call method
return call_user_func_array(array($obj, $suffix_method_name), $params);
}else{
throw new Exception('Tried to call unknown method '.$class.'::'.$suffix_method_name);
}
}
static function getMethodSuffix($method, $params_ary=array()) {
$c = '__';
if(is_array($params_ary)){
foreach($params_ary as $i=>$param){
// Adding special characters to the end of method name
switch(gettype($param)){
case 'array': $c .= 'a'; break;
case 'boolean': $c .= 'b'; break;
case 'double': $c .= 'd'; break;
case 'integer': $c .= 'i'; break;
case 'NULL': $c .= 'n'; break;
case 'object':
// Support closure parameter
if($param instanceof Closure ){
$c .= 'c';
}else{
$c .= 'o';
}
break;
case 'resource': $c .= 'r'; break;
case 'string': $c .= 's'; break;
case 'unknown type':$c .= 'u'; break;
}
}
}
return $c;
}
// Get a reference variable by name
static function &refAccess($var_name) {
$r =& $GLOBALS["$var_name"];
return $r;
}
}
//----------------------------------------------------------
#> 2. create new class
//----------------------------------------------------------
class test
{
private $name = 'test-1';
#> 3. Add __call 'magic method' to your class
// Call Overloadable class
// you must copy this method in your class to activate overloading
function __call($method, $args) {
return Overloadable::call($this, $method, $args);
}
#> 4. Add your methods with __ and arg type as one letter ie:(__i, __s, __is) and so on.
#> methodname__i = methodname($integer)
#> methodname__s = methodname($string)
#> methodname__is = methodname($integer, $string)
// func(void)
function func__() {
pre('func(void)', __function__);
}
// func(integer)
function func__i($int) {
pre('func(integer '.$int.')', __function__);
}
// func(string)
function func__s($string) {
pre('func(string '.$string.')', __function__);
}
// func(string, object)
function func__so($string, $object) {
pre('func(string '.$string.', '.print_r($object, 1).')', __function__);
//pre($object, 'Object: ');
}
// func(closure)
function func__c(Closure $callback) {
pre("func(".
print_r(
array( $callback, $callback($this->name) ),
1
).");", __function__.'(Closure)'
);
}
// anotherFunction(array)
function anotherFunction__a($array) {
pre('anotherFunction('.print_r($array, 1).')', __function__);
$array[0]++; // change the reference value
$array['val']++; // change the reference value
}
// anotherFunction(string)
function anotherFunction__s($key) {
pre('anotherFunction(string '.$key.')', __function__);
// Get a reference
$a2 =& Overloadable::refAccess($key); // $a2 =& $GLOBALS['val'];
$a2 *= 3; // change the reference value
}
}
//----------------------------------------------------------
// Some data to work with:
$val = 10;
class obj {
private $x=10;
}
//----------------------------------------------------------
#> 5. create your object
// Start
$t = new test;
#> 6. Call your method
// Call first method with no args:
$t->func();
// Output: func(void)
$t->func($val);
// Output: func(integer 10)
$t->func("hello");
// Output: func(string hello)
$t->func("str", new obj());
/* Output:
func(string str, obj Object
(
[x:obj:private] => 10
)
)
*/
// call method with closure function
$t->func(function($n){
return strtoupper($n);
});
/* Output:
func(Array
(
[0] => Closure Object
(
[parameter] => Array
(
[$n] =>
)
)
[1] => TEST-1
)
);
*/
## Passing by Reference:
echo '<br><br>$val='.$val;
// Output: $val=10
$t->anotherFunction(array(&$val, 'val'=>&$val));
/* Output:
anotherFunction(Array
(
[0] => 10
[val] => 10
)
)
*/
echo 'Result: $val='.$val;
// Output: $val=12
$t->anotherFunction('val');
// Output: anotherFunction(string val)
echo 'Result: $val='.$val;
// Output: $val=36
// Helper function
//----------------------------------------------------------
function pre($mixed, $title=null){
$output = "<fieldset>";
$output .= $title ? "<legend><h2>$title</h2></legend>" : "";
$output .= '<pre>'. print_r($mixed, 1). '</pre>';
$output .= "</fieldset>";
echo $output;
}
//----------------------------------------------------------
In PHP 5.6 you can use the splat operator ... as the last parameter and do away with func_get_args() and func_num_args():
function example(...$args)
{
count($args); // Equivalent to func_num_args()
}
example(1, 2);
example(1, 2, 3, 4, 5, 6, 7);
You can use it to unpack arguments as well:
$args[] = 1;
$args[] = 2;
$args[] = 3;
example(...$args);
Is equivalent to:
example(1, 2, 3);
What about this:
function($arg = NULL) {
if ($arg != NULL) {
etc.
etc.
}
}
<?php
class abs
{
public function volume($arg1=null, $arg2=null, $arg3=null)
{
if($arg1 == null && $arg2 == null && $arg3 == null)
{
echo "function has no arguments. <br>";
}
else if($arg1 != null && $arg2 != null && $arg3 != null)
{
$volume=$arg1*$arg2*$arg3;
echo "volume of a cuboid ".$volume ."<br>";
}
else if($arg1 != null && $arg2 != null)
{
$area=$arg1*$arg2;
echo "area of square = " .$area ."<br>";
}
else if($arg1 != null)
{
$volume=$arg1*$arg1*$arg1;
echo "volume of a cube = ".$volume ."<br>";
}
}
}
$obj=new abs();
echo "For no arguments. <br>";
$obj->volume();
echo "For one arguments. <br>";
$obj->volume(3);
echo "For two arguments. <br>";
$obj->volume(3,4);
echo "For three arguments. <br>";
$obj->volume(3,4,5);
?>
Sadly there is no overload in PHP as it is done in C#. But i have a little trick. I declare arguments with default null values and check them in a function. That way my function can do different things depending on arguments. Below is simple example:
public function query($queryString, $class = null) //second arg. is optional
{
$query = $this->dbLink->prepare($queryString);
$query->execute();
//if there is second argument method does different thing
if (!is_null($class)) {
$query->setFetchMode(PDO::FETCH_CLASS, $class);
}
return $query->fetchAll();
}
//This loads rows in to array of class
$Result = $this->query($queryString, "SomeClass");
//This loads rows as standard arrays
$Result = $this->query($queryString);

Categories