24

Currently my code looks like that:

switch ($_POST['operation']) {
    case 'create':
        $db_manager->create();
        break;
    case 'retrieve':
        $db_manager->retrieve();
        break;
...
}

What I want to do is, to check if method called $_POST['operation'] exists: if yes then call it, else echo "error" Is it possible? How can I do this?

tohuwawohu
  • 13,268
  • 4
  • 42
  • 61
heron
  • 3,611
  • 25
  • 80
  • 148

4 Answers4

45

You can use method_exists:

if (method_exists($db_manager, $_POST['operation'])){
  $db_manager->{$_POST['operation']}();
} else {
  echo 'error';
}

Though I strongly advise you don't go about programming this way...

Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • 5
    @epic_syntax: Because I could, with wget/cURL, spoof the POST variable and pry around for methods you don't necessarily want exposed. Also, you NEVER trust user input directly, you always want to sanitize it. basically, if you're using `$_POST[...]` anywhere else but the top of your file embedded in a check for safe-ness, you're doing it wrong and asking for trouble. – Brad Christie Apr 23 '12 at 20:43
  • 1
    And I almost though, you'd recomend [not to use PHP at all](http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/) :) – iblue Apr 23 '12 at 20:44
  • 1
    @epic_syntax: the easy way is to have whitelist of methods allowed to run – zerkms Apr 23 '12 at 20:45
  • 7
    @iblue: you just wanted to share that link and could find better place, didn't you? – zerkms Apr 23 '12 at 20:46
  • After programming PHP for more than 11 years, I will take every opportunity to bash it. :) – iblue Apr 23 '12 at 20:49
  • @iblue So you wanna say facebook with 910 million users making mistake by using php & c++ backend, right? – heron Apr 23 '12 at 21:50
  • Do you really judge the quality of a programming language by the number of users of a product that is partally written in that language? They had to reimplement the whole language in C++, because the original implementation is so crappy. So, yes, Facebook is making a mistake by using php. If I would write a product of this size, I would implement a new, completely event-driven programming language, with a JIT compiler, probably based on Chrome V8. Following the syntax of coffeescript. But with a less sucking definition of `this`. Or I would port rubinius to the V8. Something like this. – iblue Apr 23 '12 at 22:08
  • "But X was implemented in Y" is not an argument for or against Y. – Gabriel Jun 08 '18 at 13:30
  • 2
    @BradChristie There is any safer alternative for method_exists? Could you give a explanation about why you don't recommend using it? – Chubby Cows Jun 06 '22 at 19:25
13

You can use is_callable() or method_exists().

The difference between them is that the latter wouldn't work for the case, if __call() handles the method call.

zerkms
  • 249,484
  • 69
  • 436
  • 539
6

Use method_exists()

method_exists($obj, $method_name);
Kemal Fadillah
  • 9,760
  • 3
  • 45
  • 63
4

You can use method_exists(). But this is a really bad idea

If $_POST['operation'] is set to some magic function names (like __set()), your code will still explode. Better use an array of allowed function names.

iblue
  • 29,609
  • 19
  • 89
  • 128
  • I think, You mean something like this. $operations=array("retrieve", "create"); if (isset($_POST['operation']) && in_array($_POST['operation'], $operations)) { $db_manager->{$_POST['operation']}(); } Can I `collect` all available methods into an array automatically or only manually? – heron Apr 23 '12 at 20:41
  • Letting users call arbitrary methods in an object is generally a bad idea (and its slow as hell). Make your own list, or even better use the switch statement from your question. – iblue Apr 23 '12 at 20:42