This Is What My Brother Found When Trying Symfony

My brother recently tried to get up and running with Symfony. His theory was that learning Symfony (out of all the available PHP frameworks) seemed like a good idea, being that he could ask me questions as and when he got stuck.

I anticipated that he would have problems with the “typical” problem areas:

  • Security
  • Forms
  • Database interaction

And maybe, given it is his first time using the MVC pattern, some of the concepts around that area, too.

What I didn’t anticipate was that he couldn’t even get started.

He experienced so many issues with installing Symfony, that after a couple of hours effort – with essentially nothing to show for it – he gave up.

I could sense his frustration.

Here’s a guy who spends all day working with PHP (mainly WordPress I believe), and after 8+ hours at his desk, he comes home, grabs a bite to eat, and tries to improve his dev chops by learning about Symfony.

For most of us, time is extremely limited, and spending two hours sat at home after doing 8 or more at your desk is a pretty big ask.

To come away with nothing (except a bad experience) is, understandably, enough to put him off.

What follows may appear heretical:

I suggested he try Laravel.

The next evening he did, and was up and running in less than ten minutes.

This got me to wondering just how many others are suffering from a similar fate?

I am well aware that Symfony has a steep learning curve. Laravel does too, if you are brand new to modern PHP practices.

What I hadn’t factored in was just how difficult it is to get the “hello, world” of Symfony up and running.

Coincidentally, around the same time I got an email from a site member (thank you Parminder) stating the following:

Please note that I am not a php developer and I haven’t dabbled at all with it beyond setting up the server to work with the react/redux/sagas project on your site. I think it would be useful to include instructions in the intro to the course on setting up the server for someone who is not familiar with Symfony/backend and just wants to focus on the React/Redux material – this would probably help with course uptake I think.

And in response to my reply, Parminder also shared the following:

It did take me a while to set up the Symfony server for the course on my mac and it no doubt is a barrier for people taking up your course, which is a shame because your material is very good.

Ok, so after I had told Mr Worf to stand down from Red Alert, I started to give this problem some serious thought.

Firstly, up until very recently I had not envisaged anyone who isn’t a PHP developer would join the site.

I’ve been proven wrong on this point.

Secondly, I have seemingly forgotten to cover a fundamental part of working with Symfony – getting set up.

I’m going to remedy this with a forthcoming video series. I will try and cover set up from the three major operating system variants – Windows, Mac, and Linux.

I will offer some suggestions as to how I’ve worked, and touch upon Vagrant, Ansible, and Docker.

Another really good suggestion that I’ve had from Parminder is to spin up a standalone server which none-PHP devs, or those who do not wish to spend the time doing all the setup themselves, can access my server instead. This would likely be on a 24 hour cronjob to reset the DB, or similar. This is something I will implement moving forwards.

It pains me that Symfony is potentially losing new devs at the very top of the funnel. There’s so much good stuff to be had from using the Symfony framework. I’m not just talking about developer productivity, but the wider benefits like:

  • a well paying job
  • an enjoyable and (generally) intuitive stack to work from
  • a community filled with incredibly smart and friendly folk

I’ve said before that learning Symfony has changed my life (and yes, for the better :)), and it’s part of my mission to share that same joy with you.

I’d love to hear your experiences of what it was like getting started with Symfony.

Was there a specific issue you hit upon?

Has this process improved as you’ve used Symfony more and more, or is the pain still there?

Please hit reply and let me know.

Video Update

This week saw three new videos added to the site.

We are coming to the end of the first phase of the Wallpaper Website.

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/doing-the-little-before-the-big

Firstly we start by cleaning up our project.

Swapping and changing between branches in order to see how to write code with and without tests starts off fairly easy, but as the underlying design diverges, the setup (fixtures etc) need altering in differing ways for both branches.

There’s other stuff to cover here, too, such as the naming of files (and associated tests). It sounds almost trivial, but I’m sure you’ve experienced occasions when writing code where the names of things has started to feel… not quite right 🙂

Housekeeping is an important, if underappreciated aspect of the lives of us as developers.

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/tested-image-preview-sort-of

In the un-tested approach we added in a nice little preview snippet which allowed us to see our existing uploaded wallpaper image when going to the Update screen.

We’re going to add the same functionality into our tested version, but we won’t be able to directly test the template. Is this a problem?

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/finishing-up-with-a-tested-wallpaper-update

Finally we wrap up the test-driven approach to Wallpaper Updates. We cover not just the “happy path”, but two potential sources of bugs in our form setup.

This is really the major benefit of writing tests, as far as I am concerned. They make you think about the bad times as much as the good. It sounds very pessimistic, but 80% of the headaches I have as a developer stem from having not given enough thoughtful consideration to what might happen if things don’t go according to plan.

All we have left to do now is add in a tested approach to Deleting wallpapers (and their associated uploaded image files), and adding a little security. After all, we don’t want just any Tom, Dick, or Harry accessing our Admin panel.

That just about wraps up this week’s update. Thank you very much for reading, and I hope you have a great weekend.

Until next week, happy coding,

Chris

Software Development Is Not Beginner Friendly

As we are coming to the end of the first part of the Wallpaper Website tutorial series, I wanted to quickly reflect on a bit of feedback I’ve had regarding these videos.

The gist of this feedback was that I had miss-sold the course as being “beginner friendly”, when in fact, it has been quite a tricky course.

Here’s my view point, and as ever, feel free to disagree:

Software Development is hard.

There are two approaches I could take:

  1. Show you abstract examples where I cover concepts on an individual basis.
  2. Show you a complete, working example and all the things that getting to a “working” state entail.

My life would be easier if I opted for #1.

However, in my opinion, I would be misleading you if that’s all I showed you.

I’ve been writing software for over 15 years now, and I still regularly underestimate just how much effort is required to go from the idea phase through to “phew, it’s finally online” phase.

And as I’m sure you know, even once it’s online (or launched), it’s not done. Far from it. If anything, that’s where the real work actually begins.

Working in software development in 2017 is hard. There are a ton of things to cover. This series has been about the more traditional approach – using Symfony (or PHP) for everything, front end and back end.

In reality, and as we push further into the second and third parts of this series, to become the most employable and to stand out from being “just another dev” you will need to know more than just Symfony (or PHP). You almost inevitably will need to be decent at JavaScript, too.

Does this make the series harder? Yes, unfortunately.

Is this still stuff a beginner needs to know? In my opinion, yes.

There’s no point in just showing you what I consider the old school approach. At least, not unless all you ever want to do is build old school style websites.

My guess is that you want to make websites – or web-based applications – like those that you typically interact with in 2017.

Can PHP – and more specifically, Symfony – get you to this point?

Yes. But only half of the way there.

The other half needs to be done in JavaScript.

In other words, Symfony for your back end, and JavaScript for the front end.

Which brings me back to the original bit of feedback that this course is not beginner friendly.

I would argue that the industry is no longer beginner friendly.

There is an immense learning curve to simply getting started.

Fortunately, once you are over the initial hump, things do get a bit easier.

This isn’t a problem unique to software development. Many industries expect you to have a very broad and general level of knowledge before specialising in a particular area.

That’s my opinion on the subject. As ever, please do feel free to hit reply and let me know yours. I’m not saying I’m always right by any means, and I am not averse to having my view points challenged 🙂

Follow Up From Last Week

Last week I posed a couple of questions in my “Would you use Symfony for SaaS?” post:

  1. How many other developers are using Symfony for SaaS, or SaaS-like services?
  2. Is Stripe / payment integration something that many other devs want or need tutorial content on?

Firstly, thank you to everyone who replied. I really appreciate you taking the time to respond.

I have learned that the majority of you are not using Symfony to build your own SaaS, or SaaS-like service.

This is useful to me as it helps shape the content I aim to produce.

Even though most of you are not doing SaaS related stuff, the payment integration video idea does seem popular.

As such, I have added a payment integration course to the ToDo list. This will cover not just Stripe but also Braintree (aka PayPal), and all the fun that supporting multiple providers entails.

Video Update

This week saw three new videos added to the site.

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/adding-an-image-preview-on-edit

As mentioned earlier in this series, there is a way to integrate with VichUploaderBundle when working with EasyAdminBundle.

In doing so, one of the nice ‘bonus’ features is the image preview when viewing an existing entity with an attached image file.

In this video we look at a way to recreate this in our own implementation. It’s easier than you might think, and gives us a good opportunity to explore some of the less frequently used parts of Symfony’s form component.

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/delete-should-remove-the-wallpaper-image-file

One problem that’s been bothering me throughout this series is that when recording the videos I will do some uploading of images, and then delete the Wallpaper entity, but the image file I uploaded still remains on disk.

To fix this we can copy a process we’ve covered for both Create and Update – which is to say we can listen for a different Doctrine event, that of preRemove.

