How I Fixed: argument “$entityManager” of method “__construct()” references class “Doctrine\ORM\EntityManager” but no such service exists

Ok, mega crazy title. And honestly, this is just the tip of the iceberg. Allow me to set the scene:

Lately I have had email conversations, read threads on hackernews, and even had a forum post challenging how and why I do things the way I do.

The summary of the email conversations being why I persist with Symfony / PHP generally, when other, “better” solutions exist. And the same can be said for the linked forum post.

And then yesterday I saw that linked Hacker News thread:

It was at about ~320 comments when I read it. The top reply was the most interesting for me:

There’s a bit more to it than that, and the thread itself is worth a read. There’s basically 400+ different suggested ways to “get a web app up quickly in 2018”. I’d disagree with a bunch of them, but then, they are the way I do things.

Wait, what?

Yeah, I’d disagree with Docker + Ansible + Terraform + nginx + (Symfony/Rails/Go/etc) + Postgres, etc, being quick to get up and running.

Sure, once you know the drill / have projects to copy / paste from, it can be quick, relative to the first time you had to learn and implement all this stuff. But it’s not quick quick. It still takes me ages.

And so I challenged myself: Just how quickly could I get a typical project up and running for myself? The perfect question for a Saturday night.

My Setup

The setup I most typically use is:

  • Terraform for spinning up a server
  • Ansible for prep’ing the box
  • Docker for running stuff
  • GitLab for code hosting + CI
  • nginx for my web server
  • Symfony / PHP 7 for the code
  • Postgres for the DB

This is a lot of stuff, and it’s not super quick to set up.

This is why I started by mentioning the email / forum conversations whereby people ask: is Symfony / PHP the best tool of choice?

Well, maybe not. I don’t know. I just know I’m more productive with Symfony and PHP generally than everything else – though JavaScript is a close second.

Over the past few years I’ve tried other setups. It’s hard to invest time in learning another stack when the end result may be basically identical – what did I gain from the time invested? Could that time have been better invested elsewhere? Hard questions to answer.

But yeah, Node and more recently, Golang have been stronger contenders than usual for my attention. Anyway, that’s a bit of a digression.

The Problem

As mentioned above, that’s my stack. Learning it all took ages (years?), but as each project is, from an infrastructure point of view, very similar, I can now spin up a new environment very quickly.

My challenge was to find out how quickly. I got most of the core stuff up and running in ~1.5 hours.

I didn’t get the Behat testing environment set up in that time. Because I hit on an issue.

I wanted a simple JSON API as the outcome of this process. By simple I mean basically CRUD.

With the basic stack up and running, I created a basic entity (one property), and updated the DB accordingly. Doctrine was used for DB interactivity. Again, very typical for my projects.

In order to get data out of my repo, I needed to create a repository. There’s an awesome post on this by Tomas Votruba called How to use Repository with Doctrine as Service in Symfony.

As a side note here: if you haven’t already, I would highly recommend reading Tomas’ blog, as it’s jam packed with things you’d likely find very useful and interesting. Also, check out his GitHub projects, with Rector in particular being incredible.

I followed the linked article, and hit upon the following:

What was weird to me at this point is that I’ve followed this article before, but never hit upon any problems.

Anyway, I did as I was told – I switched up the code to reference the EntityManagerInterface instead:

This is a really simple class.

For complete clarity, here’s basically the rest of the app at this point:

And the entity:

This is basically a generated entity with a couple of tweaks. It’s not the final form, so don’t take this as good practice, or whatever.

The purpose of what this class is supposed to do is also not relevant here, but will be discussed in a future video.

Anyway, the problem is evident in the code above. If you can spot it, then good stuff 🙂

If not, keep reading.

So with three records in the DB, all the connectivity setup, things looking decent, I sent in a request to my only endpoint – GET /.

And it didn’t work. I hit a 504 Gateway Timeout  error from nginx.

Very confusing, overall. I mean, this is basically copy / paste from a different project that works just fine. Only, I’ve renamed the project name. What the heck?

I hit refresh a few times, you know, to make sure the computer wasn’t lying to me. And then everything started going unresponsive. Very odd. I’ve just bumped the system from 16gb to 32gb, and all I have is a few Docker containers running, a browser with admittedly too many open tabs, and one instance of PHPStorm. Surely this couldn’t be taxing the system. htop  told me a different story:

Yeah, I know, that swap size is ridiculous. Forgive me.

The nginx logs weren’t really that helpful. I needed to look at the PHP log output, which in this case is achieved via docker logs :

Line 23 of  TemporaryEmailRepository  is:

I mucked around a bit, trying out injecting the ObjectManager instead, but hit the same issue.

Then I wondered if it was the act of injecting itself, or actually using the injected code (durr). So I commented out the call:

Reloading now, I was no longer seeing the massive RAM spike, and looking at what that call was doing pushed me down the right lines.

I’ll admit, it took me a much longer amount of time than I’d of liked to realise my mistake:

Now, I’m not 100% certain on the conclusion here, but this is my best guess.

I believe I had created a circular reference. I’d injected the Entity Manager into the repo. Immediately I’d asked for the entity. The entity has an annotation pointing at the repo, which triggered the endless loop.

Anyway, removing the repositoryClass attribute fixed it up. Kinda obvious in hindsight.

The Conclusion

I’m convinced I could get an environment up faster than this. Without hitting this issue I believe I would be at the ~2 hour mark to go from idea to having a solid setup that’s good to write code in a sane, reproducible, reliable / testable way.

I think back to 10+ years ago, where I’d be up and running so much faster. PHP is essentially a scripting language. With shared hosting, you’d have the DB ready, the web server ready, you just needed to write a bit of code, connect to the DB, push the code up somehow (FTP :)) and bonza, you’re up and running.

Looking at that way now, I’m amazed how far I’ve come. There’s a massive overhead with using frameworks – time spent learning (which never stops, unless your framework of choice goes EOL), patching, managing all this stuff, learning new ways to make things better… is it all worth it? I think so.

I think the biggest takeaway for me lately is that whilst within the last ~5 years I’ve shipped a lot less code to prod than in the 5 years preceding this, the code I do ship is more stable, and maintainable.

Nagging in my mind, however, is that what’s the point in this slow, methodical approach if the end result is it takes so long, I either don’t bother with entire ideas, or by the time I’ve shipped them, I’m so burned out by the seeming complexity of the whole thing that I lose interest in taking them further.

Anyway, I appreciate this is half helpful, half rant. I just needed to blog it and get these thoughts out of my head.

The 2018 Beginners Guide to Back End (JSON API) + Front End Development

It’s been a few weeks in the making, but I am happy now to reveal my latest course here on CodeReviewVideos:

The 2018 Beginners Guide to Back End (JSON API) + Front End Development.

This course will cover building a JSON-based API with the following back-end stacks:

  1. ‘raw’ Symfony 4 (PHP)
  2. Symfony 4 with FOSRESTBundle (PHP)
  3. API Platform (PHP)
  4. Koa JS (JavaScript / node)

Behat will be used to test all of these APIs. One Behat project, four different API implementations – in two different languages (PHP and JS).

We’re going to be covering the happy paths of GET , POST , PUT , (optionally) PATCH , and DELETE.

We’ll also be covering the unhappy paths. Error handling and display is just as important.

Where possible we’re going to try and use just one Behat feature file. It’s not always possible – the various implementations don’t always want to behave identically.

There’s a ton of good stuff covered in these videos. But the back end is only half the battle.

Whether you want to “catch them all”, or you’re working with a dedicated front-end dev, it’s definitely useful to know the basics of both.

With that in mind, you can pick and choose whether to implement the back-end, or front-end, or both.

If you don’t want to implement a back-end yourself, cloning any of the projects and getting an environment up and running is made as easy as possible by way of Docker. But you don’t need to use Docker. You can bring-your-own database, and do it that way, too.

The Front End

Whatever back end you decide to spin up, the front end should play nicely.

We’re going to implement a few different front-ends. The two I’m revealing today are:

  1. ‘raw’ JavaScript
  2. React

I have plans for a few others, but each implementation is a fair amount of work and I don’t want to over promise at this stage. There’s definitely at least two more coming, but let me first get these two on the site 🙂

The raw JavaScript approach aims to show how things were in the ‘bad old days‘. The days before your package manager  would take up ~7gb of your hard disk with its cache  directory.

The benefit of working this way is that there’s really no extra ‘stuff’ to get in the way. We can focus on making requests, and working with responses.

But that said, this is 2018 and the many modern JavaScript libraries and frameworks are fairly awesome. You’ll definitely get a renewed sense of appreciation for how much easier your life is once you’re comfortable using a library like React, after having done things the hard way.

Again, as mentioned we will cover more than just raw JS and React. Currently each implementation is between ten and fifteen videos. Each video takes a couple of hours to write up, and another couple of hours to record on average. I’m going as fast as I can, and will upload and publish as quickly as possible.

You can watch them as they drop right here.

Site Update

Behind the scenes over the past 10 weeks I have been working on integrating CodeReviewVideos with Braintree.

This is to enable support for PayPal.

I tried to create a ticket for everything I could think of ahead of starting development.

And I added a new ticket for any issue I hit during development. I’m not convinced I tracked absolutely everything, but even so I completely underestimated just how much work would be involved in this feature.

Being completely honest, I have never been more envious of Laravel’s Spark offering. For $99 they get Stripe and Braintree integration, and a whole bunch more. Staggering.

