Use PHP value as function name to get dynamic function [duplicate] - php

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.

Related

Access a class within a function

Using as an example the class defined here
class Testclass {
private $testvar = "default value";
public function setTestvar($testvar) {
$this->testvar = $testvar;
}
public function getTestvar() {
return $this->testvar;
}
function dosomething()
{
echo $this->getTestvar();
}
}
$Testclass = new Testclass();
$Testclass->setTestvar("another value");
$Testclass->dosomething();
I would like to add inside a function "one more value", like this:
function test_function() {
$Testclass->setTestvar("one more value");
}
But it doesn´t work. I gives the error message undefined variable Testclass. In order to make it work, I have to define the variable as global within the function, like this:
function test_function() {
global Testclass;
$Testclass->setTestvar("one more value");
}
I am quite new to PHP, but it seems rather strange to me this way of using it. From the main PHP file it´s already defined, but when I use it from a function I have to define again.Basically what I am trying to do is to create a class that creates a new file and adds strings to it from different functions. Is there not a better way? Any suggestions? Many thanks in advance.
One way is to use singleton
MyClass::getInstance()->doSomethingUsefull();
Sometimes you can use static method
MyClass::doIt();
Functions have their own private variable scope. So (for example) you can use $i in a function without worrying about it screwing up another $i somewhere else in the program. If you want to have a function perform actions on an already-existing object, just pass the object as a parameter to the function:
function test_function(Testclass $testclass)
{
$testclass->setTestvar("one more value");
}
Then call it with your object:
$Testclass = new Testclass();
test_function($Testclass);
Note: If the functions you're defining outside the class are tightly related to the class, then you probably want to define them as methods inside the class instead of separate stand-alone functions.

Binding an anonymous function to an existing function in PHP

Is there a way to bind an existing function to an anonymous one in php? Something like
$my_func = strip_tags();
Or must I half-redefine it, as a sort of anonymous wrapper, with the proper arguments and return value?
I tried googling this, but I suppose I didn't correctly suss the proper search phrase, as I didn't find results on the first page.
Edit I'm making a sort of function pipeline(?) where I can pass data and functions, and I want to pass functions as variables. I would like to keep the syntax the same and be able to use $output = $function($data) without having to write a bunch of anonymous wrappings for native functions. Also I would like to avoid using call_user_func so I don't have to re-write my existing code.
Simple.
$my_func = 'strip_tags';
$output = $my_func($data);
You can bind the function by it's name. Have a look at the callable Interface from php
Code from the manual mentioned above
<?php
// An example callback function
function my_callback_function() {
echo 'hello world!';
}
// An example callback method
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!';
}
}
// Type 1: Simple callback
call_user_func('my_callback_function');
// Type 2: Static class method call
call_user_func(array('MyClass', 'myCallbackMethod'));
// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');
// Type 5: Relative static class method call (As of PHP 5.3.0)
class A {
public static function who() {
echo "A\n";
}
}
class B extends A {
public static function who() {
echo "B\n";
}
}
call_user_func(array('B', 'parent::who')); // A
?>

How to Pass a function to a class in php

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.
}

Call a PHP function dynamically

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.

PHP access external $var from within a class function

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

Categories