As we might be changing over to use a different storage mechanism in the longer term (think: Amazon S3, not storing everything on the server’s local hard disk), we also need to abstract away exactly how an image file is deleted.

We will no doubt revisit this (or a variation of this) during our test-driven approach.

https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/getting-started-testing-wallpaper-updates

Speaking of tests, in this first video of the final part of this series, we are switching back to our test-driven approach and beginning the re-implementation of our Wallpaper Update and Delete features.

As ever, thank you very much for reading, have a great weekend, and happy coding.

Chris

What happens to your design if you don’t use TDD?

In this week’s videos we are exploring TDD in PHP from an angle I’ve never seen covered before in other online tutorials.

To set the scene, we are adding File Upload to our EasyAdminBundle backend.

As this is a beginner friendly series, I am fully aware that adding tests – specifically PhpSpec – into the mix alongside all the other “stuff” we need to know to work effectively with Symfony can be a little overwhelming.

I said last week how I think testing is one of the most effective ways to improve yourself as a software developer. I stand by that.

However, there’s a hurdle with testing that’s seldom addressed:

How can I write code with tests if I don’t understand how to write the code without tests?

Ok, so to be absolutely clear here, I’m not talking about syntax. At this stage I am assuming you have a grasp of the fundamentals of PHP and are interested in expanding your knowledge into learning Symfony.

What I’m talking about here is how to write tests for everyday workflows inside your Symfony applications.

When starting with Symfony it can certainly feel overwhelming enough just to get a few forms up and running. Throw in saving your form data off to the database, and you might need a long lie down.

And yet now I’m saying hey, let’s learn how to write tests for all this jazz!

I’ll let you in on a little secret:

I was not planning on showing you any of this 🙂

When I started out writing up this series, I built out the prototype and was happy with the outcome.

When I started recording the videos I realised that I had bumped up the difficultly significantly about 50% of the way through the course. This was because of the inclusion of tests.

When coding up the prototype I had gone head down into “code mode”. I’d implemented a working, and tested upload system but the outcome would be really hard to explain without a lot of additional context.

At this point I had to make a decision. The outcome of that decision was to alter the course to show how I ended up with the test-driven outcome.

To get to this outcome it makes most sense to show how to write this code without tests.

In doing so, we will see one method of achieving out goal: a working Wallpaper file upload process.

However, back in the real world, doing this would fall quickly under the “technical debt” category.

The idea of this site is that it’s the real deal – a hobby site maybe, but a real, working website.

As administrators we would like to be able to log in to our site, add new wallpapers, see stats and stuff like that. These sorts of things keep our momentum going to add new features and keep improving the site. I find this is the best way I continually improve myself as a software developer.

Taking this further, it makes sense that as-and-when our wallpaper site becomes popular (hey, we can dream!) we will likely want to be adding new wallpaper content on a regular basis.

This means our Wallpaper file upload form is going to be getting battered.

Taking this from a different angle, you likely have code on other projects that is equally frequently used.

This kind of code absolutely needs to work, or you will be sat in the pub and your phone will ring and your boss will be angry as his / her client is angry. And that spoils your otherwise enjoyable life experiences.

but it was working when I left the office…

When I encounter code like this, I immediately reach for the test suite. It’s the insurance policy that keeps my phone from ringing, and ensures my pub visits are interruption free.

But stepping back into our application, we have our Symfony site as a whole, and then EasyAdminBundle where we need to start adding in this additional functionality.

The chances are, if we’ve never used Symfony, or never used EasyAdminBundle, or both, then we have no experience even doing this “the easy way”. That is to say, we have no idea how to do this without even worrying about writing tests.

It’s a big ask to correctly figure out all the requirements in advance to the point where we can write a bunch of failing tests that when passing would work as a file upload system. At least, it is in my opinion.

So here’s what I do in real life: I cheat.

I don’t bother with tests.

I create a new branch in git, and then I hack around until I have a solution that generally works. This can take minutes, hours, or sometimes days and weeks.

Going back to our wallpaper file upload, I would code up a solution that allows me to add, edit, and delete files. It very likely wouldn’t be pretty, but that doesn’t bother me.

What this does is it gives me the knowledge of how – roughly – this whole thing should work.

From here, I can switch back to master, create another new branch, and have another bite at the cherry – only this time, I have a starting point from which I can write some tests.

I will usually refer back to the untested implementation a bunch of times, and being able to switch branches and play about with some working code is often a massive help in defining assumptions and crafting test assertions.

And so, that is what we are doing in this – and next – week’s videos.

