Asked  7 Months ago    Answers:  5   Viewed   25 times
Class MyClass{
  private $data=array('action'=>'insert');
  public function insert(){
    echo 'called insert';
  }

  public function run(){
    $this->$this->data['action']();
  }
}

This doens't work:

$this->$this->data['action']();

only possibilites is to use call_user_func(); ?

 Answers

54

Try:

$this->{$this->data['action']}();

You can do it safely by checking if it is callable first:

$action = $this->data['action'];
if(is_callable(array($this, $action))){
    $this->$action();
}else{
    $this->default(); //or some kind of error message
}
Wednesday, March 31, 2021
 
Sagar
answered 7 Months ago
77

First of all, __get, __set, etc. are defined public and you cannot have them otherwise. Magic methods should be used wisely as it takes about three times as long to make a call to a magic method than simply calling a class method.

class A {
   public function __get($name) { ... }

   public function __getValue() { ... }     // <== is faster

}

Usually (normally, preferably), you will have your class members private or protected (never public) and have accessors and mutators to encapsulate them. Those accessors and mutator may be of any visibility, depending on what the user can do with the members. You may also have immutable classes by declaring only accessors for your members, which are initialized in the constructor only.

So, your sample class should read

class classWithReadOnlyVar {
   private $readOnlyVar;

   public function getReadonlyVar() {
     return $this->readOnlyVar;
   }

}

and should not use the magic methods.

There may be many reasons to avoid using magic methods at all :

  1. they break code completion
  2. they are slower at run-time
  3. they make refactoring and maintenance a bit (lot) harder/complicated
  4. you can't have a protected magic method
  5. etc.

Class members

Their visibility should be private or protected, it all depends if you want them accessible by inheritence. They should never be public as this breaks the OO paradigm.

Example of a protected member:

class A {
    protected $_name = 'A';

    public function getName() { return $this->_name; }
}

class B {
    protected $_name = 'B';   // getName() will not return 'B'
}

(without $_name being protected, this would not be possible, and no need to redefine the accessor)

Accessors

They should be protected or public. Having a private accessor makes no sense; a class should access it's member directly. If the member needs processing, the class will know regardless when to call the accessor or not.

Mutators

They should be protected or public. As for the accessors, it makes no sense to have a private mutator... unless a very rare case when processing needs to be done internally. If a class member has no accessor, it should not have a mutator. It also makes no sense to have a mean to set a value without being able to get the value back somehow.

Wednesday, March 31, 2021
 
Sanguine
answered 7 Months ago
23

You need to use call_user_func to do this:

call_user_func(array($this, $this->_auto));

Unfortunately PHP does not allow you to directly use property values as callables.

There is also a trick you could use to auto-invoke callables like this. I 'm not sure I would endorse it, but here it is. Add this implementation of __call to your class:

 public function __call($name, $args)
 {
     if (isset($this->$name) && is_callable($this->$name)) {
         return call_user_func_array($this->$name, $args);
     }
     else {
         throw new Exception("No such callable $name!");
     }
 }

This will allow you to invoke callables, so you can call free functions:

 $this->_auto = 'phpinfo';
 $this->_auto();

And class methods:

 $this->_auto = array($this, 'index');
 $this->_auto();

And of course you can customize this behavior by tweaking what __call invokes.

Wednesday, March 31, 2021
 
Asnexplore
answered 7 Months ago
70

I think the correct syntax for referencing ranges of cells in another sheet is:

List!$A$1:$A$10

So you should try:

$objValidation->setFormula1('List!$A$1:$A$10'); // tested it, worked for me

Got the idea from http://phpexcel.codeplex.com/discussions/320393:

->setFormula1("Worksheet!A1:{$endCell}1");// work....

Although this guy had another problem with using named ranges.

Background: I think with:

$objValidation->setFormula1('"$List.$A$1:$A$10"');

you're explicity using the given string between the quotation marks as the list value as explained here: here (where you probably got this snippet in the first place) or here. But since you don't want to use fixed list items but dynamically referred ones, you should omit the double quotation marks.

Saturday, May 29, 2021
 
Ula
answered 5 Months ago
Ula
25

In java it can be done through the reflection api.

Have a look at Class.getMethod(String methodName, Class... parameterTypes).

A complete example (of a non-static method with an argument) would be:

import java.lang.reflect.*;
public class Test {

    public String methodName(int i) {
        return "Hello World: " + i;
    }

    public static void main(String... args) throws Exception {
        Test t = new Test();
        Method m = Test.class.getMethod("methodName", int.class);
        String returnVal = (String) m.invoke(t, 5);
        System.out.println(returnVal);
    }
}

Which outputs:

Hello World: 5

Saturday, July 3, 2021
 
njai
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :