Chapters
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Hello Symfony Mailer
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
The year is 1995: internet connection speeds are reaching a blistering 56 kbit/s, GeoCities is transforming everyone into an accomplished web designer, and sending emails... is all the rage.
Quick, fast-forward 25 years! Self-driving cars are a reality, you can download an entire HD movie in seconds, we can send rockets into space and then land them safely back on Earth and... yes, love it or hate it... sending emails is still all the rage... or at least... something nobody can avoid.
Yep, emails are still a huge part of our life and pretty much every app needs to send at least some... if not a lot of emails. But sending emails has always been kind of a pain - it feels like an old process. On top of that, emails are hard to preview, a pain to debug, there are multiple ways to deliver them - do I need an SMTP server? - each email has text and HTML parts, and don't even get me started about styling emails and embedding CSS in a way that will work in all mail clients. Oof.
But then, out of the ashes of this ancient practice grew... a hero. Ok it's actually just a Symfony component - but a cool one! Enter Symfony Mailer: a fresh & modern library that makes something old - sending emails - feel... new! Seriously, Mailer actually makes sending emails fun again and handles the ugliest details automatically. Will you love sending emails after this tutorial? Yea... I think you kinda might!
Setting up the App
As always, unless you're just "mailing it in", you should totally code along with me. Dial onto the internet, download the course code from this page and unzip it with WinRAR 1.54b. Inside, you'll find a start/
directory with the same code that you see here. Open up the README.md
file to find all the setup details. The last step will be to open a terminal, move into the project and use the Symfony Binary to start a web server:
symfony serve
If you don't have the Symfony binary, you can grab it at Symfony.com/download. Once that's running, open your favorite browser - mine is Netscape Navigator - and go to https://localhost:8000
to see... The Space Bar! A news site for aliens... and the app that you probably recognize from other Symfony 4 tutorials here on the site.
In this tutorial, we'll be using Symfony 4.3. There are a few cool features that are coming in Symfony 4.4 and 5.0... but don't worry! I'll point those out along the way: they aren't big changes, mostly some nice debugging features.
Installing Mailer
Like most things in Symfony, the Mailer component is not installed by default. No problem, find your terminal, open a new tab and run:
composer require symfony/mailer
Notice that I didn't just use composer require mailer
... using the "mailer" alias. Remember: Symfony Flex lets us say things like composer require forms
or composer require templating
and then it maps that to a recommended package. But at the time of this recording, composer require mailer
would not download the Mailer component. Nope, it would download Swift Mailer... was was the recommended library for sending emails with Symfony before Symfony 4.3: that's when the Mailer component was introduced.
And even when you're Googling for documentation about Symfony's Mailer, be careful: you might end up on the docs for using SwiftMailer inside Symfony. The Mailer docs might be the second or third result.
Anyways after this installs, yea! We get some nice, post-install instructions. We'll talk about all of this.
The first step... is to create and configure an Email object! Let's do that next... then send it!
44 Comments
Thanks!
Hi, can I consider this video course valid for sy6? Or are there others you can point out to me? Thank you
Hey @pasquale_pellicani ,
Yes, this course is still valid for Symfony 6. Nevertheless the fact the course code is based on Symfony 4 it should still work on the latest Symfony version, but look closer for notes in the video/scripts - we usually add notes to the course if something was changed in the newer versions of it. And as always, if you get stuck following this course on a newer Symfony version - let us know in the comments below the video and our support team will help you.
Cheers!
wonderful, thanks @Victor for the quick reply ;)
Hello, can't find a way to use the course script:
when i run composer update, i get
<blockquote> Your requirements could not be resolved to an installable set of packages.</blockquote>
with several problems with included bundles: nexylan/slack-bundle,symfony/property-access
and when i try for exmple composer update nexylan/slack-bundle
I get the same error msg
and when i try composer update nexylan/slack-bundle --ignore-platform-reqs
I get Script cache:clear returned with error code 255
I also tried --with-all-dependencies, composer require nexylan/slack-bundle:2.3.0 , composer update "symfony/*" --with-all-dependencies , composer require doctrine/doctrine-cache-bundle --with-all-dependencies
nothing work
Is there an order in updating packages ?
Is there an updated version of this course ?
Hey mofogasy!
Sorry about the trouble! The content of this tutorial is still valid, but the code itself is showing its age :/. That's why, when you download the course code, we have a tooltip that mentions that it only works on PHP 7.
To get it work on PHP 8, it's likely tricky. The problem isn't the code in the tutorial itself... but just that you likely need to update a bunch of dependencies in order for those to be compatible with PHP 8. And if you do manage to update those... sometimes they differ from what we use in the tutorial. For me, doing the following... seems to work
- Run
composer require psr/cache:^1.0.0 --ignore-platform-reqs
- Update all symfony libs in composer.json from 4.3. to 4.4. (including the extra.symfony.require key)
- Run
composer up --ignore-platform-reqs
.
This, at least, seems to get the dependencies installed without any errors. So, no guarantees, but maybe this will help :).
Cheers!
Chiming in that steps 1 - 3 worked for me. 31 problems after
composer require psr/cache:^1.0.0 --ignore-platform-reqs
Just ignore them and push on to step 2.
Thanks for the detailed answer! that's nice.
Problem not solved yey though.
When I run composer require psr/cache:^1.0.0 --ignore-platform-reqs, I get some warnings about packages being abandoned then Executing script cache:clear [KO]
and Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Class "Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle" not found in C:\siteEcommerceApema\demo\envoiMail\start\src\Kernel.php
Since I want to use it as reference for my php 8 project, I d prefer stay with this version
Do you have another recent tutorial/project including mail sending ,please?
Hey mofogasy!
Sorry for the slow reply, and darn! I had tried those commands locally with PHP 8.1 and it worked fine for me :/. Unfortunately, we don't have any other tutorials that show sending mail. We just need to give this tutorial a "fresh up" at some point, though the fundamentals of sending emails haven't changed (it's just the darn, annoying old code :/).
Hi everyone,
How can I debug email with The SentMessage object and the TransportInterface provider ? the documentation doesn't say much .
Do you guys have an idea ?
Hey Mariem,
Here's a little info abotu debugging:
- https://symfony.com/doc/cur...
- https://symfony.com/doc/cur...
Also, all exceptions that implement TransportExceptionInterface has getDebug() method, see: https://github.com/symfony/...
It depends on what version of Symfony you're on, so this thread might be interesting for you as well: https://symfonycasts.com/sc... and thanks to this PR https://github.com/symfony/... MessageHandler now has return statement, i.e. you can get that SentMessage object from HandledStamp::getResult().
I hope this helps!
Cheers!
Hey,
How can i send auto email periodicly on production? Is messenger provide it without run any command or without cronjob?
Hey Joseph
If you don't want to send the email right away when you dispatch the event, you can create a DelayMessage with the amount of seconds you want it to be delayed
Check it out how to do so here https://symfony.com/doc/cur...
Cheers!
Thank you MolloKhan
Hi SymfonyCasts , when i upgrade the project which i build with you in the previous chapters to 4.3 , i lose the profiler (web Tool Bar) , this don't happen in 4.2 . (i want to continue on this project , i wish to not strat anothor one for the mailer) , Thanks.
Hi again , i deleted my previous vendor and composer.json with his lock , and used the one of this project , it worked after some modifications (The toolbar still here) , now i wonder should i learn webpack ENCORE first then move to the mailer or just learn the mailer then encore ?
Hey Ouahib,
I'm glad you were able to got it working, good job! Most probably it was some version incompatibilities.
> now i wonder should i learn webpack ENCORE first then move to the mailer or just learn the mailer then encore?
Great question! Actually, we made this course not much tight to Webpack Encore. So, if your main goal for now is to learn Mailer first - you're totally good to start it! We moved a few Encore-specific problems with Mailer right to the end of this tutorial to do not confuse users who do not work with Webpack Encore but give some advices and workarounds for those who do. You may watch this course at the end and if last chapters would be fuzzy for you - you can go watch a tutorial about Webpack Encore and then return back to re-watch those Encore-specific chapters again to get more clue.
And of course I would recommend you to watch Encore course as well later - this is an awesome tool!
I hope this helps!
Cheers!
Thank You Victor.
Hello SymfonyCasts,
I got this error, trying hard to resolve it but no success, can you please help?
C:\xampp\htdocs\finish>composer require symfony/mailer
Restricting packages listed in "symfony/symfony" to "4.3.*"
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.3.*"
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Conclusion: don't install symfony/mailer v4.3.9
- Conclusion: don't install symfony/mailer v4.3.8
- Conclusion: don't install symfony/mailer v4.3.7
- Conclusion: don't install symfony/mailer v4.3.6
- Conclusion: don't install symfony/mailer v4.3.5
- Conclusion: don't install symfony/mailer v4.3.4
- Conclusion: don't install symfony/mailer v4.3.3
- Conclusion: don't install symfony/mailer v4.3.2
- Conclusion: don't install symfony/mailer v4.3.1
- Installation request for symfony/mailer ^4.0 -> satisfiable by symfony/mailer[v4.3.0, v4.3.1, v4.3.2, v4.3.3, v4.3.4, v4.3.5, v4.3.6, v4.3.7, v4.3.8, v4.3.9].
- Conclusion: remove symfony/event-dispatcher v4.1.6
- symfony/mailer v4.3.0 requires symfony/event-dispatcher ^4.3 -> satisfiable by symfony/event-dispatcher[v4.3.0, v4.3.1, v4.3.2, v4.3.3, v4.3.4, v4.3.5, v4.3.6, v4.3.7, v4.3.8, v4.3.9].
- Can only install one of: symfony/event-dispatcher[v4.3.0, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.1, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.2, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.3, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.4, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.5, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.6, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.7, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.8, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.9, v4.1.6].
- Installation request for symfony/event-dispatcher (locked at v4.1.6) -> satisfiable by symfony/event-dispatcher[v4.1.6].
Installation failed, reverting ./composer.json to its original content.
C:\xampp\htdocs\finish>composer require symfony/mailer
Hey Dung,
Symfony Mailer is a new component that was introduced in Symfony 4.3. From the console output I suppose you have Symfony 4.1 installed. To be able to install and use Symfony Mailer - you will need to upgrade your Symfony application to version 4.3 at least. Then you should be able to install Mailer on it.
I hope it helps! If you're not on Symfony 4.1 but on Symfony 4.3 already and still have this problem - please, let me know!
Cheers!
Hello victor , I now thinking of upgrading my project to symfony 5 if possible from my current project Symfony 4.1.6 ? Or I will have to do incremental upgrade to 4.3 then 4.4 then version 5?
Can you also point to a preferable SymfonyCasts tutorial or a Symfony documentation that show how to upgrade to these specific version?
Best regards,
Dung.
Hey Dung,
Yeah, very good question! Well, at least you should update to the latest minor version, i.e. 4.4.x in your case. Then, fix all the deprecations you found in your code, and only then try to upgrade to 5.0. Btw, I'd recommend you to look at our new screencast course about how to upgrade to Symfony 5.0! Actually, we follow the exact this strategy there :) See https://symfonycasts.com/sc...
Good luck with upgrading!
Cheers!
Thank you Victor, I will give it a try.
Dung.
Hello victor
You are right that i am on
C:\xampp\htdocs\finish>php bin/console --version
Symfony 4.1.6 (kernel: src, env: dev, debug: true)
C:\xampp\htdocs\finish>
But can you tell me how you know that it is 4.1.6. I read the error message and for the life of me I will never understand it :) - a simple error but the message is so confusing!
Thanks!
Hey Dung,
Haha, I just noticed that "locked" version:
> Installation request for symfony/event-dispatcher (locked at v4.1.6)
So I supposed you're on 4.1 - it was that simple :p
Yeah, message is huge and probably confusing, but in general it says that Composer found out that you have some packages as your dependencies locked to versions that are not satisfied in order to install that "symfony/mailer" package. It mostly means that the new package you're going to install has the same dependencies but requires a newer version of them.
I hope it helps!
Cheers!
Hello victor ,
when starting up symfony server I get the below message, I am wondering if I should say yes to upgrade it to later version so that I can install "symfony/mailer" package? I really do not want to mess up my entire project by answering yes to upgrade to 4.11.3?
C:\xampp\htdocs\finish>symfony serve
Version 4.11.3 is available. Do you want to update now (execution will continue after whatever you decide) ? [Y/n]:
Best regards,
Hey Dung,
You're confusing this message a bit :) This message is from the Symfony CLI, i.e. it asks you if you want to upgrade the version of your Symfony CLI binary program, not about upgrading your Symfony application at all! I.e. this means even if you answer "Yes" - your Symfony application won't be upgraded and you won't be able to install Mailer yet. Basically, it equals to running the command "symfony self:update", that's it. To upgrade your Symfony application - you would need to upgrade your *Composer dependencies* instead.
Therefore, I'd recommend you to upgrade your Symfony CLI to the latest version because it won't affect your application at all... but it's totally not required though good to do.
I hope this is clear for you now.
Cheers!
Yup, thanks victor very much! Merry Christmas! :)
Hey Dung!
Merry Christmas to you too! :)
Cheers!
thanks for your explanation, i will keep learning ... :)
Hello !
It's me again, struggling with installation with PHP 7.4 ;-)
Well, this time the installation goes well with Composer, but when I try to load the Fixtures I get:
<blockquote>
In Parser.php line 3195:
Notice: Trying to access array offset on value of type null
</blockquote>
Running composer update
won't solve the issue, upgrading to Symfony 4.4 neither, I still get:
<blockquote>
Cannot autowire service "App\Repository\ApiTokenRepository": argument "$registry" of method "__construct()" references interface
"Symfony\Bridge\Doctrine\RegistryInterface" but no such service exists. Did you create a class that implements this interface?
</blockquote>
I changed the Repository classes constructor argument type hint to Doctrine\Common\Persistence\ManagerRegistry
which is the only one I found working but is marked as <b>deprecated</b> by PHPStorm. Using Doctrine\Persistence\ManagerRegistry
as recommended does not work.
Just sharing if it helps in any way !
Hey AymDev!
I know the first error :). It's because doctrine/annotations is not compatible with PHP 7.4 unless you have version 1.7.0 or higher. BUT, about a week ago, I made sure that this tutorial was updated. If you download the course code now, you will get doctrine/annotations 1.8.0. Do you get the error if you download the course code now and try the "start/" directory? Maybe you just downloaded it before I could fix the issue :).
The second error is caused by the composer update
which you shouldn't (if you have my fix above) have to run. Basically, it updates DoctrineBundle from version 1 to 2, which has some breaking changes in it. Specifically here: https://github.com/doctrine/DoctrineBundle/blob/master/UPGRADE-2.0.md#service-aliases - as you can see, it recommends to make the change you did - changing the type-hints from Doctrine\Common\Persistence\ManagerRegistry
to Doctrine\Common\Persistence\ManagerRegistry
.
So then, why is Doctrine\Common\Persistence\ManagerRegistry
deprecated? Sigh, that's because the doctrine/common
package is being "split" into smaller repositories. This is a great change - but a few things right now are in "flux". In fact, using Doctrine\Persistence\ManagerRegistry
instead WILL work, even though it's not documented in that upgrade file. You mentioned that this didn't work for you - but it should. You will need DoctrineBundle 2.0.3 or higher.
I hope that explains! Mostly, you should not have any issues right now if you download the start code in PHP 7.4. But now you have the whole story :)
Cheers!
Hey weaverryan !
Thank you for the detailed explanations !
Unfortunately I re-downloaded the course code, and only ran composer install --no-cache
, then ran DB migrations but got the same error during the fixtures loading.
I'm not sure if I did anything wrong. I'd be happy to help and investigate but I don't have that precious time at the moment :-(
Thank you for everything you do !
Cheers !
Hey AymDev
Let's try something quick, I believe you got a cached version of the course code because of your browser's cache. Check inside your composer.lock the version of doctrine/annotations
. It should be 1.8.0, if it's not, then I'm right and you will have to do a hard refresh on the page or clear your browser's cache for this site. If I'm wrong then, please check that you are using DoctrineBundle 2.0.3
If the problem still continues, please let us know.
Cheers!
Hello MolloKhan
I downloaded the course code with an other browser with which I never downloaded the Mailer course code (so... no browser cache this time ? Or I'm missing a point about that maybe).
I checked the composer.lock
and I always get doctrine/annotations v1.8.0
but I always get doctrine/doctrine-bundle v1.11.2
too which is wrong I guess.
If you see doctrine/annotations v1.8.0
then you got the newest code. About DoctrineBundle version, I'm not sure to be honest but if it's not working, you can try upgrading it to version 2 or just tweak the type-hint as you did before. I think it should do the trick
Hey AymDev
This is interesting. Can you tell me if it works on PHP7.3? I want to know if this has anything to do with PHP version
Cheers!
Hey MolloKhan
I used a new installation of your source code (see my answer to Ryan) where the Fixtures loading failed.
I tried loading them using a 7.3.12 binary: /usr/bin/php7.3 ./bin/console d:f:l
and it worked.
Cheers !
yeah, it's because of the bug the library has on PHP7.4. Please check my answer above :)
Hi Ryan
Can you please say me, how can I configure monolog to send emails about errors via Symfony Mailer
Hey @Andranik!
Sorry for the slow reply. Mailer support in Monolog has not been merged yet - we were hoping it would happen for Symfony 4.4 (that was the cause of the delay), but it wasn't quite added in time. Here is the pull request: https://github.com/symfony/symfony/pull/33456
So, right now, it's not currently possible, unless you write your own custom handler. Actually, you could adapt/use the handler from that pull request. Here is what the codeconfig would (probably) look like - apologies if I get a detail wrong!
1) Copy the MailerHandler from the PR into, for example, a src/Logger/MailerHandler.php file (and update the namespace)
2) Modify the class. Instead of accepting a $messageTemplate
2nd argument, remove it. Instead, in the constructor,
set the property to some new Email
(or TemplatedEmail
) object:
public function __construct(MailerInterface $mailer, int $level = Logger::DEBUG, bool $bubble = true)
{
parent::__construct($level, $bubble);
$this->mailer = $mailer;
$this->messageTemplate = (new Email())
->from(...)
->to()
->subject('Error on the site!');
}
4) Configure as a handler
# config/packages/prod/monolog.yaml
monolog:
handlers:
# ...
my_mail_handler:
type: service
id: App\Logger\MailerHandler
That should be it - but I'm filling in some of the details right here in the comment box without trying them. So let me know if you run into any issues ;).
Cheers!
Hi Ryan, Glad this tutorial is coming up:)
Just a quick note: at 2:39, we didn't install the self-signed certificate of the Symfony binary, there is a problem to display the images on the website.
I added a .env.local file and overloaded the environment variable: SITE_BASE_URL.
Note: I don't know if SSL is a necessary condition to follow the tutorial.
Thank you, for the good work you did!
Hey Cedruyne!
Glad this tutorial is coming up:
Me too! :)
I added a .env.local file and overloaded the environment variable: SITE_BASE_URL.
Hmm, yes, this was a perfect workaround. If you don't install the SSL cert with the binary (which is totally fine), then indeed, your images won't be displayed until you set SITE_BASE_URL=http://localhost:8000
in .env
or .env.local
(notice no "s" in http://). Thanks for the comment - this has tripped a few people up in other tutorials!
Cheers!
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"aws/aws-sdk-php": "^3.87", // 3.110.11
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.1
"doctrine/doctrine-bundle": "^1.6.10", // 1.11.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.7.2
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.1
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-snappy-bundle": "^1.6", // v1.6.0
"knplabs/knp-time-bundle": "^1.8", // v1.9.1
"league/flysystem-aws-s3-v3": "^1.0", // 1.0.23
"league/flysystem-cached-adapter": "^1.0", // 1.0.9
"league/html-to-markdown": "^4.8", // 4.8.2
"liip/imagine-bundle": "^2.1", // 2.1.0
"nexylan/slack-bundle": "^2.1,<2.2.0", // v2.1.0
"oneup/flysystem-bundle": "^3.0", // 3.1.0
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.1
"sensio/framework-extra-bundle": "^5.1", // v5.4.1
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.3.4
"symfony/console": "^4.0", // v4.3.4
"symfony/flex": "^1.9", // v1.21.6
"symfony/form": "^4.0", // v4.3.4
"symfony/framework-bundle": "^4.0", // v4.3.4
"symfony/mailer": "4.3.*", // v4.3.4
"symfony/messenger": "4.3.*", // v4.3.4
"symfony/property-access": "4.3.*", // v4.3.4
"symfony/property-info": "4.3.*", // v4.3.4
"symfony/security-bundle": "^4.0", // v4.3.4
"symfony/sendgrid-mailer": "4.3.*", // v4.3.4
"symfony/serializer": "4.3.*", // v4.3.4
"symfony/twig-bundle": "^4.0", // v4.3.4
"symfony/validator": "^4.0", // v4.3.4
"symfony/web-server-bundle": "^4.0", // v4.3.4
"symfony/webpack-encore-bundle": "^1.4", // v1.6.2
"symfony/yaml": "^4.0", // v4.3.4
"twig/cssinliner-extra": "^2.12", // v2.12.0
"twig/extensions": "^1.5", // v1.5.4
"twig/extra-bundle": "^2.12|^3.0", // v2.12.1
"twig/inky-extra": "^2.12", // v2.12.0
"twig/twig": "^2.12|^3.0" // v2.13.1
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.2.2
"easycorp/easy-log-handler": "^1.0.2", // v1.0.7
"fzaninotto/faker": "^1.7", // v1.8.0
"symfony/browser-kit": "4.3.*", // v4.3.5
"symfony/debug-bundle": "^3.3|^4.0", // v4.3.4
"symfony/dotenv": "^4.0", // v4.3.4
"symfony/maker-bundle": "^1.0", // v1.13.0
"symfony/monolog-bundle": "^3.0", // v3.4.0
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.3.4
"symfony/stopwatch": "4.3.*", // v4.3.4
"symfony/var-dumper": "^3.3|^4.0", // v4.3.4
"symfony/web-profiler-bundle": "4.3.*" // v4.3.4
}
}
Finally some quality videos