教义不是在拯救我的实体吗?
Doctrine isn't saving my entities?
我有以下模型,或者你称之为实体,我还有一个控制器,在这个动作中一切正常,但是当我检查数据库时没有用户。所以我很好奇我错过了什么。那么让我们从头开始,看看我有什么:
bootstrap.php
包含以下代码等。
...
/** ---------------------------------------------------------------- **/
// Lets Setup Doctrine.
/** ---------------------------------------------------------------- **/
require_once 'vendor/autoload.php';
$loader = require 'vendor/autoload.php';
\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
/**
* Set up Doctrine.
*/
class DoctrineSetup {
/**
* @var array $paths - where the entities live.
*/
protected $paths = array(APP_MODELS);
/**
* @var bool $isDevMode - Are we considered "in development."
*/
protected $isDevMode = false;
/**
* @var array $dbParams - The database paramters.
*/
protected $dbParams = null;
/**
* Constructor to set some core values.
*/
public function __construct(){
if (!file_exists('db_config.ini')) {
throw new \Exception(
'Missing db_config.ini. You can create this from the db_config_sample.ini'
);
}
$this->dbParams = array(
'driver' => 'pdo_mysql',
'user' => parse_ini_file('db_config.ini')['DB_USER'],
'password' => parse_ini_file('db_config.ini')['DB_PASSWORD'],
'dbname' => parse_ini_file('db_config.ini')['DB_NAME']
);
}
/**
* Get the entity manager for use through out the app.
*
* @return EntityManager
*/
public function getEntityManager() {
$config = Setup::createAnnotationMetadataConfiguration($this->paths, $this->isDevMode, null, null, false);
return EntityManager::create($this->dbParams, $config);
}
}
/**
* Function that can be called through out the app.
*
* @return EntityManager
*/
function getEntityManager() {
$ds = new DoctrineSetup();
return $ds->getEntityManager();
}
/**
* Function that returns the conection to the database.
*/
function getConnection() {
$ds = new DoctrineSetup();
return $ds->getEntityManager()->getConnection();
}
...
现在我们已经有了学说,可以创建模型(实体)并设置哪些字段可以为空,哪些字段不能为空等等。
注意 在这一点上,你应该知道我不是在使用 Symfony,而是它在 Doctrine 之上的组件。我正在使用 Slim 框架。因此,如果有任何建议是使用 symfony 中的 x 或 y,请确保它是一个组件。
Models/User.php
<?php
namespace ImageUploader\Models;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="users", uniqueConstraints={
* @ORM\UniqueConstraint(name="user", columns={"userName", "email"})}
* )
*/
class User {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="string", length=32, nullable=false)
* @Assert\NotBlank()
*/
protected $firstName;
/**
* @ORM\Column(type="string", length=32, nullable=false)
* @Assert\NotBlank()
*/
protected $lastName;
/**
* @ORM\Column(type="string", length=100, unique=true, nullable=false)
* @Assert\NotBlank(
* message = "Username cannot be blank"
* )
*/
protected $userName;
/**
* @ORM\Column(type="string", length=100, unique=true, nullable=false)
* @Assert\NotBlank(
* message = "Email field cannot be blank."
* )
* @Assert\Email(
* message = "The email you entered is invalid.",
* checkMX = true
* )
*/
protected $email;
/**
* @ORM\Column(type="string", length=500, nullable=false)
* @Assert\NotBlank(
* message = "The password field cannot be empty."
* )
*/
protected $password;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $created_at;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $updated_at;
/**
* Get the value of Created At
*
* @return mixed
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set the value of Created At
*
* @param mixed created_at
*
* @return self
*/
public function setCreatedAt(\DateTime $created_at = null)
{
$this->created_at = $created_at;
return $this;
}
/**
* Get the value of Updated At
*
* @return mixed
*/
public function getUpdatedAt()
{
return $this->updated_at;
}
/**
* Set the value of Updated At
*
* @param mixed updated_at
*
* @return self
*/
public function setUpdatedAt(\DateTime $updated_at = null)
{
$this->updated_at = $updated_at;
return $this;
}
/**
* Get the value of First Name
*
* @return mixed
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set the value of First Name
*
* @param mixed firstName
*
* @return self
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* Get the value of Last Name
*
* @return mixed
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Set the value of Last Name
*
* @param mixed lastName
*
* @return self
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
/**
* Get the value of User Name
*
* @return mixed
*/
public function getUserName()
{
return $this->userName;
}
/**
* Set the value of User Name
*
* @param mixed userName
*
* @return self
*/
public function setUserName($userName)
{
$this->userName = $userName;
return $this;
}
/**
* Get the value of Email
*
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* Set the value of Email
*
* @param mixed email
*
* @return self
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Set ths password.
*
* @param string password
*
* @return self
*/
public function setPassword($password) {
$this->password = password_hash($password, PASSWORD_DEFAULT);
return $this;
}
/**
* Check the users password against that which is enterd.
*
* @param string password
*
* @return bool
*/
public function checkPassword($password) {
if (password_hash($password, PASSWORD_DEFAULT) === $this->getPassword()) {
return true;
}
return false;
}
/**
* Return the password value.
*
* @return hash
*/
private function getPassword(){
return $this->password;
}
/**
* @ORM\PrePersist
*/
public function setCreatedAtTimeStamp() {
if (is_null($this->getCreatedAt())) {
$this->setCreatedAt(new \DateTime());
}
}
/**
* @ORM\PreUpdate
*/
public function setUpdatedAtTimeStamp() {
if (is_null($this->getUpdatedAt())) {
$this->setUpdatedAt(new \DateTime());
}
}
}
上面的模型是正确的,据我所知,我的意思是当我运行"vendor/bin/doctrine migrations:migrate"
创建了一个数据库tableis .
现在,这些都用在什么地方了?它在名为 SignupController
的控制器中用于名为 createAction($params)
的操作
**createAction($params)**
public static function createAction($params){
$postParams = $params->request()->post();
$flash = new Flash();
if ($postParams['password'] !== $postParams['repassword']) {
$flash->createFlash('error', 'Your passwords do not match.');
self::$createEncryptedPostParams($postParams);
$params->redirect('/signup/error');
}
$user = new User();
$user->setFirstName($postParams['firstname'])
->setLastName($postParams['lastname'])
->setUserName($postParams['username'])
->setEmail($postParams['email'])
->setPassword($postParams['password'])
->setCreatedAtTimeStamp();
$validator = Validator::createValidatorBuilder();
$validator->enableAnnotationMapping();
$errors = $validator->getValidator()->validate($user);
if (count($errors) > 0) {
foreach($errors as $error) {
$flash->createFlash(
$error->getPropertyPath() . 'error',
$error->getMessage()
);
}
self::createEncryptedPostParams($postParams);
$params->redirect('/signup/error');
}
$anyEncryptedErors = self::getEncryptedPostParams();
if ($anyEncryptedErors !== null) {
$anyEncryptedErors->destroy('error');
}
getEntityManager()->flush();
getEntityManager()->persist($user);
$flash->createFlash('success', ' You have signed up successfully! Please sign in!');
$params->redirect('/signin');
}
现在你应该正确输入所有内容,我会显示成功并重定向你。 这有效 它重定向,它显示一条闪现消息。但它是:
getEntityManager()->flush();
getEntityManager()->persist($user);
我认为这行不通。为什么?因为对有问题的数据库执行 select * from users
返回时没有任何记录。
为什么?
Flush语句应该在persist之后执行。所以代码应该是:
getEntityManager()->persist($user);
getEntityManager()->flush();
如果您有对象 ID,然后数据库没有显示它,您可能有一个 "START TRANSACTION",然后您有一个插入,在此插入之后您将有一个 "COMMIT"。如果在您的坚持和提交之间出现任何错误,对象将不会存储在您的数据库中。
检查您的 Symfony 请求分析器信息。
您可以使用开发者工具找到它并检查您的回复。
我有一个类似的问题,我想我会 post 在这里。我正在创建一个实体并且一切都正确响应,但是当我检查数据库时没有创建任何记录。
只需将冲洗包裹在 try-catch
中并记录错误。
$this->em->persist($insectLifeCycle);
try {
$this->em->flush();
} catch (\Exception $error) {
$this->logger->debug($error);
}
事实证明,其中一个属性超出了其字符数限制,数据库引发了错误。还发现我需要改进我的错误处理....
正如 Samiul Amin Shanto 所说:
getEntityManager()->persist($user);
getEntityManager()->flush();
将是正确的方法,因为持久化操作准备要存储在数据库中的数据并刷新“将所有更改刷新到数据库中。”
我有以下模型,或者你称之为实体,我还有一个控制器,在这个动作中一切正常,但是当我检查数据库时没有用户。所以我很好奇我错过了什么。那么让我们从头开始,看看我有什么:
bootstrap.php
包含以下代码等。
...
/** ---------------------------------------------------------------- **/
// Lets Setup Doctrine.
/** ---------------------------------------------------------------- **/
require_once 'vendor/autoload.php';
$loader = require 'vendor/autoload.php';
\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
/**
* Set up Doctrine.
*/
class DoctrineSetup {
/**
* @var array $paths - where the entities live.
*/
protected $paths = array(APP_MODELS);
/**
* @var bool $isDevMode - Are we considered "in development."
*/
protected $isDevMode = false;
/**
* @var array $dbParams - The database paramters.
*/
protected $dbParams = null;
/**
* Constructor to set some core values.
*/
public function __construct(){
if (!file_exists('db_config.ini')) {
throw new \Exception(
'Missing db_config.ini. You can create this from the db_config_sample.ini'
);
}
$this->dbParams = array(
'driver' => 'pdo_mysql',
'user' => parse_ini_file('db_config.ini')['DB_USER'],
'password' => parse_ini_file('db_config.ini')['DB_PASSWORD'],
'dbname' => parse_ini_file('db_config.ini')['DB_NAME']
);
}
/**
* Get the entity manager for use through out the app.
*
* @return EntityManager
*/
public function getEntityManager() {
$config = Setup::createAnnotationMetadataConfiguration($this->paths, $this->isDevMode, null, null, false);
return EntityManager::create($this->dbParams, $config);
}
}
/**
* Function that can be called through out the app.
*
* @return EntityManager
*/
function getEntityManager() {
$ds = new DoctrineSetup();
return $ds->getEntityManager();
}
/**
* Function that returns the conection to the database.
*/
function getConnection() {
$ds = new DoctrineSetup();
return $ds->getEntityManager()->getConnection();
}
...
现在我们已经有了学说,可以创建模型(实体)并设置哪些字段可以为空,哪些字段不能为空等等。
注意 在这一点上,你应该知道我不是在使用 Symfony,而是它在 Doctrine 之上的组件。我正在使用 Slim 框架。因此,如果有任何建议是使用 symfony 中的 x 或 y,请确保它是一个组件。
Models/User.php
<?php
namespace ImageUploader\Models;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="users", uniqueConstraints={
* @ORM\UniqueConstraint(name="user", columns={"userName", "email"})}
* )
*/
class User {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="string", length=32, nullable=false)
* @Assert\NotBlank()
*/
protected $firstName;
/**
* @ORM\Column(type="string", length=32, nullable=false)
* @Assert\NotBlank()
*/
protected $lastName;
/**
* @ORM\Column(type="string", length=100, unique=true, nullable=false)
* @Assert\NotBlank(
* message = "Username cannot be blank"
* )
*/
protected $userName;
/**
* @ORM\Column(type="string", length=100, unique=true, nullable=false)
* @Assert\NotBlank(
* message = "Email field cannot be blank."
* )
* @Assert\Email(
* message = "The email you entered is invalid.",
* checkMX = true
* )
*/
protected $email;
/**
* @ORM\Column(type="string", length=500, nullable=false)
* @Assert\NotBlank(
* message = "The password field cannot be empty."
* )
*/
protected $password;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $created_at;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $updated_at;
/**
* Get the value of Created At
*
* @return mixed
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set the value of Created At
*
* @param mixed created_at
*
* @return self
*/
public function setCreatedAt(\DateTime $created_at = null)
{
$this->created_at = $created_at;
return $this;
}
/**
* Get the value of Updated At
*
* @return mixed
*/
public function getUpdatedAt()
{
return $this->updated_at;
}
/**
* Set the value of Updated At
*
* @param mixed updated_at
*
* @return self
*/
public function setUpdatedAt(\DateTime $updated_at = null)
{
$this->updated_at = $updated_at;
return $this;
}
/**
* Get the value of First Name
*
* @return mixed
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set the value of First Name
*
* @param mixed firstName
*
* @return self
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* Get the value of Last Name
*
* @return mixed
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Set the value of Last Name
*
* @param mixed lastName
*
* @return self
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
/**
* Get the value of User Name
*
* @return mixed
*/
public function getUserName()
{
return $this->userName;
}
/**
* Set the value of User Name
*
* @param mixed userName
*
* @return self
*/
public function setUserName($userName)
{
$this->userName = $userName;
return $this;
}
/**
* Get the value of Email
*
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* Set the value of Email
*
* @param mixed email
*
* @return self
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Set ths password.
*
* @param string password
*
* @return self
*/
public function setPassword($password) {
$this->password = password_hash($password, PASSWORD_DEFAULT);
return $this;
}
/**
* Check the users password against that which is enterd.
*
* @param string password
*
* @return bool
*/
public function checkPassword($password) {
if (password_hash($password, PASSWORD_DEFAULT) === $this->getPassword()) {
return true;
}
return false;
}
/**
* Return the password value.
*
* @return hash
*/
private function getPassword(){
return $this->password;
}
/**
* @ORM\PrePersist
*/
public function setCreatedAtTimeStamp() {
if (is_null($this->getCreatedAt())) {
$this->setCreatedAt(new \DateTime());
}
}
/**
* @ORM\PreUpdate
*/
public function setUpdatedAtTimeStamp() {
if (is_null($this->getUpdatedAt())) {
$this->setUpdatedAt(new \DateTime());
}
}
}
上面的模型是正确的,据我所知,我的意思是当我运行"vendor/bin/doctrine migrations:migrate"
创建了一个数据库tableis .
现在,这些都用在什么地方了?它在名为 SignupController
的控制器中用于名为 createAction($params)
**createAction($params)**
public static function createAction($params){
$postParams = $params->request()->post();
$flash = new Flash();
if ($postParams['password'] !== $postParams['repassword']) {
$flash->createFlash('error', 'Your passwords do not match.');
self::$createEncryptedPostParams($postParams);
$params->redirect('/signup/error');
}
$user = new User();
$user->setFirstName($postParams['firstname'])
->setLastName($postParams['lastname'])
->setUserName($postParams['username'])
->setEmail($postParams['email'])
->setPassword($postParams['password'])
->setCreatedAtTimeStamp();
$validator = Validator::createValidatorBuilder();
$validator->enableAnnotationMapping();
$errors = $validator->getValidator()->validate($user);
if (count($errors) > 0) {
foreach($errors as $error) {
$flash->createFlash(
$error->getPropertyPath() . 'error',
$error->getMessage()
);
}
self::createEncryptedPostParams($postParams);
$params->redirect('/signup/error');
}
$anyEncryptedErors = self::getEncryptedPostParams();
if ($anyEncryptedErors !== null) {
$anyEncryptedErors->destroy('error');
}
getEntityManager()->flush();
getEntityManager()->persist($user);
$flash->createFlash('success', ' You have signed up successfully! Please sign in!');
$params->redirect('/signin');
}
现在你应该正确输入所有内容,我会显示成功并重定向你。 这有效 它重定向,它显示一条闪现消息。但它是:
getEntityManager()->flush();
getEntityManager()->persist($user);
我认为这行不通。为什么?因为对有问题的数据库执行 select * from users
返回时没有任何记录。
为什么?
Flush语句应该在persist之后执行。所以代码应该是:
getEntityManager()->persist($user);
getEntityManager()->flush();
如果您有对象 ID,然后数据库没有显示它,您可能有一个 "START TRANSACTION",然后您有一个插入,在此插入之后您将有一个 "COMMIT"。如果在您的坚持和提交之间出现任何错误,对象将不会存储在您的数据库中。 检查您的 Symfony 请求分析器信息。 您可以使用开发者工具找到它并检查您的回复。
我有一个类似的问题,我想我会 post 在这里。我正在创建一个实体并且一切都正确响应,但是当我检查数据库时没有创建任何记录。
只需将冲洗包裹在 try-catch
中并记录错误。
$this->em->persist($insectLifeCycle);
try {
$this->em->flush();
} catch (\Exception $error) {
$this->logger->debug($error);
}
事实证明,其中一个属性超出了其字符数限制,数据库引发了错误。还发现我需要改进我的错误处理....
正如 Samiul Amin Shanto 所说:
getEntityManager()->persist($user);
getEntityManager()->flush();
将是正确的方法,因为持久化操作准备要存储在数据库中的数据并刷新“将所有更改刷新到数据库中。”