如何取消/删除受保护的属性

5

我有一个以下的Product对象/类:

class Product
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @Exclude()
     * @ORM\Column(name="deletedAt", type="datetime", nullable=true)
     */
    private $deletedAt;

    /**
     * @Assert\NotBlank()
     * @Assert\MinLength( limit=3, message=" Product Name should have at least {{ limit }} characters.")
     * @ORM\Column(name="name", type="string", length=100 , nullable=false)
     */
    protected $name;

    /**
     * @var datetime $created
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(type="datetime")
     */
    private $created;

    /**
     * @var datetime $updated
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(type="datetime")
     */
    private $updated;

    /**
     * @ORM\Column(name="description", type="string", length=350)
     */
    protected $description;


    /**
     * @Assert\NotBlank()
     * @ORM\Column(name="code", type="string", length=100)
     */
    protected $code;


    /**
     * @Assert\NotBlank()
     * @ORM\ManyToOne(targetEntity="Shopious\MainBundle\Entity\Category", inversedBy="products")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id", onDelete="CASCADE", nullable=true)
     */
    protected $category;

    /**
     * @Assert\NotBlank()
     * @Assert\Min(limit = "0", message = "negative number is invalid")
     * @Assert\Type(type="float", message="The value {{ value }} is not a valid number.")
     * @ORM\Column(name="price", type="float")
     */
    protected $price;

    /**
     * @Assert\NotBlank()
     * @Assert\Min(limit = "0", message = "negative number is invalid")
     * @Assert\Type(type="float", message="The value {{ value }} is not a valid number.")
     * @ORM\Column(name="height", type="float")
     */
    protected $height;

    /**
     * @Assert\NotBlank()
     * @Assert\Min(limit = "0", message = "negative number is invalid")
     * @Assert\Type(type="float", message="The value {{ value }} is not a valid number.")
     * @ORM\Column(name="width", type="float")
     */
    protected $width;

    /**
     * @Assert\NotBlank()
     * @Assert\Min(limit = "0", message = "negative number is invalid")
     * @Assert\Type(type="float", message="The value {{ value }} is not a valid number.")
     * @ORM\Column(name="length", type="float")
     */
    protected $length;

    /**
     * @Assert\NotBlank()
     * @Assert\Min(limit = "0", message = "negative number is invalid")
     * @Assert\Type(type="float", message="The value {{ value }} is not a valid number.")
     * @ORM\Column(name="weight", type="float" )
     */
    protected $weight;

    /**
     * @Accessor(getter="getShopRef")
     * @ORM\ManyToOne(targetEntity="Shopious\MainBundle\Entity\Shop", inversedBy="products")
     * @ORM\JoinColumn(name="shop_id", referencedColumnName="id", onDelete="CASCADE" , nullable=false)
     */
    protected $shop;


    /**
     * @ORM\OneToMany(targetEntity="ProductAttribute", mappedBy="product", cascade={"persist","remove"})
     */
    protected $attributes;

}

我有一个Product对象,想要移除该产品的所有属性,所以我执行了以下操作:

unset(product->attributes)

然而,它抱怨无法访问属性。如何将产品的属性设置为nil?


2
你想要实现什么?你意识到取消设置不会影响持久化数据吗? - zerkms
最好还是实例化一个新对象,而不是尝试“清理”现有对象。就像zerkms所说的那样。 - Mike Purcell
4个回答

6

根据定义,受保护的属性只能从定义它的类的实例或继承类中访问。

这就是为什么人们会选择将属性设置为受保护而不是公共的原因,以使其在类的实例外部无法更改。

要取消设置,必须在类内部执行,如:

  public function removeAttributes(){
      unset($this->attributes);
  }

我还会添加一个循环/条件 property_exists($this, $property) 来确保它存在。 - Robert
1
在 PHP 中,取消设置不存在的属性或变量不是错误。https://3v4l.org/0YuhC - Orangepill

5
您可以使用反射来将私有/受保护的属性设置为nullhttp://php.net/manual/zh/reflectionproperty.setvalue.php
class Foo {
    public static $staticProperty;

    public $property;
    protected $privateProperty;
}

$reflectionClass = new ReflectionClass('Foo');

$reflectionProperty = $reflectionClass->getProperty('privateProperty');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($foo, null);

2
如果属性被类型提示并且不可为空,该怎么办? - pmishev

3

我认为您需要为此创建一个公共函数:

class product{
    // Include everything from above

    public function unset_attributes(){
        unset($this->attributes);
    }
}

在对象内部的受保护变量方面,您可以在这里找到更多信息。

0

使用array_diff代替unset,像这样:

$this->channels = ['value_1', 'value_2'];

$this->channels = array_values(array_diff($this->channels, array('value_1')));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接