There’s a bunch of other new and interesting features in this release.

I’ve taken the opportunity to migrate from Symfony 3 to Symfony 4 for the API. There’s a bunch of new issues that arose during this transition – I hadn’t given it much prior thought, but with the new front controller ( public/index.php) totally broke my Behat ( app_acceptance.php) setup.

This work is also enabling the next major feature which I will start work on, once PayPal is live. More on that in my next update.

I appreciate that from the outside looking in, there doesn’t seem to have been a great deal of activity on the site over the last few weeks. I can assure you that behind the scenes, there has never been more activity.

Have A Great Weekend

Ok, that’s about it from me for the moment.

As ever, have a great weekend, and happy coding.

p. s. – I would be extremely grateful if you could help me spread the word by clicking here to tweet about the new course.

The First Symfony 4 Tutorial Is Here

This week saw six new videos added to the site.

These are the final four in the Docker Tutorial for Beginners series, and the first two in the Beginners Symfony 4 Tutorial series.

A tutorial on Symfony 4 has been highly requested since it released on 30th November 2017.

Since then we’ve had three patches, so we’re now on Symfony 4.0.3.

Have you tried it yet?

I Had My Doubts

I will be completely honest, for the longest time Symfony 4 scared me.

We switched from the Symfony 2 / Symfony 3 Standard Edition, to the Symfony 4 skeleton. From a nice “full stack” to a minimal, bare bones starting point.

The first time I used Symfony 4, I just couldn’t wrap my head around why they would remove most of the very useful things:

  • Monolog
  • Twig
  • Routing…

And then the more I read, the more I thought that the symfony/skeleton was taking Symfony to become a replacement Silex. And whilst I have used and quite like Silex, I preferred the Symfony Standard Edition / full-stack approach.

I also went into a panic as I thought pretty much everything on the CodeReviewVideos.com would be obsolete.

Moar Skellingtons

Thankfully, all my fears were eliminated when they released the  symfony/website-skeleton.

For me, this is perfect.

All the benefits of why I use Symfony for all my web projects, with all the added new features and bug fixes.

And a bare bones edition for my command line apps.

My Favourite Video

Even though this is a Symfony 4 beginners series, the last two videos get a little geeky. I can’t help myself.

There’s a really interesting change in Symfony 4 with the way we use controllers.

It’s useful to know as a beginner, and hopefully it sparks your curiosity into knowing more about the “how” and “why” of Symfony generally.

This one should be useful even if you’re not a beginner.

Other Stuff

There’s a lot of other change in progress at the moment, particularly on the back end of the site.

I’ve been putting some of the front end tweaks live this morning, and these take on board the suggestions I’ve had from site visitors. Thank you for all your feedback I really appreciate it.

There are still 15 or so videos to come from this batch. I’m currently taking a break from editing to write this.

Ok, on that note, have a great weekend, and happy coding.

Chris – CodeReviewVideos.com

Merry Christmas and a Happy New Year for 2018

This is the last you will be hearing from me – newsletter wise, at least – for 2017.

With that in mind I’d like to take this opportunity to say firstly a very big and sincere thank you to you for your support this year.

Whether your are a subscriber currently, have subscribed to the site in the past, or will be subscribing in the future, your support means a lot to me.

I’m really pleased with how things have progressed with CodeReviewVideos.com this year.

I launched the new site version, which whilst still a work-in-progress (and likely always will be) now is in line with almost everything new I’ve learned in the last four years.

I share everything I know on CodeReviewVideos.com, and from the feedback I’ve had this year (thank you!) I know it’s really helpful to many of you, too.

This site is all about saving you weeks, months, or even years off the amount of time it takes to learn a framework as big and (potentially) complex as Symfony.

There’s other great stuff on here too, like learning how to use Docker in the real world, and another of my personal favourites, React with Redux and Redux Saga all connected to a Symfony JSON API.

Video Update

This week saw three new videos added to the site.

#1 – Fixing Third Party Bundle Deprecations (Indirectly)

We’ve fixed the issues with Symfony’s code.

We’ve fixed the issues with our own code.

Now we must fix the issues with any third party bundles we are using.

In our case we have just one bundle – eightpoints/guzzle-bundle.

The issue we have is fairly common. If a bundle you use adds ‘stuff’ to the sidebar in the profiler, then you are almost certainly going to need to fix this issue. Well, I say you. What I really mean is you will need to hope your bundle maintainer has updated their code appropriately, or you have a few options:

  1. Don’t upgrade
  2. Fix it yourself (which may take a while to get merged)
  3. Fork it, and fix it yourself (hoorah, now you’re in open source)
  4. Be lucky and have the bundle maintainer already have updated it for you

We all hope for number 4, right?

Fortunately on eightpoints/guzzle-bundle we get lucky. This is fixed for us… but:

