我试图用Symfony 4和Doctrine创建一个网站。我是一个完整的初学者(一般都是Symfony和PHP),所以如果我的问题很简单,我会道歉。
我想用doctrine创建一个数据库,这意味着我必须在src/Entity
中创建类。但我也希望向网站添加表单,并且还需要src/Entity
中的类。我想在两个子文件夹中分隔这些类:src/Entity/database
和src/Entity/forms
。我尝试按如下方式编辑config/packages/doctrine.yaml
:
doctrine:
#...
orm:
#...
mappings:
App:
#...
dir: '%kernel.project_dir%/src/Entity/database'
prefix: 'App\Entity\database'
但是,当我使用bin/console make:entity Entity
时,它会在src/Entity
中创建文件并出现以下错误:
[ERROR] Only annotation mapping is supported by make:entity, but the
<info>App\Entity\Entity</info> class uses a different format. If you
would like this command to generate the properties & getter/setter
methods, add your mapping configuration, and then re-run this command
with the <info>--regenerate</info> flag.
当我运行bin/console make:entity Entity --regenerate
时,它说:
[ERROR] No entities were found in the "Entity" namespace.
我也试过bin/console make:entity database/Entity
,但它失败了:
[ERROR] "App\Entity\Database/Entity" is not valid as a PHP class name (it must start with a letter or underscore,
followed by any number of letters, numbers, or underscores)
如果我使用反斜杠(database\Entity
)执行相同操作,则会在错误的目录中创建一个DatabaseEntity.php
文件,并提供与第一个相同的错误。
答案 0 :(得分:1)
要非常小心,因为采用这种方法可能会破坏您的架构。这个问题有点自以为是,但我会告诉你我们是如何用实体和形式来做的。
首先,我坚信,实体和表格应该是分开的。因此,我们在src/Entity
中包含了Entites,在src/Form
中包含了Form。它们之间的连接是FormType,我们包含src/FormType
中的那些。
以下是src/Entity/User.php
中包含的用户实体示例:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @UniqueEntity("username")
*
* @ORM\Entity()
* @ORM\Table(name="users")
*/
class User implements UserInterface, \Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
* @var int
*/
private $id;
/**
* @Assert\NotBlank()
* @Assert\Email
* @Assert\Length(max="255")
*
* @ORM\Column(type="string", length=255, unique=true)
*
* @var string
*/
private $username;
/**
* @ORM\Column(type="string", length=64)
*
* @var string
*/
private $password;
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return string The username
*/
public function getUsername()
{
return $this->username;
}
/**
* @param null|string $username
*
* @return User
*/
public function setUsername(?string $username): User
{
$this->username = (string) $username;
return $this;
}
/**
* @return string
*/
public function getPassword(): string
{
return $this->password;
}
/**
* @param null|string $password
*
* @return User
*/
public function setPassword(?string $password): User
{
$this->password = (string) $password;
return $this;
}
}
现在,我们需要一个用户才能注册。为此,我们创建一个FormType和一个Form。看看src/FormType/User.php
:
namespace App\FormType;
use App\Entity;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as NativeType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\NotBlank;
class User extends AbstractType
{
public function getParent(): string
{
return BaseType::class;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
// This maps `Entity\User::username` to the respective field
$builder->add(
'username',
NativeType\EmailType::class,
['label' => 'username']
);
// This maps `Entity\User::password` to the respective field
$builder->add(
'password',
NativeType\RepeatedType::class,
[
'constraints' => [new NotBlank()],
'invalid_message' => 'nonMatchingPasswords',
'first_options' => ['label' => 'password'],
'second_options' => ['label' => 'password again'],
'type' => NativeType\PasswordType::class,
]
);
}
// This tells Symfony to resolve the form to the `Entity\User` class
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['data_class' => Entity\User::class]);
}
}
现在表格本身就是src/Form/UserRegistration.php
:
namespace App\Form;
use App\FormType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as NativeType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints;
class UserRegistration extends AbstractType
{
public function getParent()
{
// Note this!
return FormType\User::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'fields' => ['username', 'password'],
'translation_domain' => 'forms',
]
);
}
}
最后一击。在src/Controller/Registration.php
我们这样做:
$form = $this->createForm(
Form\UserRegistration::class,
$user = new Entity\User()
);
其他(如何处理表格等)你知道。如果你不这样做,请阅读Symfony文档,它们完全覆盖它。
我已经从这个例子中删除/编辑了一些敏感或非必要的东西。例如,我们不将password
绑定到password
,我们要求输入普通密码然后对其进行加密。我没有测试过上面的内容,所以它可能不稳定。但是为了演示你的架构应该如何完成,这是一个很好的例子,IMO。