Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I dereference a constructor?

Tags:

php

Ideally I would like to do something like this....

$formElement->addValidator
(
    (new RegexValidator('/[a-z]/') )->setErrorMessage('Error')
    // setErrorMessage() returns $this
);

Of course PHP won't allow that, so I settle for this...

$formElement->addValidator
(
    RegexValidator::create('/[a-z]/')->setErrorMessage('Error')
);

And the code in the Base class....

static public function create( $value )
{
  return new static( $value );
}

I would like to go one step further and do something like this...

static public function create()
{
  return call_user_func_array( 'static::__construct', func_get_args() );
}

Again, PHP won't allow me to do this. I could code individual 'create' methods for each validator, but I want it to be a little more slick.

Any suggestions please?

like image 748
thomas-peter Avatar asked Dec 04 '22 07:12

thomas-peter


1 Answers

Corzin massively pointed me in the right direction, Reflection - (thanks Krzysztof).

Please note that late static binding applies, which is only a feature of PHP >= 5.3

The method of interest is Validator::create(). It provides a work-around for the lack of ability to call methods on objects which have bee created inline (see my original question).

The base class...

class Validator
{
    ....
    static public function create()
    {
        $class = new ReflectionClass( get_called_class() );
        return $class->newInstanceArgs( func_get_args() );
    }

    public function setErrorMessage( $message )
    {
    ....
}

The extended class....

class RegexValidator extends Validator
{

    public function __construct( $regex )
    {
    ....
}

A usage example...

    $form
        ->getElement('slug')
        ->setLabel( 'Slug' )
        ->addValidator( RegexValidator::create('/[a-z]/')->setErrorMessage('Error') )
        ->addValidator( RequiredValidator::create() );
like image 190
thomas-peter Avatar answered Dec 21 '22 13:12

thomas-peter