0

I want to make object and execute code getting from database table . Suppose in my database table I have code like

class testClass {
    function testFunctionOne() {
        .......
    }
} 

Now I am trying to make object of that class to execute this code by fetching value from that table . So that I can use that object for further use. I also tried with call_user_func() . But it's nit working. Thanks in advance

azibom
  • 1,769
  • 1
  • 7
  • 21
Mithun
  • 255
  • 1
  • 7
  • 17

2 Answers2

2

The function you are looking for is eval. But beware!

  • It is often joked that "eval is evil", because it's very dangerous to run code supplied by a user. Think very carefully what you actually need to store in the database, and whether it can be something other than plain PHP code.
  • You can only have one class with a given name, so declaring a whole class each time will have extra problems. Again, think about what you actually need to store, and adjust the design to be more resilient.
Martijn
  • 15,791
  • 4
  • 36
  • 68
IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • Thanks a lot. Can you tell me how can I make object of above class which I stored in db ? Like **new testClass()** Thats my expectation – Mithun Feb 16 '21 at 08:10
  • @Mithun Yes, if you do store actual PHP code and use `eval`, it's just the same as if you'd defined that class anywhere else, so you can run `new testClass()` normally. Of course, you need to know the name of the class, but that comes back to the point of deciding what you're actually trying to store in this database. – IMSoP Feb 16 '21 at 09:09
0

Do not use eval! The eval function can have unwanted side effects on your code and is often a security vulnerability.

For this purpose you can use PHPs own serialization. Have a look at the following example.

<?php
declare(strict_types=1);
namespace Marcel;

class MyTest
{
    protected string $something;

    public function __construct(string $something)
    {
        $this->something = $something;
    }

    public function getSomething(): string
    {
        return $this->something;
    }
}

$object = new MyTest('Marcel');

// the $serialized var contains a string representing the initialized class
// the string can be stored in the database
$serialized = serialize($object);
var_dump($serialized);

// when you query from database, just unserialized the queried string
$unserialized = unserialize($serialized);
var_dump($unserialized->getSomething());

As you said in the comments, you don 't know the classname. Well, I better don 't ask, what the hell you 're trying to do. Anyway ... here 's a short example using eval().

<?php
declare(strict_types=1);
namespace Marcel;

use ParseError;

$string = 'class MyTest
{
    protected string $something;

    public function __construct(string $something)
    {
        $this->something = $something;
    }

    public function getSomething(): string
    {
         return $this->something;
    }
}';

try {
    $before = get_declared_classes();

    ob_start();
    eval($string);
    $class = ob_get_contents();
    ob_end_clean();

    $classname = current(array_diff(get_declared_classes(), $before));
    $object = new $classname('Marcel');
    var_dump($object->getSomething());
} catch (ParseError $error) {
    var_dump($error);
}

This example compares the declared classes before and after eval execution. The name of the class comes from the difference between the two arrays. With the computed name you can initialize the class.

Beware! This example does not cover all possibilities. There are some more things to note.

  • What about constructor parameters?
  • How do you know which methods the class contains?
  • You 're running into problems, if there are more than one class definition in the eval'd code.
  • What about error handling?
  • You will run into serious problems when it comes to dealing with namespaces

Most of the questions you can solve with the PHP Reflection API.

Again: Your plan is highly risky and you should not do this in a real world application.

Marcel
  • 4,854
  • 1
  • 14
  • 24
  • Thanks a lot. **I don't know the class name. Its from db.** Can you tell me how can I make object of above class which I stored in db ? Like new testClass() Thats my expectation – Mithun Feb 16 '21 at 08:18
  • Even though I may be repeating myself: This is bad practice! You should not run code this way because it can be potentially dangerous. Why you don 't know the class name. What is the source? Where does the code come from? – Marcel Feb 16 '21 at 08:31
  • While not as dangerous as `eval`, `unserialize` is **also** not suitable for use with untrusted data, because a serialized string can construct objects that have immediate side-effects. See the Warning at the top of [the manual page](https://www.php.net/unserialize). – IMSoP Feb 16 '21 at 09:07
  • Absolutely. The whole issue is potentially unsafe. Even with eval it is not possible to execute unknown classes without running in an `class MyTest not found` fatal error. Even if you try to initialise them as anonymous classes. – Marcel Feb 16 '21 at 09:25
  • @Mithun I edited my answer with an example how to retrieve the classname with an `eval()` example. – Marcel Feb 16 '21 at 09:44