First, we are exploring how to simply get EasyAdminBundle file upload working.

Then next week we will re-do the implementation but using PhpSpec to guide us.

Until then, thanks for reading, have a great weekend and happy coding.

Chris

10 Tips For Better Symfony Debug Logs with Monolog 

I can’t quite believe it’s over a month already since Christmas day. Although I only need to step outside for a few moments to wish it was Summer already. I’m much happier coding in my shorts and t-shirt.

A number of people have asked for a suggested watching order / learning track, and with 50 courses to choose from, I can totally understand it can be hard knowing where to start. With this in mind, I’ve added a Learning Tracks page to the site.

This week saw three new videos added to the site.

https://codereviewvideos.com/course/react-redux-and-redux-saga-with-symfony-3/video/testing-javascript-s-fetch-with-jest-happy-path

Firstly we cover testing JavaScript’s Fetch, the nicer replacement to XMLHttpRequest. It baffles me why XML is uppercase, but Http is title cased. Anyway, fetch is nice to use, but testing can still be a little tricky.

To begin with, we cover the happy path, which gets our setup code out of the way. Seeing how things work when the everything is right in the world is a great way to start. But of course, once real users start tinkering with our systems, inevitably they will find new and baffling ways to destroy our good intentions. Which is why…

https://codereviewvideos.com/course/react-redux-and-redux-saga-with-symfony-3/video/testing-javascript-s-fetch-with-jest-unhappy-paths

We also need to cover the “unhappy paths”. And in this case, testing that our code throws the expected exceptions is a little trickier than you might expect. It’s one of those problems that you might estimate at taking you a morning, but end up losing two days too – never fun explaining that in the daily stand up.

Fortunately help is at hand, and we will use a small snippet of code to ensure testing when things go wrong is that much easier.

When it comes to tracking down errors, of course it’s not just the client side that can go wrong. If you’ve worked with Symfony beyond the most basic of applications then more than likely you will have needed to log out additional information to help you debug. Monolog is the fantastic out-of-the-box logging solution in Symfony, and so…

https://codereviewvideos.com/course/log-log-it-s-better-than-bad-it-s-good/video/10-tips-for-a-better-symfony-debug-log 

In this video we look at 10 ways to improve your Symfony debug log output by making use of a variety of options and techniques that Monolog gives to us.

We start off with the basics here, but quickly cover the handler stack – including the rather brilliantly named fingers_crossed  handler, which you will have seen in config_prod.yml  – then onto channels, logging from console commands, and also how to log out to Graylog.

This video will be free to watch until next Friday, so be sure to set aside 10 minutes for this one.

Lastly, did you know you can keep track of the latest videos via an RSS reader? I have a full feed available to ensure you never miss a video.

Until next week, take care, and happy coding.

Chris

How I Fixed: CSRF Token Is Invalid

There’s an obvious fix, and a not so obvious fix to this problem – The CSRF Token Is Invalid. Please try to resubmit the form:

The CSRF Token Is Invalid. Please try to resubmit the form.
pesky.

The ‘obvious’ fix is that you may very well have forgotten to add in:

{{ form_end(yourFormNameHere) }}

To your twig form template file.

It’s easy to do, and we’ve all done it.

You may see this as:

{{ form_rest(yourFormName) }}
{{ form_end(yourFormName) }}

Also, but as of Symfony 3 at leastform_rest is now added in to form_end for free. It may have arrived earlier, but it’s late now, and I’m too tired to check.

Anyway, if that all works then perfect, and off you go.

However, the less obvious problem might be that your session directory is not writable by the web server user.

This just caught me out when setting up a new server.

I’d used Ansible to build my dev server, and then I’d also deployed a variant of my dev script to production.

However, somewhere along the way I’d boobed and created myself a var/sessions directory, and also a shared/var/sessions directory, and whilst the permissions where correct on one, they weren’t correct on the right one :/

Why might this be the case? Well, I deploy using Deployer, but I’d only just set that up to deploy to prod. During dev I simply work on the local VM – no deploy script needed. And at this stage I don’t have a staging box for  this project.

So yeah, make sure that whatever user your web server is running as – www-data in this case – also has permissions to write to whichever directory you are storing your session data in.

You can find this directory by looking in config.yml :

framework:
    # snip
    session:
        # http://symfony.com/doc/current/reference/configuration/framework.html#handler-id
        handler_id:  session.handler.native_file
        save_path:   "%kernel.root_dir%/../var/sessions/%kernel.environment%"