Загруженное изображение слишком большое: появляется круговая ссылка - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь создать форму подписки с Symfony4, и мне показалось, что она работает, но кажется, что, когда я пытаюсь загрузить изображение профиля, которое слишком велико, у меня появляется следующая ошибка:обнаружен при сериализации объекта класса «App \ Entity \ User» (настроено ограничение: 1)

Однако я установил ограничение на мое свойство profilePicture в отношении максимального размера файла, который пользователь попытается загрузить, поэтому яне понимаю, почему это происходит (у меня все остальные ошибки отображаются хорошо).

Вот часть кода, касающаяся свойства profilePicture:

/**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank(message="Merci de bien vouloir sélectionner une image")
     * @Assert\Image(
     *     minRatio="1",
     *     maxRatio="1",
     *     minWidth="250",
     *     minHeight="250",
     *     minRatioMessage="Votre photo de profil doit avoir un ratio de 1:1",
     *     maxRatioMessage="Votre photo de profil doit avoir un ratio de 1:1",
     *     minWidthMessage="Votre image doit faire minimum {{ minWidth }} de large",
     *     maxWidthMessage="Votre image doit faire minimun {{ minHeight }} de hauteur", 
     *     maxSize="2M",
     *     maxSizeMessage="Votre image ne peut pas fait plus de 2M")
     */
    private $profilePicture;

HomeController, имеющий дело сформа подписки:

/**
     * @Route("/", name="home")
     */
    public function index(Request $request, UserPasswordEncoderInterface $passwordEncoder): Response
    {
        //To Manage registration
        $user = new User();
        $form = $this->createForm(RegistrationFormType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && !$form->isValid()) {
            return $this->json([
                "status" => "error(s)",
                "errors" => $form->getErrors(true, true)
            ], 200);
        }
        if ($form->isSubmitted() && $form->isValid()) {
            // move the file from the temp folder
            $fileUploader = new FileUploader($this->getParameter('profile_pictures_directory'));
            $profilePicture = $form['userProfile']['profilePicture']->getData();
            if ($profilePicture) {
                $profilePictureFilename = $fileUploader->upload($profilePicture);
                $user->getUserProfile()->setProfilePicture($profilePictureFilename);
            }
            // encode the plain password
            $user->setPassword(
                $passwordEncoder->encodePassword(
                    $user,
                    $form->get('plainPassword')->getData()
                )
            );
            $user->setCreationDate(new \DateTime());

            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($user);
            $entityManager->flush();

            // do anything else you need here, like send an email

            return $this->json(["status" => "success"]);
        }

        return $this->render('home/index.html.twig', [
            'registrationForm' => $form->createView(),
        ]);
    }

Служба FileUploader:

<?php
namespace App\Service;

use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class FileUploader
{
    private $targetDirectory;

    public function __construct($targetDirectory)
    {
        $this->targetDirectory = $targetDirectory;
    }

    public function upload(UploadedFile $file)
    {
        $originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
        $safeFilename = transliterator_transliterate('Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()', $originalFilename);
        $fileName = $safeFilename.'-'.uniqid().'.'.$file->guessExtension();
        try {
            $file->move($this->getTargetDirectory(), $fileName);
        } catch (FileException $e) {

        }

        return $fileName;
    }

    public function getTargetDirectory()
    {
        return $this->targetDirectory;
    }
}

Между объектом User и объектом UserProfile существует отношение OneToOne, в котором хранятся дополнительные данные о пользователе.

Я бы хотел, чтобы это просто отображало сообщение об ошибке, касающееся размера файла, как это происходит для всех других типов ошибок. Дайте мне знать, если вам нужны другие части моего кода.

1 Ответ

1 голос
/ 23 октября 2019

Как оказалось, форма выдает ошибки, и по крайней мере одна из ошибок содержит сложный объект, который вводит рекурсию в процесс кодирования json *:

        return $this->json([
            "status" => "error(s)",
            "errors" => $form->getErrors(true, true)
        ], 200);

, чтобы этого не происходилопредпочтительно подготовить отображаемые ошибки:

$formerrors = [];
foreach($form->getErrors(true, true) as $error) {
    $fieldname = ($origin = $error->getOrigin()) ? $origin->getName() : null;
    if($fieldname) {
        $formerrors[$fieldname] = $error->getMessage();
    } else {
        $formerrors[] = $error->getMessage();
}
return $this->json([
    "status" => "error(s)",
    "errors" => $formerrors,
], 200);

, поскольку ошибка может иметь нет источника, но сама форма, условие в цикле может быть необходимым. также: для глубоко вложенных форм может быть необходимо улучшить подход.

В качестве примечания: возвращенный код состояния (200 в вашем случае) не в порядке, и он должен быть чем-то в 400-х годах, поскольку запрос выдал ошибку, ответ не должен быть 200 («ОК»).

*) для тех, кто интересуется, как это заметить: обычно требуется ВСЕ из стандартного времени 30-х, пока не истечет время ожидания. и если стандартное время выполнения установлено неограниченным, весь компьютер может зависнуть, потому что он медленно (или очень быстро) израсходует всю память, чтобы подготовить бесконечно длинный ответ. это почти всегда происходит, когда var_dump или print_r сложные объекты, которые в своих ссылках (возможно, многоуровневые) ссылаются на сложные объекты или друг на друга, создавая бесконечный цикл, когда процесс сериализации следует за ссылками глубже в объекты. dump, а также dd (выходные данные отладки Symfony) обычно работают way лучше (рекурсия исключается) и, таким образом, позволяют проверять объект. - однако, и dd, и dump не должны использоваться в производстве, также компонент отладки по умолчанию отключен в prod env.

...