Ric*_*man 4 php mysql symfony doctrine-orm
当我将文件上传到 Symfony 时,它会按应有的方式上传。我已经使用了 Symfony 文件上传教程并对其进行了修改以满足我的需要。
if($form->isValid())
{
$em = $this->oStarter->getEntityManager();
// Save file to database
$uploadedFile = new ProfilePicture();
$uploadedFile->setFile($formData["profile_picture"]);
$user->setProfilePicture($uploadedFile);
$uploadedFile->setUser($user);
$em->persist($uploadedFile);
$em->persist($user);
$em->flush();
// Other things like Twig templates etc..
Run Code Online (Sandbox Code Playgroud)
此代码用于上传图像并将其设置为用户的个人资料图片。$this->getUser()
通过在控制器中找到用户。当我在刷新后输出实体时,它会向我显示有效实体的转储,就像我所期望的那样。
当我访问该用户的个人资料页面时,找不到该图像。当我检查 MySQL 表时,我发现 ProfilePicture 的有效条目具有正确的 ID 和路径。正如您所期望的,用户还可以引用 ProfilePicture 的 ID。相反,该页面向我显示以下转储:
$avatar = $user->getProfilePicture();
$path = $avatar->getWebPath();
Debug::dump($avatar);
object(stdClass)#938 (8)
{
["__CLASS__"]=>
string(42) "Takeabyte\CoreBundle\Entity\ProfilePicture"
["__IS_PROXY__"]=>
bool(true)
["__PROXY_INITIALIZED__"]=>
bool(false)
["id"]=>
NULL
["user"]=>
object(stdClass)#1011 (52) {
["__CLASS__"]=>
string(32) "Takeabyte\CoreBundle\Entity\User"
["id"]=>
int(11)
// lots of user info
}
["file"]=>
NULL
["path"]=>
NULL
["temp"]=>
NULL
}
Run Code Online (Sandbox Code Playgroud)
转储显示没有设置路径。即使在调用代理函数之后,实际数据似乎也没有被加载。我究竟做错了什么?
编辑 实体如下:
/**
* @author Tim Cocu
* @author Rick Slinkman
*
* @ORM\Entity
* @ORM\Table(name="profilepictures")
* @Database(target="client")
*/
class ProfilePicture extends Image
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="\Takeabyte\CoreBundle\Entity\User", mappedBy="profilePicture")
*/
private $user;
// accessors and mutators
}
/**
* Description of Image
*
* @ORM\MappedSuperclass
* @Database(target="client")
* @author Rick Slinkman (r.slinkman@take-a-byte.eu)
*/
class Image extends MediaFile
{
/**
* @param ClassMetadata $metadata
*/
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('file', new Assert\File(array(
'maxSize' => 6000000,
'mimeTypes' => array(
"image/jpeg",
"image/png",
"image/gif"
),
)));
}
// other functions
}
/**
* Standard container of an uploaded media file
* @author Rick Slinkman
* @author Tim Cocu
*
* @ORM\HasLifecycleCallbacks
* @ORM\MappedSuperclass
* @Database(target="client")
*
* Based on:
* http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html
*/
class MediaFile
{
/**
* @Assert\File(maxSize="6000000")
*/
protected $file;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $path;
/**
* Temporary storage on file moving.
*/
protected $temp;
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->getFile())
{
// do whatever you want to generate a unique name
$filename = sha1(uniqid(mt_rand(), true));
$this->path = $filename.'.'.$this->getFile()->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->getFile())
{
return;
}
// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->getFile()->move($this->getUploadRootDir(), $this->path);
// check if we have an old image
if (isset($this->temp))
{
// delete the old image
unlink($this->getUploadRootDir().'/'.$this->temp);
// clear the temp image path
$this->temp = null;
}
$this->file = null;
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if ($file = $this->getAbsolutePath())
{
unlink($file);
}
}
// other functions
}
/**
* @author: Jordy - j.deruijter@take-a-byte.eu
* @author: Rick - r.slinkman@take-a-byte.eu
* @author: Tim - t.cocu@take-a-byte.eu
* @since: 25-10-13
*
* @ORM\Entity
* @ORM\Table(name="fos_user_user")
* @Database(target="client")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// Lots of data
/**
* @var ProfilePicture
* @ORM\OneToOne(targetEntity="\Takeabyte\CoreBundle\Entity\ProfilePicture", inversedBy="user")
*/
protected $profilePicture;
// Even more data
}
Run Code Online (Sandbox Code Playgroud)
我想大约一年前我也遇到过类似的错误。
您会看到,当您进行身份验证时,实体的序列化(文本)版本User
存储在您的会话中。当您访问防火墙后面的页面时,它会被反序列化并User
再次转换。但是,由于您的关系ProfilePicture
并不急切,并且在序列化期间该属性未序列化。代理对象不可序列化...
因此,当它尝试从会话中检索经过身份验证的用户时,其$profilePicture
属性被设置为NULL
。
这可能是你的情况吗?
EAGER
在您的User
实体中。always_authenticate_before_granting: true
在您的confir.yml
(security
块)中进行设置我相信这将导致安全性进入数据库并User
在每次页面访问时重新获取实体......
刷新您的用户实体并profilePicture
手动获取。也许您也可以在会话中单独存储用户个人资料图片?