This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Use a variable to define a PHP function
Use Variable as Function Name in PHP
I want to perform a conditional function call but I don't necessarily know what what the function will be, so that would be a long switch.
For example;
$userSelection = "calculator"; /* or "stocks" or whatever widget */
$widget->get_widget($userSelection);
public function __construct($userSelection){
/* pseudo code */
call function $userSelection();
}
public function calculator(){
/* Get Calculator */
}
Sure there is. This feature is called variable functions:
$functionName = "strlen";
$length = $$functionName("Hello world!");
The $$var(...) syntax is convenient, but it will only work with free functions. If you want to call a class method this way, you will need to use call_user_func or call_user_func_array (these functions can also handle the "free function" case).
Look at the call-user-func function. This allows you to call another function, e.g.
call_user_func('calculator')
call_user_func($userSelection);
http://php.net/manual/en/function.call-user-func.php
Take a look at this php functions:
call_user_func(): http://php.net/manual/de/function.call-user-func.php
call_user_func_array(): http://www.php.net/manual/de/function.call-user-func-array.php
create_function(): http://www.php.net/manual/de/function.create-function.php
There is also a direct (though ugly) execution syntax:
function some_func(args) {...}
$function_name='some_func';
$$function_name(args2);
You can use call_user_func() for that, like this:
$userSelection = "calculator";
call_user_func($userSelection[, $param1, $param2, ...]);
call_user_func_array($userSelection, $params);
If it's just a function you're after then using this should solve your problems
$function = "echo";
$$function "fooBar";
If it's a class method that you want to keep flexible use magic method __call() which will allow you to use method names that are not pre-defined.
__call() is triggered when invoking inaccessible methods in an object context.
i.e.
class Foo {
public function __call($name, $arguments) {
echo $name;
}
}
$foo = new Foo();
$foo->bar(); // will echo "bar"
PHP built-in function 'eval' can do everything, but beware of injection.
$var = "somefunction";
eval("$var();");
http://php.net/manual/en/function.eval.php
It's pretty simple if that's what you mean.
function calculator() {
echo 'foo';
}
$userSelection = "calculator";
if (function_exists($userSelection)) {
$userSelection();
}
Or within a class like in your example:
class widget {
public function __construct($userSelection) {
echo 'constructed widget<br>';
if (function_exists($userSelection)) {
$this->$userSelection();
}
}
public function calculator() {
echo 'bar';
}
}
$userSelection = "calculator";
$widget = new widget($userSelection);
Or from outside a class when the function is part of the class.
class widget {
public function calculator() {
echo 'bar';
}
}
$widget = new widget();
$userSelection = "calculator";
$widget->$userSelection();
I would work with if/else statements though to determine the function to be called just to be sure that only valid functions are executed (do you sanitize the user selection or do you just get it from a $_POST? The latter would be a very bad idea).
You can do following :
$var = 'abc';
switch ($var) {
case 'abc':
$result = $var('test param');
echo $result;
break;
default :
echo 'default';
break;
}
function abc($data) {
return $data;
}
Related
Is there a way to call a function through variables?
For instance, I want to call the function Login(). Can I do this:
$varFunction = "Login"; //to call the function
Can I use $varFunction?
Yes, you can:
$varFunction();
Or:
call_user_func($varFunction);
Ensure that you validate $varFunction for malicious input.
For your modules, consider something like this (depending on your actual needs):
abstract class ModuleBase {
public function main() {
echo 'main on base';
}
}
class ModuleA extends ModuleBase {
public function main() {
parent::main();
echo 'a';
}
}
class ModuleB extends ModuleBase {
public function main() {
parent::main();
echo 'b';
}
}
function runModuleMain(ModuleBase $module) {
$module->main();
}
And then call runModuleMain() with the correct module instance.
You can use...
$varFunction = "Login";
$varFunction();
...and it goes without saying to make sure that the variable is trusted.
<?php
$fxname = 'helloWorld';
function helloWorld(){
echo "What a beautiful world!";
}
$fxname(); //echos What a beautiful world!
?>
I successfully call the function as follows:
$methodName = 'Login';
$classInstance = new ClassName();
$classInstance->$methodName($arg1, $arg2, $arg3);
It works with PHP 5.3.0+
I'm also working in Laravel.
If it's in the same class:
$funcName = 'Login';
// Without arguments:
$this->$funcName();
// With arguments:
$this->$funcName($arg1, $arg2);
// Also acceptable:
$this->{$funcName}($arg1, $arg2)
If it's in a different class:
$someClass = new SomeClass(); // create new if it doesn't already exist in a variable
$someClass->$funcName($arg1, $arg2);
// Also acceptable:
$someClass->{$funcName}($arg1, $arg2)
Tip:
If the function name is dynamic as well:
$step = 2;
$this->{'handleStep' . $step}($arg1, $arg2);
// or
$someClass->{'handleStep' . $step}($arg1, $arg2);
This will call handleStep1(), handleStep2(), etc. depending on the value of $step.
You really should consider using classes for modules, as this would allow you to both have consistent code structure and keep method names identical for several modules. This will also give you the flexibility in inheriting or changing the code for every module.
On the topic, other than calling methods as stated above (that is, using variables as function names, or call_user_func_* functions family), starting with PHP 5.3 you can use closures that are dynamic anonymous functions, which could provide you with an alternative way to do what you want.
I have a class that generates data based on a few things. I would like to format that data from the outside. So I am trying to pass a function into the class so that it would format that data. I have looked at many examples, but it seems this is unique.
Can anybody give an idea of how to do this? The following code gives an error.
<?php
class someClass {
var $outsideFunc; // placeholder for function to be defined from outside
var $somevar='Me'; // generated text
function echoarg($abc){
$outsideFunc=$this->outsideFunc; // bring the outside function in
call_user_func($outsideFunc,$abc); // execute outside function on text
echo $abc;
}
}
function outsidefunc($param){ // define custom function
$param='I am '.$param;
}
$someClass=new someClass();
$someClass -> outsideFunc = 'outsideFunc'; // send custom function into Class
$someClass -> echoarg($someClass->somevar);
$someClass -> outsidefunc = 'outsidefunc';
In PHP, function names are not case sensitive, yet object property names are. You need $someClass->outsideFunc, not $someClass->outsidefunc.
Note that good OOP design practice calls for the use of getter and setter methods rather than just accessing properties directly from outside code. Also note that PHP 5.3 introduced support for anonymous functions.
Yeah. You are right. Now there is no error. But it does not work either.
By default, PHP does not pass arguments by reference; outsidefunc() does not actually do anything useful. If you want it to set $param in the caller to something else, and do not want to just return the new value, you could change the function signature to look like this:
function outsidefunc(&$param) {
You would also need to change the way you call the function, as call_user_func() does not allow you to pass arguments by reference. Either of these ways should work:
$outsideFunc($abc);
call_user_func_array($outsideFunc, array(&$abc));
Why not pass your function as an argument?
<?php
class someClass {
public $somevar="Me";
public function echoarg($abc,$cb=null) {
if( $cb) $cb($abc);
echo $abc;
}
}
$someClass = new someClass();
$someClass->echoarg($someClass->somevar,function(&$a) {$a = "I am ".$a;});
i am not sure what exactly you are looking for, but what i get is, you want to pass object in a function which can be acheive by
Type Hinting in PHP.
class MyClass {
public $var = 'Hello World';
}
function myFunction(MyClass $foo) {
echo $foo->var;
}
$myclass = new MyClass;
myFunction($myclass);
OP, perhaps closures are what you're looking for?
It doesn't do EXACTLY what you're looking for (actually add function to class), but can be added to a class variable and executed like any normal anonymous function.
$myClass->addFunc(function($arg) { return 'test: ' . $arg });
$myClass->execFunc(0);
class myClass {
protected $funcs;
public function addFunc(closure $func) {
$this->funcs[] = $func;
}
public function execFunc($index) { $this->funcs[$index](); } // obviously, do some checking here first.
}
Is it possible to add methods to functions?
For example:
<?
function func(){
;
}
//add method
func->test = function(){
;
}
func->test();
func();
I'm coming from a javascript background, and therefore I'm used to 'everything is an object'.
EDIT:
I was just explaining where the misconception may often come from for new phpers. I understand the above code doesn't work.
EDIT 2
Figured it out.
class myfunc_class{
function __invoke(){
//function body
}
function __call($closure, $args)
{
call_user_func_array($this->$closure, $args);
}
}
$func = new myfunc_class;
$func->test = function(){
echo '<br>test<br>';
};
$func->test();
$func();
Even sexier :)
class func{
public $_function;
function __invoke(){
return call_user_func_array($this->_function,func_get_args());
}
function __construct($fun){
$this->_function = $fun;
}
function __call($closure, $args)
{
call_user_func_array($this->$closure, $args);
}
}
$func = new func(function($value){
echo $value;
});
$func->method = function(){
echo '<br>test<br>';
};
$func('someValue');
$func->method();
No.
Not everything is an object in PHP. In fact the only thing that is an object is, well, an object. More specifically, and generally, an instantiation of a class.
Your code converted to PHP
// function_object.php
<?php
class FunctionObject {
public method func() {
// do stuff
}
}
?>
In other code you would use it like this:
<?php
// example.php in same folder as function_object.php
include 'function_object.php';
$FuncObj = new FunctionObject;
$FuncObj->func();
Also: read more about PHP & OOP
No, because an object is a different PHP language construct than a function. Functions do not have properties, but are instead simply execution instructions.
But, if func were instead a pre-defined class, then yes... with a bit of witchcraft, ignoring public outcry, foregoing readability and PHP coding standards, and by using closures with the __call() magic method...
class func
{
function __call($func, $args)
{
return call_user_func_array($this->$func, $args);
}
}
$obj = new func;
$obj->test = function($param1, $param2)
{
return $param1 + $param2;
};
echo $obj->test(1,1);
This won't work as you'd think without __call(), because by $obj->test(1,1), PHP thinks you're trying to call a non-existent method of func when out of object scope. But inside, being that the new "test" property is of a type: closure, the call_user_func_array() just sees the "test" property as just another function, so you can hide this bit of trickery from outside scope.
You would need your function func() to return an object, then you'd be able to do something like: func()->test();
But please note that your way of handling objects is not right in PHP and I suggest that you go read the OO documentations here.
In difference to javacript, in PHP not everything is an object. Therefore you need to differ between function and class.
If you want to create an object, you need to define the class first.
class myClass {
}
You can then add as many functions to the class as you need. But you need to define them first:
class myClass {
function test() {
echo "test!\n";
}
}
When everything is ready, you can bring it to life then:
$class = new myClass;
$class->test();
Checkout the manual for more.
You can't do what you're trying to do, but you can define functions inside of other functions.
This example outputs text:
function a() {
function b() { echo 'Hi'; }
}
a();
b();
Output: HiHi
This example outputs an error:
function a() {
function b() { echo 'Hi'; }
}
b();
Output: ERROR
Is there a way to call a function through variables?
For instance, I want to call the function Login(). Can I do this:
$varFunction = "Login"; //to call the function
Can I use $varFunction?
Yes, you can:
$varFunction();
Or:
call_user_func($varFunction);
Ensure that you validate $varFunction for malicious input.
For your modules, consider something like this (depending on your actual needs):
abstract class ModuleBase {
public function main() {
echo 'main on base';
}
}
class ModuleA extends ModuleBase {
public function main() {
parent::main();
echo 'a';
}
}
class ModuleB extends ModuleBase {
public function main() {
parent::main();
echo 'b';
}
}
function runModuleMain(ModuleBase $module) {
$module->main();
}
And then call runModuleMain() with the correct module instance.
You can use...
$varFunction = "Login";
$varFunction();
...and it goes without saying to make sure that the variable is trusted.
<?php
$fxname = 'helloWorld';
function helloWorld(){
echo "What a beautiful world!";
}
$fxname(); //echos What a beautiful world!
?>
I successfully call the function as follows:
$methodName = 'Login';
$classInstance = new ClassName();
$classInstance->$methodName($arg1, $arg2, $arg3);
It works with PHP 5.3.0+
I'm also working in Laravel.
If it's in the same class:
$funcName = 'Login';
// Without arguments:
$this->$funcName();
// With arguments:
$this->$funcName($arg1, $arg2);
// Also acceptable:
$this->{$funcName}($arg1, $arg2)
If it's in a different class:
$someClass = new SomeClass(); // create new if it doesn't already exist in a variable
$someClass->$funcName($arg1, $arg2);
// Also acceptable:
$someClass->{$funcName}($arg1, $arg2)
Tip:
If the function name is dynamic as well:
$step = 2;
$this->{'handleStep' . $step}($arg1, $arg2);
// or
$someClass->{'handleStep' . $step}($arg1, $arg2);
This will call handleStep1(), handleStep2(), etc. depending on the value of $step.
You really should consider using classes for modules, as this would allow you to both have consistent code structure and keep method names identical for several modules. This will also give you the flexibility in inheriting or changing the code for every module.
On the topic, other than calling methods as stated above (that is, using variables as function names, or call_user_func_* functions family), starting with PHP 5.3 you can use closures that are dynamic anonymous functions, which could provide you with an alternative way to do what you want.
In PHP, how do you use an external $var for use within a function in a class? For example, say $some_external_var sets to true and you have something like
class myclass {
bla ....
bla ....
function myfunction() {
if (isset($some_external_var)) do something ...
}
}
$some_external_var =true;
$obj = new myclass();
$obj->myfunction();
Thanks
You'll need to use the global keyword inside your function, to make your external variable visible to that function.
For instance :
$my_var_2 = 'glop';
function test_2()
{
global $my_var_2;
var_dump($my_var_2); // string 'glop' (length=4)
}
test_2();
You could also use the $GLOBALS array, which is always visible, even inside functions.
But it is generally not considered a good practice to use global variables: your classes should not depend on some kind of external stuff that might or might not be there !
A better way would be to pass the variables you need as parameters, either to the methods themselves, or to the constructor of the class...
Global $some_external_var;
function myfunction() {
Global $some_external_var;
if (!empty($some_external_var)) do something ...
}
}
But because Global automatically sets it, check if it isn't empty.
that's bad software design. In order for a class to function, it needs to be provided with data. So, pass that external var into your class, otherwise you're creating unnecessary dependencies.
Why don't you just pass this variable during __construct() and make what the object does during construction conditional on the truth value of that variable?
Use Setters and Getters or maybe a centralized config like:
function config()
{
static $data;
if(!isset($data))
{
$data = new stdClass();
}
return $data;
}
class myClass
{
public function myFunction()
{
echo "config()->myConfigVar: " . config()->myConfigVar;
}
}
and the use it:
config()->myConfigVar = "Hello world";
$myClass = new myClass();
$myClass->myFunction();
http://www.evanbot.com/article/universally-accessible-data-php/24