PhpStorm在快速创建setter和getter时有一个很有用的功能:
Code -> generate -> select the items to generate
这非常适合设置基本的setter / getter。
然而,我不时想要设置的不仅仅是设置者和吸气剂。例如,我可能想要为一对多或多对多关系创建setter和getter。
即。
多对多
/**
* {@inheritDoc}
*/
public function getOwner()
{
return $this->owner->toArray();
}
/**
* Set the list of user
* @param Collection $owner
*/
public function setOwner( Collection $owner )
{
$this->registeredUsers->clear();
foreach ( $owner as $item ) {
$this->owner[] = $item;
}
}
/**
* Add merchant to the collection
* @param Collection $owner
*/
public function addOwner( Collection $owner )
{
foreach( $owner as $item ) {
$this->owner->add( $item );
}
}
/**
* @param Collection $owner
*/
public function removeOwner( Collection $owner )
{
foreach( $owner as $item ) {
$this->owner->removeElement( $item );
}
}
有没有办法通过相同的代码生成过程来做到这一点?
答案 0 :(得分:2)
不幸的是,ATM PhpStorm不支持此类功能。
https://youtrack.jetbrains.com/issue/WI-25003 - 观看此门票(明星/投票/评论)以获得有关任何进展的通知(到目前为止,未计划任何特定的未来版本 - 可能是因为票数非常低 - 排序of:no votes = no interest =不需要立即投入资源)。
相关:https://youtrack.jetbrains.com/issue/WI-19891
我现在能想到的唯一选择(将使用代码生成功能)..是修改Getter / Setter的模板,以便它包含多个方法(example)。这样您就可以一次性生成setXXX
/ addXXX
以及getXXX
/ removeXXX
方法。
显然,它会在所有情况下都适用,所以如果你只需要get/set
,那么你需要手动删除add/remove
方法 - 这就是这种方法的缺点。
请注意文件&代码模板可以是IDE范围(Default
模式)或项目特定的(Project
模式)..因此您可以仅在某些项目中使用此类组合的getter / setter。
https://www.jetbrains.com/help/phpstorm/2016.1/file-and-code-templates-2.html
唯一的另一种选择是半手动并要求您使用Live Templates。
使用您的addXXX
/ removeXXX
代码示例,可能最终只填充1或2个模板变量(只是对我看到的内容进行快速估算;相同的变量可以多次使用,因此可以在几个地方同时填充;输入的文本可以转换(有限的转换集),因此可以自动在另一个变量中重复使用(例如,您正在键入owner
和在另一个地方,它会自动用作Owner
。
答案 1 :(得分:0)
检查出来:
#set ($array = $TYPE_HINT.split('\|'));
#set ($IS_COLLECTION = false);
#set ($FIXED_RETURN_TYPE = $RETURN_TYPE);
#set ($NAME_LENGTH = $FIELD_NAME.length());
#set ($NAME_BEFORE_LAST = $FIELD_NAME.length() - 1);
#set ($LAST_CHARACTER = $FIELD_NAME.substring($NAME_BEFORE_LAST, $NAME_LENGTH));
#set ($METHOD_NAME_BEFORE_LAST = $NAME.length() - 1);
#if (${LAST_CHARACTER} == 's')
#set ($FIXED_PROPERTY_NAME = $FIELD_NAME.substring(0, $NAME_BEFORE_LAST));
#set ($FIXED_METHOD_NAMING_PART = $NAME.substring(0, $METHOD_NAME_BEFORE_LAST));
#else
#set ($FIXED_PROPERTY_NAME = $FIELD_NAME);
#set ($FIXED_METHOD_NAMING_PART = $NAME);
#end
#foreach($hint in $array)
#if ($hint.toString().contains('[]'))
#set ($ENTRY_HINT = $hint.toString().replace('[]', ''));
#set ($HAS_ENTRY_HINT = true);
#end
#end
#foreach($hint in $array)
#if ($hint == 'Collection')
#set ($IS_COLLECTION = true)
#set ($FIXED_RETURN_TYPE = 'Collection')
#break
#elseif ($hint == 'ArrayCollection')
#set ($IS_COLLECTION = true)
#set ($FIXED_RETURN_TYPE = 'Collection')
#break
#elseif ($hint == 'array')
#set ($IS_COLLECTION = true)
#set ($FIXED_RETURN_TYPE = 'array')
#elseif ($hint.toString().contains('[]'))
#set ($IS_COLLECTION = true)
#set ($FIXED_RETURN_TYPE = 'array')
#end
#end
#if ($IS_COLLECTION)
/**
* @param ${ENTRY_HINT} $${FIXED_PROPERTY_NAME}
*
* @return ${CLASS_NAME}
*/
public function add${FIXED_METHOD_NAMING_PART}(#if (${HAS_ENTRY_HINT})${ENTRY_HINT} #else#end$${FIXED_PROPERTY_NAME})#if(${RETURN_TYPE}): ${CLASS_NAME}#else#end
{
#if ($FIXED_RETURN_TYPE == 'Collection')
if(false === $this->${FIELD_NAME}->contains($${FIXED_PROPERTY_NAME})) {
$this->${FIELD_NAME}->add($${FIXED_PROPERTY_NAME});
}
#else
if(false === in_array($${FIXED_PROPERTY_NAME}, $this->${FIELD_NAME}, true)) {
$this->${FIELD_NAME}[] = $${FIXED_PROPERTY_NAME};
}
#end
return $this;
}
/**
* @param ${ENTRY_HINT} $${FIXED_PROPERTY_NAME}
*
* @return ${CLASS_NAME}
*/
public function remove${FIXED_METHOD_NAMING_PART}(#if (${HAS_ENTRY_HINT})${ENTRY_HINT} #else#end$${FIXED_PROPERTY_NAME})#if(${RETURN_TYPE}): ${CLASS_NAME}#else#end
{
#if ($FIXED_RETURN_TYPE == 'Collection')
if(true === $this->${FIELD_NAME}->contains($${FIXED_PROPERTY_NAME})) {
$this->${FIELD_NAME}->removeElement($${FIXED_PROPERTY_NAME});
}
#else
if(true === in_array($${FIXED_PROPERTY_NAME}, $this->${FIELD_NAME}, true)) {
$index = array_search($${FIXED_PROPERTY_NAME}, $this->${FIELD_NAME});
array_splice($this->${FIELD_NAME}, $index, 1);
}
#end
return $this;
}
#end
/**
* @param ${TYPE_HINT} $${PARAM_NAME}
* @return ${CLASS_NAME}
*/
public function set${NAME}(#if (${SCALAR_TYPE_HINT})${SCALAR_TYPE_HINT} #else#end$${PARAM_NAME})#if(${RETURN_TYPE}): ${CLASS_NAME}#else#end
{
$this->${FIELD_NAME} = $${PARAM_NAME};
return $this;
}
我设法创造了类似的东西,随时根据您的需求进行修改。这是流畅的setter 实时模板。
它适用于Doctrine的Collection / ArrayCollection数组。扩展此功能就像创建新的 #elseif 语句一样简单。
/**
* @var array|string[]
*/
protected $oneField;
/**
* @var ArrayCollection|Collection|Another[]
*
* @ORM\OneToMany(targetEntity="Acme\DemoBundle\Entity\Another")
*/
protected $anotherField;