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;
}
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".
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.
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.
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.
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
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};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With