Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

phpstorm generate setter with type hint

In phpstorm, you can generate a setter method for class members by alt + insert > setters > picking the variables to make setter methods for.

But, even when phpstorm knows the type/class of the variable, it doesn't insert a type hint into the parameter list.

How to make phpstorm generate setters with type hints, but only for type hintable types?

Example class

class CodeGenerationTest {
    /* @var \DateTimeInterface */
    private $date;
    /* @var int */
    private $num;
}

The desired generated setters should be:

/**
 * @param DateTimeInterface $date
 */
public function setDate(DateTimeInterface $date)
{
    $this->date = $date;
}

/**
 * @param int $num
 */
public function setNum($num)
{
    $this->num = $num;
}

setNum is correct, but setDate gets generated missing the type hint on the parameter:

/**
 * @param DateTimeInterface $date
 */
public function setDate($date)
{
    $this->date = $date;
}
like image 959
goat Avatar asked Oct 25 '14 03:10

goat


People also ask

How to change type hint in PHP setter method in PhpStorm?

You need to change the template of your PHP Setter Method in PhpStorm to specify the type hint. Open PhpStorm's Preferences and "File and Code Templates" menu, under the "Code" tab there's an option called "PHP Setter Method".

How do I generate accessor and mutator methods in PhpStorm?

PhpStorm can generate accessor and mutator methods ( getters and setters) for the fields in your classes. Generated methods have only one argument. In the PHP context, getters and setters are generated using the PHP Getter/Setter/Fluent setter file templates.

How to generate getters and setters in PHP?

In the PHP context, getters and setters are generated using the PHP Getter/Setter/Fluent setter file templates. By default, as specified in these templates, setters are generated with the set prefix, and getters with the is or get prefix according to the inferred property type – boolean or non-boolean.

How do I create a constructor in PhpStorm?

From the main menu, select Code | Generate Alt+Insert to open the popup menu with available constructs that you can generate. PhpStorm can generate a constructor that initializes specific class properties using values of corresponding arguments. On the Code menu, click Generate Alt+Insert.


2 Answers

You need to change the template of your PHP Setter Method in PhpStorm to specify the type hint.

Open PhpStorm's Preferences and "File and Code Templates" menu, under the "Code" tab there's an option called "PHP Setter Method". Modify it to look like this:

#set($typeHintText = "$TYPE_HINT ")
## First we check against a blacklist of primitive and other common types used in documentation.
#set($nonTypeHintableTypes = ["", "string", "int", "mixed", "number", "void", "object", "real", "double", "float", "resource", "null", "bool", "boolean"])
#foreach($nonTypeHintableType in $nonTypeHintableTypes)
    #if ($nonTypeHintableType == $TYPE_HINT)
        #set($typeHintText = "")
    #end
#end
## Make sure the type hint actually looks like a legal php class name(permitting namespaces too) for future proofing reasons.
## This is important because PSR-5 is coming soon, and will allow documentation of types with syntax like SplStack<int>
#if (!$TYPE_HINT.matches('^((\\)?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+)+$'))
    #set($typeHintText = "")
#end
## Next, we check if this is using the array syntax like "MyClass[]", and type hint it as a plain array
#if ($TYPE_HINT.endsWith("[]"))
    #set($typeHintText = "array ")
#end

/**
 * @param ${TYPE_HINT} $${PARAM_NAME}
 */
public ${STATIC} function set${NAME}($typeHintText$${PARAM_NAME})
{
#if (${STATIC} == "static")
    self::$${FIELD_NAME} = $${PARAM_NAME};
#else
    $this->${FIELD_NAME} = $${PARAM_NAME};
#end
}

Actually, since the php primitive list is actually short, it's possible to detect if it's a primitive type or not.

So:

    class CodeGenerationTest {

        /**
         * @var DateTimeInterface
         */
        private $date;

        /**
         * @var int
         */
        private $num;
    } 

Would actually generates this:

     /**
     * @var \DateTimeInterface $date
     */
    public function setDate(\DateTimeInterface $date)
    {
        $this->date = $date;
    }

    /**
     * @var int $num
     */
    public function setNum($num)
    {
        $this->num = $num;
    }

You can find help about templates variables here: https://www.jetbrains.com/phpstorm/webhelp/file-template-variables.html

like image 63
Pier-Alexandre Bouchard Avatar answered Sep 20 '22 07:09

Pier-Alexandre Bouchard


I found @Pier's solution so useful that I updated his template to generate setters with both type hinting AND optional type casting. Hope this helps someone else.

Given:

class CodeGenerationTest
{
    /**
     * @var \DateTime
     */
    private $date;

    /**
     * @var int
     */
    private $id;

    /**
     * @var string|null
     */
    private $notes;
}

Will generate:

/**
 * @param \DateTime $date
 */
public function setDate(\DateTime $date)
{
    $this->date = $date;
}

/**
 * @param int $id
 */
public function setId($id)
{
    $this->id = (int)$id;
}

/**
 * @param null|string $notes
 */
public function setNotes($notes)
{
    $this->notes = is_null($notes) ? null : (string)$notes;
}

Here's the code template to copy/paste into PHPStorm under: Settings > Editor > File and Code Templates > Code > PHP Setter Method

#set($typeHintText = "$TYPE_HINT ")
## First we check against a blacklist of primitive and other common types used in documentation.
#set($nonTypeHintableTypes = ["", "string", "int", "integer", "mixed", "number", "void", "object", "real", "double", "float", "resource", "null", "bool", "boolean"])
#foreach($nonTypeHintableType in $nonTypeHintableTypes)
    #if ($nonTypeHintableType == $TYPE_HINT)
        #set($typeHintText = "")
    #end
#end
## Make sure the type hint actually looks like a legal php class name(permitting namespaces too) for future proofing reasons.
## This is important because PSR-5 is coming soon, and will allow documentation of types with syntax like SplStack<int>
#if (!$TYPE_HINT.matches('^((\\)?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+)+$'))
    #set($typeHintText = "")
#end
## Next, we check if this is using the array syntax like "MyClass[]", and type hint it as a plain array
#if ($TYPE_HINT.endsWith("[]"))
    #set($typeHintText = "array ")
#end

## Set this or self
#set($thisOrSelf = "$this->")
#if (${STATIC} == "static")
    #set($thisOrSelf = "self::$")
#end

## Type cast incoming variable that can also be null, using the ternary operator
#set($ternaryCast = "")
#if ($TYPE_HINT.contains('null|') || $TYPE_HINT.contains('|null'))
    #set($ternaryCast = "is_null($${PARAM_NAME}) ? null : ")
#end

## Type cast incoming variable
#set($cast = " ")
#if ($TYPE_HINT.contains('string')) 
    #set($cast = "(string) ")
#elseif ($TYPE_HINT.contains('object')) 
    #set($cast = "(object) ")
#elseif ($TYPE_HINT.contains('int')) 
    #set($cast = "(int) ")
#elseif ($TYPE_HINT.contains('bool')) 
    #set($cast = "(bool) ")
#elseif ($TYPE_HINT.contains('float') || $TYPE_HINT.contains('double') || $TYPE_HINT.contains('real')) 
    #set($cast = "(float) ")
#end

/**
 * @param ${TYPE_HINT} $${PARAM_NAME}
 */
public ${STATIC} function set${NAME}($typeHintText$${PARAM_NAME})
{
    $thisOrSelf${FIELD_NAME} = $ternaryCast$cast$${PARAM_NAME};
}
like image 43
PancakeTornado Avatar answered Sep 18 '22 07:09

PancakeTornado