Always a but. This will mean we need to be on at least PHP 7. Actually thought, Symfony 4 needs PHP 7.1, so yeah… either way it’s time to come kicking and screaming in to the modern world of PHP. Good.

#2 – [Part 1/2] Migrating to Symfony 4.0 with Flex

The recommended approach for upgrading to Symfony 4 with Flex is to start a brand new Flex project, and then migrate code between the old project, and the new.

This brings a potential problem:

When you create the new Flex project you will, by default, get a git repo created on your local computer.

For the love of Mike, don’t do what I did and accidentally copy that git directory over your existing git directory. Whoops. I share for the comedy, and fortunately it didn’t cost me any, because that was during the write up, and I re-do the whole thing again for the video. I bet you don’t want to do things twice though 🙂

There’s a bunch of steps to work through, some easier than others. You won’t believe step 5! Ho, ho, a buzz feed style bit of link bait title nonsense.

No, but seriously, step 5 needs some extra attention so be sure to watch the video to learn what that is.

#3 – [Part 2/2] Migrating to Symfony 4.0 with Flex

Finally we finish up the Symfony 4 migration by moving over the src  directory contents from the old Symfony 3.4 project to the new Symfony 4 Flex approach.

We then move over the Twig templates. There’s more work to be done here, and some of the problems we will face are not very intuitive. I guess it depends on how much you’ve been following the changes made in Symfony 4.

It really does feel good to have migrated a complete project, regardless of the project’s size, from Symfony 3 to Symfony 4. There’s some serious sense of satisfaction in seeing everything continue to work, even with such a massive amount of change behind the scenes.

Here’s to 2018

Whatever you are up to in 2018 I sincerely wish you every success.

Thank you and happy Christmas!

Chris

Symfony 4 Tutorial Content Update

Symfony 4 has caused me a few headaches this week. In between the usual site work, I’ve been tackling a noticeable up-tick in support requests regarding video content.

There are a number of reasons why this is, some of my own making.

Anyway, though I had planned to work on finishing each of the currently in-progress courses, I am instead switching to updating every existing Symfony related course on the site to use Symfony 4.

I’m honestly not sure how much work this will involve at this stage. I’m expecting it to take a few human days in total, which I unfortunately don’t have in one large block.

What this will mean is for each course I will pull the code from GitHub, and add a new branch, or branches, to enable support for Symfony 4.

I don’t expect, nor plan to have to update every video.

I do expect to have to record some new video content around updating some of the bigger projects.

I’m going to work on the courses based on the volume I’ve been receiving in support requests.

I’ll know and share more on this next week.

Video Update

This week saw three new videos added to the site.

#1 – Simple Backup Shell Script Linux

Backing stuff up is a real chore.

During development it’s not that big of a deal. Sure, if we accidentally destroy the DB it *might* be a pain, but it’s unlikely to cost us our jobs, or make national news (or, at least, hackernews).

Once we hit production however, backups are up there with the toppest of top priorities.

I guess we could do manual backups. It’s a good way to waste 30 minutes every day by following some regimented process.

A better way is to delegate to our robotic helper: the computer.

In this video we cover a basic but “good enough” (for me, at least) method of backing up pretty much anything, and keeping only the last X backups (where X may be 7 days for example).

We’ll cover how to write a backup script using Bash shell scripting, and how to automate running that script using a cronjob.

#2 – How to change the DB with a Phoenix Migration

Most every application I work on involves the database in some way.

When starting a fresh application it’s fairly easy to remember how and why the database schema ended up the way it is.

Then, after chopping and changing between four other projects, I come back to this “small” project and I’ve forgotten everything about it. Including why one of the fields is inexplicably an integer when a boolean seems like it might have been a better choice.

Fortunately, if you’re using database migrations, you can easily check back through the Git logs and figure out just what was changing in the code when you made such an interesting schema change.

I once read, somewhere, that having database migrations is effectively like adding version control to your database. I’m not entirely convinced by this, but they are helpful, and have proved worthwhile for me over the last few years.

Whatever your opinion, database migrations are available to us right “out of the box” with Phoenix, so using them is a no-brainer.

#3 – Database Schema: What and Why

In the previous video we covered how to tell the database about our changes, be it adding a new table, editing an existing table, adding or updating an index, and so on.

In order to work with that table we must write some Elixir code that represents that table.

A schemer

This code is called a Schema.

In this video we cover how we can generate a Schema for any particular table, and what the generated code is doing for us, and why.

Once we have a Schema, in this case for our “Contact”, we can start adding new records to the database. And we will do just this by making use of the REPL.

There are some interesting extras included in this video, such as touching on the purpose of alias, working with dates and times, and our first encounter with Pattern Matching.

That’s a Wrap

Ok, that’s it from me this week.

Until next week, have a great weekend and happy coding.

Chris