php - symfony2 项目上的 Swiftmailer 附件错误(无法打开文件进行阅读)

标签 php forms symfony email swiftmailer

我正在开发一个 symfony 项目,我有一个必须使用 swiftmailer 发送邮件的表单。 对于解释 -> 用户可以在表单的可选文件上传功能中使用附件。 (表格像命令一样保存在 bdd 中,提交表格后我们进行了回顾,并且发送了 3 封邮件(我们每次都不使用附件的两封邮件,只有带附件选项的邮件失败了有一个文件要加入,否则如果我们只使用评论(其他字段可选,像路径一样工作,邮件正在工作)

我希望我的解释清楚易懂,我的英语并不完美,功能也不太容易。由于某些信息的 secret 性,我在这里只写了与邮件有关的代码,但如果我忘记了什么,请告诉我,我会更新帖子。

当我发送一个没有附件的邮件时,我没有遇到任何问题,但是当我尝试加入一个文件时,symfony 给我这个错误:

Unable to open file for reading [uploads/6M.jpg]

我试图在 StackOverflow 的其他帖子上找到解决方案,但没有人在工作。所以我希望你能帮助我。

命令实体(我只是把有关文件、路径和附件上传的代码放在一起(其余的邮件程序/代码工作):

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Form\Extension\HttpFoundation;

/**
* Commandes
*/
class Commandes
{
// CUSTOM CODE

/**
 * @var string
 */
public $file3;

/**
 * @var string
 */
protected $path3;

public function getAbsolutePath1()
{
    return null === $this->path1 ? null : $this->getUploadRootDir().'/'.$this->id.'.'.$this->path1;
}

public function getWebPath1()
{
    return null === $this->path1 ? null : $this->getUploadDir().'/'.$this->path1;
}

protected function getUploadRootDir()
{
    return __DIR__ . '/../../../web/' . $this->getUploadDir();
}


protected function getUploadDir()
{
    return 'uploads';
}


/**
 * @var string
 */
protected $path1;


/**
 * @Assert\File(maxSize="60000000")
 */
public $file1;


// CallBack : preUpdate | prePersist \\
public function preUpload1()
{
    if (null !== $this->file1) {
        $this->path1 = $this->file1->guessExtension();
    }
}


// CallBacks : PostPersist | PostUpdate \\
public function upload1()
{
    if (null === $this->file1) {
        return;
    }

    $this->file1->move($this->getUploadRootDir(), $this->getReferencePatient() . 'M.' . $this->file1->guessExtension());

    $this->path1 = $this->getReferencePatient() . 'M.' . $this->file1->getClientOriginalExtension();

    $this->file1 = null;
}


protected $path2;

public $file2;

// CallBack : preUpdate | prePersist \\
public function preUpload2()
{
    if (null !== $this->file2) {
        $this->path2 = $this->file2->guessExtension();
    }
}


// CallBacks : PostPersist | PostUpdate \\
public function upload2()
{
    if (null === $this->file2) {
        return;
    }

    $this->file2->move($this->getUploadRootDir(), $this->getReferencePatient() . 'm.' . $this->file2->guessExtension());

    $this->path2 = $this->getReferencePatient() . 'm.' . $this->file2->getClientOriginalExtension();

    $this->file2 = null;
}


public function getAbsolutePath2()
{
    return null === $this->path2 ? null : $this->getUploadRootDir() . '/' . $this->path2;
}

public function getWebPath2()
{
    return null === $this->path2 ? null : $this->getUploadDir() . '/' . $this->path2;
}


// CallBack : preUpdate | prePersist \\
public function preUpload3()
{
    if (null !== $this->file3) {
        $this->path3 = $this->file3->guessExtension();
    }
}

public function upload3()
{
    if (null === $this->file3) {
        return;
    }

    $this->file3->move($this->getUploadRootDir(), $this->getReferencePatient() . '.' . $this->file3->guessExtension());

    $this->path3 = $this->getReferencePatient() . '.' . $this->file3->getClientOriginalExtension();

    $this->file3 = null;
}

public function getAbsolutePath3()
{
    return null === $this->path3 ? null : $this->getUploadRootDir() . '/' . $this->path3;
}

public function getWebPath3()
{
    return null === $this->path3 ? null : $this->getUploadDir() . '/' . $this->path3;
}

/**
 * Set pathPJ1
 *
 * @param string $pathPJ1
 * @return Commandes
 */
public function setPathPJ1($pathPJ1)
{
    $this->pathPJ1 = $pathPJ1;

    return $this;
}

/**
 * Get pathPJ1
 *
 * @return string
 */
public function getPathPJ1()
{
    return $this->pathPJ1;
}

/**
 * Set pathPJ2
 *
 * @param string $pathPJ2
 * @return Commandes
 */
public function setPathPJ2($pathPJ2)
{
    $this->pathPJ2 = $pathPJ2;

    return $this;
}

/**
 * Get pathPJ2
 *
 * @return string
 */
public function getPathPJ2()
{
    return $this->pathPJ2;
}

/**
 * Set pathPJ3
 *
 * @param string $pathPJ3
 * @return Commandes
 */
public function setPathPJ3($pathPJ3)
{
    $this->pathPJ3 = $pathPJ3;

    return $this;
}

/**
 * Get pathPJ3
 *
 * @return string
 */
public function getPathPJ3()
{
    return $this->pathPJ3;
}

/**
 * Set path1
 *
 * @param string $path1
 * @return Commandes
 */
public function setPath1($path1)
{
    $this->path1 = $path1;

    return $this;
}

/**
 * Get path1
 *
 * @return string
 */
public function getPath1()
{
    return $this->path1;
}

/**
 * Set path2
 *
 * @param string $path2
 * @return Commandes
 */
public function setPath2($path2)
{
    $this->path2 = $path2;

    return $this;
}

/**
 * Get path2
 *
 * @return string
 */
public function getPath2()
{
    return $this->path2;
}

/**
 * Set path3
 *
 * @param string $path3
 * @return Commandes
 */
public function setPath3($path3)
{
    $this->path3 = $path3;

    return $this;
}

/**
 * Get path3
 *
 * @return string
 */
public function getPath3()
{
    return $this->path3;
}

Commande Controller(同样的东西我只放了关于附件的代码):

use Symfony\Component\HttpFoundation\Request;
use OrthoBundle\Entity\Compteur;
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use OrthoBundle\Entity\Commandes;
use OrthoBundle\Form\Type\CommandesType;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\Session;

class FormulaireController extends Controller
{
    public function createFormulaireAction(Request $request)
    {   
        $em = $this->getDoctrine()->getManager();

       $commande = new Commandes();

        $request = $this->get('request');

        $user = $this->getUser();

        $form = $this->createForm(new CommandesType($user), $commande);

        if ($form->isValid() && $form->isSubmitted()) {

        ***""""""SOME CODE THAT I DON'T PUT ABOUT PERSIST FLUSH THE COMMAND IN DB""""***

       $message = \Swift_Message::newInstance()
            ->setSubject('Commande n°' . $commande->getId())
            ->setFrom(array('mymail@example.com' => 'send from'))
            ->setTo(array('onemail@example.com' => 'destinatory'))
            ->setCharset('utf-8')
            ->setContentType('text/html')
            ->setBody($this->renderView('@Ortho/Mail/mail_impress.html.twig', array(
                'parentUser' => $user->getParent(),
                'commande' => $commande,
            )));
        if ($commande->getWebPath1() != '') {
            $message->attach(\Swift_Attachment::fromPath($commande->getWebPath1()));
        }
        if ($commande->getWebPath2() != '') {
            $message->attach(\Swift_Attachment::fromPath($commande->getWebPath2()));
        }
        if ($commande->getWebPath3() != '') {
            $message->attach(\Swift_Attachment::fromPath($commande->getWebPath3()));
        }
        if ($commande->getWebPath1() != '' or
            $commande->getWebPath2() != '' or
            $commande->getWebPath3() != '' or
            $commande->getCommentaire() != '') {
            $this->get('mailer')->send($message);              
        }

此代码适用于没有附件的邮件,但如果我尝试以文件形式上传邮件,则邮件不会发送。供引用:文件的上传工作和上传的文件保存在 MyApp/web/uploads 中。

命令类型.php :

<?php

namespace MyBundle\Form\Type;

use MyBundle\Entity\Utilisateurs;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;

class CommandesType extends AbstractType
{
private $user;

public function __construct(Utilisateurs $utilisateurs)
{
    $this->user = $utilisateurs;
}
/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('commentaireLabo', TextareaType::class, array(
            'attr' => array(
                'placeholder' => 'Select a product'
            ),
        ))
        ->add('file1', FileType::class, array(
            'required' => false
        ))
        ->add('file2', FileType::class, array(
            'required' => false
        ))
        ->add('file3', FileType::class, array(
            'required' => false
        ))
        ->add('commentairePrestataire', TextareaType::class, array(
            'required' => false
        ));
}

/**
 * @param OptionsResolver $resolver
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'MyBundle\Entity\Commandes'

    ));
}

这里是查看文件的表单部分:

<fieldset class="smallbloc"> <!-- Bloc n°3 : Les pièces jointes -->
    <h2 class="fs-title">Pièces jointes complémentaires</h2>
    <h3 class="fs-subtitle">Toutes les pièces jointes à apporter à la commande.</h3>

    {{ form_label(form.file1, "Arcade Maxilaire :") }}
    {{ form_errors(form.file1) }}
    {{ form_widget(form.file1) }}

    {{ form_label(form.file2, "Arcade Mandibulaire :") }}
    {{ form_errors(form.file2) }}
    {{ form_widget(form.file2) }}

    {{ form_label(form.file3, "Autre pièces jointe :") }}
    {{ form_errors(form.file3) }}
    {{ form_widget(form.file3) }}

    {{ form_label(form.commentairePrestataire3D, "Commentaires pour le prestataire 3D :") }}
    {{ form_errors(form.commentairePrestataire3D) }}
    {{ form_widget(form.commentairePrestataire3D) }}

    <input type="hidden" id="monthstat" name="monthstat" value="{{ "now"|date("m-Y") }}">

    <input type="button" name="previous" class="previous action-button" value="Précédent"/>
    <input type="submit" name="previous" class="action-button" value="ENVOYER"/>

    {{ form_rest(form) }}
</fieldset>

我希望所有必要的代码都在这里,并且我没有忘记任何东西,如果不是刚刚说的话,我将更新我的帖子,并添加错误的部分。或者如果我说了一些无脑的话或者谁不理解的话就说我解释一下。我知道阅读 x) 并不容易。谢谢大家的帮助。

最佳答案

附加文件时必须使用文件系统的绝对路径,例如:

$message->attach(\Swift_Attachment::fromPath($commande->getAbsolutePath1()));

SwiftMailer 在“服务器端”运行,它不会访问您的前端来获取您想要附加到邮件中的文件。

PS : You might also want to check that your file is actually present in the directory where it should be. Maybe the upload did not work as expected and the file is not present

关于php - symfony2 项目上的 Swiftmailer 附件错误(无法打开文件进行阅读),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39363613/

相关文章:

php - 使用 MySQL + PHP 更新多个变量

php - SELECT * FROM 多个表,按 ID 分组

php - 在 Symfony 中找不到 Call to a member function isPasswordValid() on null 的解决方案

php - Doctrine 2 多个选择元素、别名、日期格式

php - 如何在 Symfony 3 中集成 Select2 JS

javascript - PHP/JS : Auto click button in iframe when its opened

javascript - 如何在 POST 之前操作表单文件输入

mysql - Symfony Doctrine 迁移重命名表与关系

PHP导入PDF表单和输出PDF表单

jquery - 所有输入字段通过 jQuery 代码上的单行/最少行进行验证