When it comes to rendering a page, the application compares the URL against the routes until one matches, Symfony reads the _controller
key and executes that function. The page you want to render is built in the function. Controller functions are dead-simple, and there’s just one big rule: it must return a Symfony Response object. In this lesson, we'll build our Response, take a look at JSON, and then render the template using the Symfony templating service.
Getting down to the actual templates we want to render, we need to get a handle on Twig, a language that feels a lot like PHP, but was made specifically to be awesome at doing templating tasks, like looping, rendering other templates, and handling layouts. In this lesson, we'll go over the basic Twig tags, and extend a base layout to get our page looking the way we want.
Additional resources
Symfony doesn’t care about your database or the code you use to talk to it. Most people that use Symfony use a third-party database library called Doctrine. Doctrine maps rows and columns in your database to objects and properties in PHP. Imagine we have an Event object with name and location properties. If we tell Doctrine to save this object, it inserts a row into a table and puts the data on name and location columns. And when we query for the event, it puts the column data back onto the properties of an Event object. When using Doctrine you need to stop thinking about tables, and start thinking about PHP classes. In this lesson, you will create the Event Entity Class, and learn a little debugging trick.
Additional resources
In this lesson, you will start using Doctrine to insert and query a database. First, you need to actually create and configure the database. Once we have that all set up, you will query the database, and render the results with Twig.
Additional resources
We’re using the built-in PHP web server, and it’s awesome for development. But it only handles one request at a time, so unless you only ever want one visitor, we’re going to need something different. To see how this might look, we’ll invent a fake domain, events.l
, and set it up to point to our project. I’ll use Apache, though it’s more and more common to use Nginx with PHP-FPM, because they’re lightning fast, but all the ideas are the same.
Additional resources
Now that we have an event page, we need our app to let users create, view, update and delete events. In other words, we need a CRUD for the Event entity. We can use Doctrine to generate a CRUD for us, but when it does that we need to clean a few things up since we've already been doing work in there. We'll also take a look at how to tighten up the generated code.
Additional resources
In this lesson, you'll use the assets:install command to get some nice CSS added to your application so we can make things look a little nicer.
We've got our Twig template files, and in this lesson we're going to take a closer look at working with creating links with the Twig path function, and making our dates make sense of the Twig date filter.
Additional resources
We have the application looking a lot better, and now, to see things fleshed out a little more we're going to load fixtures, which are dummy data we put into the database. When we started the project, we downloaded the Symfony Standard edition—our pre-started project that came with Symfony and other tools like Doctrine. Unfortunately, it didn’t come with any tools for handling fixtures. To do this yourself, you're going to learn to use Composer and KnpBundles.com to take care of things.
A fixture is just a PHP class that puts some stuff into the database. To get your dummy data set up, in this lesson, you'll write a fixture and then load it up.
Autoloading is the magic that lets us use classes without needing to require or include the file that holds them first. An autoloader has a tricky job: given any class name, it needs to know the exact location of the file that holds that class. In many modern projects, including ours, Composer handles this for us, and there are two pieces to understanding how it figures out what file a class lives in. In this lesson we're going to get an overview of how directory structures and namespaces make autoloading work.
Additional resources
In this lesson we'll going to look at a few shortcuts we can use in our controller, using the SensioFrameworkExtraBundle
, which comes with the standard Symfony project. We're going to review how to use @Template
rendering, annotations, and working with routes.
Additional resources
In this tutorial we're going to wrap things up by taking a look at some quick, simple tips for working with Twig. We're going to explain what GlobalVariables is, and then play with the block function and clean up some whitespace issues.
Additional resources
In this tutorial we're going to play with some extra nice things you can do with Twig. We're going to get expert control of our blocks with the block function, work with concatenating strings, controlling our whitespace, and using undefined variables with the default filter. We'll wrap things up with a look at escaping HTML. Whenever you render content that may have been filled in by the user, you need to escape it. This prevents people from writing HTML tags that you don’t want or, worse, JavaScript code that could be used for cross-site scripting attacks.
In this PHP tutorial we are going to continue to remove the flat functions in our code. We'll refactor one of them to a private function and create a new ShipLoader
service class to clean up the rest. With this refactoring in place, we'll be able to rename the functions.php file since it won't contain any functions any longer.
The next thing we want to tackle is our battle()
function, with its array, inside our BattleManager class. It's not obvious at all what's inside the $outcome
variable, or whether the keys it has now might be missing or different in the future. To rectify this we're going to create a new BattleResult model class with some properties and methods that will clean things up and remove the need for weird associative arrays. Our BattleManager::battle()
function will return a nice BattleResult object, and we'll be in full control of what public methods we put on that.
We now have a BattleResult
class, and we type-hinted the two Ship
arguments. But now, if you look at the battle()
function, there's a case where the ships can destroy each other. When that happens, there is no winning or losing ship—they're both null. Since null
is not a Ship
object, PHP gets angry and throws an error. In this PHP tutorial we'll fix that problem by creating a isThereAWinner
semantic method in our BattleResult
class.
In this PHP tutorial we're going to update some information in our ship object and see another way that objects are different from arrays—objects are always passed by reference. We need to add a new feature to our app so that after the battle we can display the final health of the battling ships. One will be zero or negative, but how much health did the other have left? Let's take a look at how we can update the ships to reflect their new health after a battle.
So far we've been hard-coding our ships in the ShipLoader
class. In this tutorial we'll take things up a notch by fetching that information from a database. First we're going to create a new database to hold our data, using PDO
. (If you are not familiar with working with databases in PHP, you can check out the PHP for Beginners Part 3 series, which covers database fun.) Once we have the database created and filled with some ship data, we'll learn how to fetch that data back out again as an object our app can work with.
In the prevous tutorial we set up our app to fetch the ship objects from the database, but now our app ship select lists are not working properly. To deal with that, in this PHP tutorial, we're going to add a ship ID property to our class and then we will use the ShipLoader
class to query for individual ships. Lastly, we will once again need to turn the array that we fetch into an object that our app can use. As an added bonus we'll also update the PHPDoc so we can get autocompleting method names.