Is it possible to define a class within an array in earlier versions of PHP 7?

4

Is it possible? If yes, how? In PHP 7 it is possible to create anonymous classes, which have the possibility of being defined in any variable / property, but I do not know if it is possible to do this in previous versions, because I am not very active ... in PHP.

I want to do something like this:

$arr = array("class" => new class() {});

Then I could build my class this way:

new $arr->class(/* ... */);

P.S: I was thinking of doing this because I'm converting the code of a library, but I did not have to do that necessarily. The situation: the code is written in JavaScript and makes use of classes, eg:

/**
 * Representa uma tabela em Lua.
 * @param {Object} obj Valores iniciais para montar na nova tabela.
 */
shine.Table = function(obj) {/* ... */};

That would be built like this:

new shine.Table;

The problem of converting this code to PHP is because I do not find it possible to implement a class inside an array (or object). The intention is to run Lua in PHP, then adopt Lua in a project, which can be programmed by someone and run to the side of the server.

    
asked by anonymous 05.08.2016 / 02:47

2 answers

7

There may be confusions of terms there. If you are talking about PHP versions prior to PHP 7 (currently PHP 5.6 down), there is no Anonymous Class resource.

In fact, do not confuse "class instance" with "class declaration / definition".

Definition or Statement is the act of writing the class to you. The class instance deals with the object, using the class with the new operator.

If the question is that it is possible to save instances of classes (better known as "object") within a array , yes, it is possible.

PHP 5 example:

class User {
      public $name = 'Wallace';
}

$arr = [];

$arr['user'] = new User;

// OU

$arr = ['user' => new User];

echo $arr['user']->name; // Obtendo o valor

As mentioned earlier, in versions prior to PHP 7, there are no anonymous classes, so you can not use this feature before PHP 7. But in relation to class instances, you can save your values to an index of one array quietly, since you can declare it.

Update

After updating the question, I realized that the Author wanted to make a kind of container / repostory with class names.

You can do this in PHP because of the dynamic way the language treats the data.

Referencing classes by their name, using a string :

In php it is possible to instantiate a class only by knowing its name. If you have a string, for example, with the name of the class, you can instantiate it.

class TaskClass {
       public function run() {}
}

$repository = [
   'task' => 'TaskClass',
];


$task = new $repository['task'];

$task->run();

Scope resolution operator combined with ::class

In PHP, in versions prior to 5.5, you can use ::class to resolve the name of a class.

See:

 use App\Project\Task;

 $repository = [

     'task' => \App\Project\Task::class, // nome completo,

     'another_task' => Task::class,
 ];


 $task = new $repository['task'];

 $task2 = new $repository['task'];

 get_class($task); // App\Project\Task(object)

 get_class($task2); // App\Project\Task(object) # esse é o nome real

In some cases, if you need to, you can use the pattern described in this question:

What are the ServiceProvider and ServiceContainer design patterns used in Laravel and Symfony?

Where you use Closures (anonymous functions) to tie the instantiation logic of the class. Of course, in this case, it is something more complex, but it could be exemplified as follows:

 $repository = [

     'task' => function ($parametro) {
           return new Task($parametro);
      }
 ];


 $task = $repository['task'](); // chama como se faz com as funções
    
05.08.2016 / 13:45
6

In the code you posted you are instantiating an anonymous class .

Anonymous classes were introduced in PHP7.

Regardless of using array, it will not work in lower versions.

Below are two options, one from the other:

Using stdClass

The final goal is unclear, so it may be useful to know that you can instantiate a stdClass

$arr = array("class" => (object)array('foo') = 'bar');

print_r($arr);
// ou
echo $arr['class']->foo;

Class name from a variable

class Foo
{

}

$clss = 'Foo';
$foo = new $clss();

Obviously in this case the class must already exist before being invoked.

    
05.08.2016 / 15:08