gpt4 book ai didi

php - 为什么我不能在 Doctrine 实体中使用公共(public)属性?

转载 作者:可可西里 更新时间:2023-11-01 13:59:37 26 4
gpt4 key购买 nike

假设我有一个非常简单的 PHP CRUD 系统来管理数据库。假设它包含一个产品列表。使用 Doctrine ORM,我想查询数据库并查看/编辑/添加记录。根据Getting Started手册,

When creating entity classes, all of the fields should be protected or private (not public), with getter and setter methods for each one (except $id). The use of mutators allows Doctrine to hook into calls which manipulate the entities in ways that it could not if you just directly set the values with entity#field = foo;

这是提供的示例:

// src/Product.php
class Product
{
/**
* @var int
*/
protected $id;
/**
* @var string
*/
protected $name;

public function getId()
{
return $this->id;
}

public function getName()
{
return $this->name;
}

public function setName($name)
{
$this->name = $name;
}
}

// Recording a new title
$product->setName("My new name");
$db->persist($product);
$db->flush();

// Echoing the title
echo $product->getName();

但是,这似乎过于复杂。假设我不需要像手册中所解释的那样 Hook 来操纵实体的调用。我可以让这段代码更短,然后这样做:

// src/Product.php
class Product
{
/**
* @var int
*/
public $id;
/**
* @var string
*/
public $name;
}

这将允许这样的事情:

$product = $db->getRepository('Product')->find(1);

// Recording a new name
$product->name = "My new title";
$db->persist($product);
$db->flush();

// Echoing the title
echo $product->name;

优点是:

  • 始终使用完全相同的名称
  • 实体类中没有额外的 setter 和 getter

使用这个有什么缺点?我在这里冒某些风险吗?

最佳答案

Say I don't have a need to hook into calls to manipulate entities, as explained in the manual.

不需要 Hook 这些调用,但Doctrine 需要。 Doctrine 在内部覆盖了这些 getter 和 setter 以尽可能透明地实现 ORM。

是的,它过于复杂,但这是 PHP 语言的错误,而不是 Doctrine。使用公共(public)属性本质上没有错,只是 PHP 语言不允许像其他一些语言那样创建自定义 getter/setter(例如 KotlinC#)。

Doctrine 到底做了什么?它生成所谓的 Proxy 对象来实现延迟加载。这些对象扩展您的类并覆盖某些方法。

对于您的代码:

// src/Product.php
class Product
{
/**
* @var int
*/
protected $id;
/**
* @var string
*/
protected $name;

public function getId()
{
return $this->id;
}

public function getName()
{
return $this->name;
}

public function setName($name)
{
$this->name = $name;
}
}

学说可能会产生:

class Product extends \YourNamespace\Product implements \Doctrine\ORM\Proxy\Proxy
{

// ... Lots of generated methods ...

public function getId(): int
{
if ($this->__isInitialized__ === false) {
return (int) parent::getId();
}


$this->__initializer__ && $this->__initializer__->__invoke($this, 'getId', []);

return parent::getId();
}

public function getName(): string
{

$this->__initializer__ && $this->__initializer__->__invoke($this, 'getName', []);

return parent::getName();
}

// ... More generated methods ...
}

(这到底做了什么不是重点,重点是 Doctrine 必须能够覆盖 getter 和 setter 以实现 ORM)

要亲自查看,请检查 Doctrine 代理目录中生成的 Proxy 对象。查看Advanced Configuration部分了解有关配置代理目录的更多信息。另见 Working with Objects有关代理对象以及 Doctrine 如何使用它们的更多信息。

关于php - 为什么我不能在 Doctrine 实体中使用公共(public)属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46022607/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com