How to exclude a variable from being required in a function?
IE:
function foo($name,$address,$pizza_preference,$date)
{
if(!$pizza_preference)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
When calling this function how would I set it up so $pizza_preference is not required, but optional? So that if you only entered 3 arguments in the function it omits $pizza_preference, or would I have to make it so when you enter 0 it just doesn't return it?
Just define a default value for it. Then you can use that function without passing a value:
function foo($name,$address,$date,$pizza_preference=null)
{
if(!$pizza_preference)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
Usually you put variables that have default values at the end of the parameters list so you don't have to include blank parameters when calling the function.
See Default argument values on the PHP website for more.
UPDATE
If you're going to have multiple parameters with default values and want to be able to skip them individually you can pass an array as the only parameter and read the values from there:
function foo(array $parameters)
{
if(!$parameters['pizza_preference'])
{
return array($parameters['name'],$parameters['address'],$parameters['date']);
}
else
{
return array($parameters['name'],$parameters['address'],$parameters['date'],$parameters['pizza_preference']);
}
}
I recommend (and I always do) to pass arguments as Object..
function foo($params)
{
if(!$params->pizza_preference)
{
return array($pizza_preference->name,$pizza_preference->address,$pizza_preference->date);
}
else
{
return array($pizza_preference->name,$pizza_preference->pizza_preference->address,$pizza_preference,$pizza_preference->date);
}
}
Sample usage:
$p1 = new stdClass;
$p1->name = 'same name';
$p1->address ='same address';
$p1->pizza_preference = '1';
$p1->date = '26-04-2012';
$p2 = new stdClass;
$p2->name = 'same name';
$p2->address ='same address';
$p2->date = '26-04-2012';
foo($p1); //will return the first array
foo($p2); //will return the second array
Well youll need to change the signature... anything not required should go last:
function foo($name, $address, $date, $pizza_preference = null) {
}
You can set default values in the function declaration:
function foo($name,$address,$date,$pizza_preference=null)
{
if($pizza_preference === null)
{
return array($name,$address,$date);
}
else
{
return array($name,$address,$pizza_preference,$date);
}
}
As an alternative approach, you can use an associative array as a single argument, and then just check it inside the function like this:
function foo($args) {
$name = (!empty($args['name']) ? $args['name'] : NULL);
$address = (!empty($args['address']) ? $args['address'] : NULL);
$pizza_preference = (!empty($args['pizza_preference']) ? $args['pizza_preference'] : NULL);
$date = (!empty($args['date']) ? $args['date'] : NULL);
}
Related
this is the code:
class university {
function hello($name){
return $this->name;
}
}
function compare1(&$obj1 , $obj2){
if ($obj1 === $obj2) {
return TRUE;
}else {
return FALSE;
}
}
}
$uni1 = new university();
$uni2 = new university();
$uni3 = $uni1;
echo compare1($uni1 , $uni3) ?"SAME" : "DIFFERENT";
I want to know why the output is SAME ,although the compare function take the first parameter by refrence and the second by value, so the identity operator must gives us FALSE.
Also if we try to make this:
$uni3 = clone $uni1;
echo compare1($uni1 , $uni3) ?"SAME" : "DIFFERENT";
the output is DIFFERENT .
knowing that both example are equal .right?
$uni3 = $uni1;
Here the value have been passed by reference, so of course when compare they are the same object.
$uni3 = clone $uni1;
Here you've made a shallow copy, so the references are different then the result will be not the same.
Is there a way in PHP to use a function which has optional parameters in its declaration where I do not have to pass an optional arguments which already have values declared and just pass the next argument(s) which have different values that are further down the parameter list.
Assuming I have a function that has 4 arguments, 2 mandatory, 2 optional. I don't want to use null values for the optional arguments. In usage, there are cases where I want to use the function and the value of the 3rd argument is the same as the default value but the value of the 4th argument is different.
I am looking for a not so verbose solution that allows me to just pass the argument that differs from the default value without considering the order in the function declaration.
createUrl($host, $path, $protocol='http', $port = 80) {
//doSomething
return $protocol.'://'.$host.':'.$port.'/'.$path;
}
I find myself repeating declaring variables so that I could use a function i.e to use $port, I redeclare $protocol with the default value outside the function scope i.e
$protocol = "http";
$port = 8080;
Is there any way to pass the 2nd optional parameter($port) without passing $protocol and it would "automatically" fill in the default value of $protocol i.e
getHttpUrl($server, $path, $port);
This is possible in some languages like Dart in the form of Named Optional parameters.See usage in this SO thread. Is their a similar solution in PHP
You could potentially use a variadic function for this.
Example:
<?php
function myFunc(...$args){
$sum = 0;
foreach ($args as $arg) {
$sum += $arg;
}
return $sum;
}
Documentation:
http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list
PHP doesn't allow at this state to call functions parameters in the order we want.Maybe in the future it will.However you can easily achieve your purpose by using an associative array as the only argument, and then define, the default parameter in the function.For the call you will need to pass an array with only the values which interest you.This array will be merged with the default array.You can even implement required parameters and call them in any order you want.
example:
function mysweetcode($argument){
$required=['first'];//specify required parameters here
$default=['first'=>0,'second'=>1,'third'=>2];//define all parameters with their default values here
$missing=[];
if(!is_array($argument)) return false;
$argument=array_intersect_key($argument,$default);
foreach($required as $k=>$v){//check for missing required parameters
if(!isset($argument[$v]))
$missing[]=$v;
}
if(!empty($missing)){// if required are missing trigger or throw error according to the PHP version
$cm=count($missing);
if (version_compare(PHP_VERSION, '7.0.0') < 0) {
trigger_error(call_user_func_array('sprintf',
array_merge(array('Required '.(($cm>1)?'parameters:':'parameter:').
str_repeat('%s,',$cm).(($cm>1)?' are':' is').' missing'),$missing)),
E_USER_ERROR);
}else{
throw new Error(call_user_func_array('sprintf',array_merge(
array('Required '.(($cm>1)?'parameters:':'parameter:').
str_repeat('%s',$cm).(($cm>1)?' are':' is').' missing'),$missing)));
}
}
$default=array_merge($default,$argument);//assign given values to parameters
extract($default);/*extract the parameters to allow further checking
and other operations in the function or method*/
unset($required,$missing,$argument,$default,$k,$v);//gain some space
//then you can use $first,$second,$third in your code
return $first+$second+$third;
}
var_dump(mysweetcode(['first'=>9,'third'=>8]));//the output is 18
var_dump(mysweetcode(['third'=>8]));//this throws Error on PHP7 and trigger fatal error on PHP5
You can check a live working code here
Well, this should work:
function myFunc($arg1, $arg2, $arg3=null, $arg4= null){
if ( is_null( $arg3 ) && is_null( $arg4 ) {
$arg3 = 3;
$arg4 = 4;
} else if ( is_null( $arg4 ) ) {
$arg4 = $arg3;
$arg3 = 3;
}
echo $arg1 + $arg2 + $arg3 + $arg4;
}
However I suggest you to rethink your problem (as a whole) because this is not a very good idea.
You could refactor this to use a parameter object; this way, you could include the default parameters in this object and set them in any order (with a trade-off of more verbose code). As an example using your above code,
<?php
class AdditionParameters
{
private $arg1 = 0;
private $arg2 = 0;
private $arg3 = 3;
private $arg4 = 4;
public function getArg1() { return $this->arg1; }
public function getArg2() { return $this->arg2; }
public function getArg3() { return $this->arg3; }
public function getArg4() { return $this->arg4; }
public function setArg1($value) { $this->arg1 = $value; return $this; }
public function setArg2($value) { $this->arg2 = $value; return $this; }
public function setArg3($value) { $this->arg3 = $value; return $this; }
public function setArg4($value) { $this->arg4 = $value; return $this; }
}
From there, you could simply call the function while passing in this new object.
function myFunc(AdditionParameters $request) {
return $request->getArg1()
+ $request->getArg2()
+ $request->getArg3()
+ $request->getArg4();
}
echo myFunc((new AdditionParameters)->setArg1(1)->setArg2(2)->setArg4(6));
// or echo myFunc((new AdditionParameters)->setArg1(1)->setArg4(6)->setArg2(2));
Otherwise, PHP doesn't allow you to have named optional parameters. (e.g. myFunc(1, 2, DEFAULT, 4);)
You have the response in your question, you can declare your function like
function myFunc($arg1, $arg2, $arg3 = null, $arg4 = null){
//here you check if the $arg3 and $arg4 are null
}
then you call your function using
myFunc($arg1, $arg2);
There is no such way in PHP(like in python for example).
You have to use some tricks in order to do that but will not always work.
For example:
// creates instances of a class with $properties.
// if $times is bigger than 1 an array of instances will be returned instead.(this is just an example function)
function getInstance($class, $properties = [], $times = 1){
//my code
}
$user = getInstance("User", ["name" => "John"]); // get one instance
$users = getInstance("User", ["name" => "John"],2); // get two instances.
If you want to use the function without passing the $parameters argument, like this:
$users = getInstance("User",2);
you can change the function to:
// creates instances of a class with $properties.
// if times is bigger than 1 an array of instances will be returned instead.
function getInstance($class, $properties = [], $times = 1){
if(is_numberic($properties)){
$times = $properties;
$properties = [];
}
//my code
}
Of course, this strategy will work only if you parameters have different types.
PS. This method is use in the Laravel Framework a lot. From there I got the inspiration.
This is modified from one of the answers and allows arguments to be added in any order using associative arrays for the optional arguments
function createUrl($host, $path, $argument = []){
$optionalArgs = [
'protocol'=>'http',
'port'=>80];
if( !is_array ($argument) ) return false;
$argument = array_intersect_key($argument,$optionalArgs);
$optionalArgs = array_merge($optionalArgs,$argument);
extract($optionalArgs);
return $protocol.'://'.$host.':'.$port.'/'.$path;
}
//No arguments with function call
echo createUrl ("www.example.com",'no-arguments');
// returns http://www.example.com:80/no-arguments
$argList=['port'=>9000];
//using port argument only
echo createUrl ("www.example.com",'one-args', $argList);
//returns http://www.example.com:9000/one-args
//Use of both parameters as arguments. Order does not matter
$argList2 = ['port'=>8080,'protocol'=>'ftp'];
echo createUrl ("www.example.com",'two-args-no-order', $argList2);
//returns ftp://www.example.com:8080/two-args-no-order
As of version 8.0, PHP now has named arguments. If you name the arguments when calling the function, you can pass them in any order and you can skip earlier default values without having to explicitly pass a value for them.
For example:
function createUrl($host, $path, $protocol = 'http', $port = 80)
{
return "$protocol://$host:$port/$path";
}
createUrl(host: 'example.com', path: 'foo/bar', port: 8080);
// returns: "http://example.com:8080/foo/bar"
function valueFromGetOrPost($parameter)
{
$shvalue=NULL;
if ($_GET[$parameter])
{
$shvalue=$_GET[$parameter];
}
else if (isset($_POST[$parameter]))
{
$shvalue=$_POST[$parameter];
}
return $shvalue;
}
say by using filter_input
Basically the code check whether a parameter exist either in GET or POST. And then return the value of the parameter.
I think this must be so common it should be there by some built in function already
Use $_REQUEST (documentation).
An associative array that by default contains the contents of $_GET, $_POST and $_COOKIE.
So your code will look like:
function valueFromGetOrPost($parameter)
{
$shvalue=NULL;
if ($_REQUEST[$parameter])
{
$shvalue=$_REQUEST[$parameter];
}
return $shvalue;
}
You could use fast return to simplify it a bit, i.e
function valueFromGetOrPost($parameter){
$shvalue=NULL;
if (isset($_GET[$parameter])){
return $_GET[$parameter];
} else if (isset($_POST[$parameter])){
return $_POST[$parameter];
}
}
Or, you could use a ternary operator, since you're returning NULL anyway if neither are set:
function valueFromGetOrPost($parameter){
$shvalue = (isset($_GET[$parameter]) ? $_GET[$parameter] : $_POST[$parameter]);
return $shvalue;
}
Here is my proposal, using the filter_input() function:
function valueFromGetOrPost($parameter)
{
$value = ($getValue = filter_input(INPUT_GET, $parameter))
? $getValue
: filter_input(INPUT_POST, $parameter);
return ($value) ? $value : NULL;
}
i need to know how to pass an array to a function as separate variables, for instance,
function myfunction($var, $othervar) {
}
$myarray = array('key'=>'val', 'data'=>'pair');
here is where I am running into problems, the following doesn't seem to work:
$return = myfunction(extract($myarray));
it should, if I understand correctly, basically be the same as
$return = myfunction($key, $data);
where $key='val' and $data='pair'
can anyone please explain this to me.
If I am understanding your question right then try this
$return = myfunction($myarray["key"],$myarray["data"]);
here we are simply passing the associative array as arguments.
public function get($key=null, $function='', array $vars=array()) {
if ($key==null || !array_key_exists($key, $this->_obj)) {
return null;
}
var_dump($vars);
if (!empty($function)) {
return $this->_obj[$key]->$function(array_walk($vars));
// return call_user_func_array(array(get_class($this->_obj[$key]), $function), $vars);
// return $this->_obj[$key]->$function(extract($vars));
}
return $this->_obj[$key];
}
public function get($key=null, $function='', array $vars=array()) {
if ($key==null || !array_key_exists($key, $this->_obj)) {
return null;
}
if (!empty($function)) {
return call_user_func_array(array($this->_obj[$key], $function), $vars);
}
return $this->_obj[$key];
}
$registry = Registry_Object::Singleton();
//...later on
$registry = $GLOBALS['registry'];
$registry->set('Content', new Content($_SERVER['REQUEST_URI']));
$id = $registry->get('Content', 'GetIdFunc');
$registry->set('DB', 'Database');
$query = $registry->get('DB', 'Read', array("SELECT TITLE, CONTENT FROM APP_CONTENT WHERE ID=$id"));
print '<h1>'.$query[0]['TITLE'].'</h1>';
print Template_Helper::TPL_Paragraphs($query[0]['CONTENT']);
thanks all
So I'd like to use the call_user_func to pass data to an optional parameter of a function.
Here's the example of a code, the optional parameter $data represents a functional called data that was declared in another file. I just want it to be called by using call_user_func that will set the parameter with the function's name and call it within the createtable function, but doesn't seem to work.
I got the example from the PHP Manual, but createTable contains many parameters. How can I make call_user_func only assign the string data to the optional parameter $data set to NULL as default?
function createTable($database, $table, $patch,$data = NULL)
{
echo "INFO: Adding '$table'in database '$database'.\n";
$sql = "SHOW TABLES FROM $database WHERE Tables_in_$database='$table';";
$result = mysql_query($sql);
$result_count = mysql_num_rows($result);
if ( $result_count != 1 ) {
echo "ERROR: Can not find table '$table' in database '$database'.\n";
$result = mysql_query($patch);
if ( false === $result ) {
echo "ERROR: Adding Table '$table' in database '$database' ... Failed\n";
return false;
}
else {
echo "INFO: Adding Table '$table'in database '$database' ... Success\n";
// using the optional parameter here
$data();
return true;
}
} else {
if ( $result_count == 1 ) {
echo "ERROR: Table '$table'already in database '$database'.\n";
return false;
}
}
}
// Now I'm passing value to the optional parameter $ data that is NULL as default.
call_user_func('createTable', "data");
Even with call_user_func you have to pass all the parameters.
Anyway, call_user_func is intended for use when the name of the function isn't necessarily known up front. For instance, you might have several functions and a variable, and the variable contains the name of the function to call.
Personally I think it's on par with eval and variable variables: A horrible idea. After all, if you have $foo = "function_name"; then you can call $foo() and it will call function_name.
Anyway, back to the point, just call it as a normal function and give it the parameters it needs. Pass null if you have to.
you must pass value like this
call_user_func('createTable', $database, $table, $patch,$data);
or this for call from class
call_user_func(array(&$objectName->{$anotherObject},$functionName), $arg1, $arg2, $arg2);
or you can use this can get arg as array
call_user_func_array("createTable", array("one", "two"));
or this for call from class can get arg as array
call_user_func_array(array($foo, "bar"), array("three", "four"));
or This can help you too it not need to pass all args
function __named($method, array $args = array())
{
$reflection = new ReflectionFunction( $method);
$pass = array();
foreach($reflection->getParameters() as $param)
{
/* #var $param ReflectionParameter */
if(isset($args[$param->getName()]))
{
$pass[] = $args[$param->getName()];
}
else
{
try{
$pass[] = $param->getDefaultValue();
}catch(Exception $e){
$pass[] = NULL;
}
}
}
return $reflection->invokeArgs( $pass);
}
I hope It Work
sample:
__named('createTable', array('data' => 'value'));
and it is for use in class
public function __named($method, array $args = array())
{
$reflection = new ReflectionMethod($this, $method);
$pass = array();
foreach($reflection->getParameters() as $param)
{
/* #var $param ReflectionParameter */
if(isset($args[$param->getName()]))
{
$pass[] = $args[$param->getName()];
}
else
{
try{
$pass[] = $param->getDefaultValue();
}catch(Exception $e){
$pass[] = NULL;
}
}
}
return $reflection->invokeArgs($this,$pass);
}
if you Don't set any value __named Put Null instead of Unset Value
It seems you just want to pass the last param, and not worry about the 1st three. I don't think call_user_func is the right tool here at all.
Why not just make a function that calls your function?
function call_createTable($data){
$database = '...';
$table = '...';
$patch = '...';
return createTable($database, $table, $patch, $data);
}
Then just simply call it like this: call_createTable("data");.