Home > OS >  PHP passing arguments into class's constructor dynamically
PHP passing arguments into class's constructor dynamically

Time:04-06

I've written a PHP class in my project's framework that contains a constructor, and for the purposes of this class it contains a single argument called name.

My class is loaded dynamically as part of the feature I'm building and I need to load a value into my argument from an array, but when I do this it just comes through as Array even when I use array_values, e.g, here's my class:

<?php

class GreetingJob
{

    /**
     * The name
     */
    public $name;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * Write data to a file
     */
    public function writeToFile($data = '')
    {
        $file = fopen('000.txt', 'w');
        fwrite($file, $data);
        fclose($file);
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try {
            $this->writeToFile('Hello ' . $this->name);
        } catch (Exception $e) {
            // do something
        }
    }
}

And where it's loaded:

/**
* Get the job
*/
public function getJob($job = '') {
    return APP . "modules/QueueManagerModule/Jobs/$job.php";
}

/**
* Check that the job exists
*/
public function jobExists($job = '') {
    if (!file_exists($this->getJob($job))) {
        return false;
    }

    return true;
}

/**
* Execute the loaded job
*/
public function executeJob($class, $rawJob = [], $args = []) {
    require_once $this->getJob($class);

    $waitTimeStart = strtotime($rawJob['QueueManagerJob']['available_at']) / 1000;
    $runtimeStart = microtime(true);

    // initiate the job class and invoke the handle
    // method which runs the job
    $job = new $class(array_values(unserialize($args)));
    $job->handle();
}

$args would look like this:

[
  'name' => 'john'
]

How can I dynamically pass args through to my class in the order that they appear and use the values from each.

CodePudding user response:

array_values() still returns an array. All it does it resetting keys to be consecutive zero-based integers.

I think you want to use the splat operator:

$job = new $class(...array_values(unserialize($args)));

Full runnable example:

<?php

class GreetingJob
{
    public function __construct($name)
    {
        var_dump($name);
    }
}

$class = 'GreetingJob';
$args = serialize(
    [
        'name' => 'Jimmy',
    ]
);
$job = new $class(...array_values(unserialize($args)));

Beware that the overall design can be confusing. Accepting arguments in an associative array suggests names matter and position doesn't, but it's the other way round.

CodePudding user response:

this is the way to instantiate a class dynamically using Reflection in php:

$className = 'GreetingJob';
$args = [];
$ref = new \ReflectionClass($className);
$obj = $ref->newInstanceArgs($args);

https://www.php.net/manual/en/reflectionclass.newinstanceargs.php

  • Related