This is a starter app from Symfony4 for easy forking for new starters.
- Install Virtualbox
- Install Vagrant
- Run
vagrant plugin install vagrant-hostsupdater - Run
vagrant up
You now have a web server running on http://symfony.local.
You can edit the code directly in this directory to make changes.
You can ssh into the vagrant box with vagrant ssh.
Get to the code with cd /srv/www/app/current.
Once inside the vagrant box you can run Symfony commands, here are some useful ones:
# Clear the Symfony cache
$ bin/console cache:clear- Create a new Controller with an index action
- Create a route in
routes.yamlfor the index action at the/path - Create a new twig template in
templates/ - Make the twig template extend
base.html.twig - Make the index action render the new template
- Pass some variables through to the twig template and render them
- Play with adding new variables and removing them
- Create a hello action in your Controller
- Create a route for the action, give the route a path parameter of
{name} - Add
Request $requestandstring $nameas parameters to the action - Get the
lastNameparameter from the$requestwith a suitable default value if it doesn't exist - Create a new twig template and pass the two names through to it
- Make the twig template render the names
- Play with the path and request parameters
- Create your database schema
$ ./bin/console doctrine:database:create
- Create a
Postentity inEntity/ - Give it the following attributes:
- string id
- string slug
- string title
- string text
- \DateTimeImmutable $createdAt
- \DateTimeImmutable $updatedAt
- Import
Doctrine\ORM\Mapping as ORM, these are the Doctrine annotations you'll use to define the schema - Add the
@ORM\Entityannotation to the class - Add the
@ORM\Column(type=<your type>)annotation to each property- Choose which type you want from the Doctrine docs
- Add the following annotations to the
idfield to make MySQL automatically generate it:/** * @ORM\Id * @ORM\GeneratedValue(strategy="UUID") */
- Check the SQL that Doctrine wants to run to update the database
$ ./bin/console doctrine:schema:update --dump-sql
- If the SQL makes sense, execute it
$ ./bin/console doctrine:schema:update --force
- Get the details to log into the database from the
.envfileDATABASE_URL=mysql://<username>:<password>@127.0.0.1:3306/<db name> - Log into the database
$ mysql -u <username> -p <db name>
- Have a play, here are some fun SQL commands
show tables; describe post; select * from post;
- Create a
PostTypeclass inForm/that extendsAbstractType - Implement the
buildForm(FormBuilderInterface $builder, array $options)function - Add a few fields to the form with
$bulider->add()that exist in thePostentity, eg.$builder->add('title')
- The second argument to the
add()function allows you to change the type of the form field that's rendered$builder->add('text', TextareaType::class);
- Add a submit button to your form
$builder->add('sumbit', SubmitType::class)
- Create a new Controller action and route for
createPost(remember to inject theRequest) - In your controller, create a new
Post, bind it to the form and handle the requsett$post = new Post(); $form = $this->createForm(PostType::class, $post); $form->handleRequest($request)
- Now create a new twig template 'create-post.html.twig' to render your form, you can render a form with:
{{ form(form) }} - If the form hasn't been submitted, you need to render your new twig file
if (false === $form->isSubmitted() || false === $form->isValid()) { return $this->>render('create-post.html.twig', ['form' => $form->createView()]); }
- Now you can load your page and look at the form, have a play with the
PostTypeclass to see what you can change - In order to save your
Postto the database when the form is submitted, you need to use theEntityManager, so you inject it into the constructor of your Controller/** @var EntityManagerInterface **/ private $entityManager; public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManagerInterface; }
- Now you can save your
Postto the database, but only if the form has been submitted and is valid$this->entityManager->persist($post); $this->entityManager->flush();
- It's best practice to do a redirect after a form is successfully submitted because it prevents the user from
accidentally submitting the form twice
return $this->redirect('create');
- Submit your form a few times, log into the database like we did in the previous task and check our your posts
- Create a new twig template that iterates through a list of Posts and prints their title
<ul> {% for post in posts %} <li>{{ post.title }}</li> {% endfor %} </ul>
- Create a new Controller action
- Get a list of all the Posts and pass them through to your twig template
$posts = $this->entityManager->findAll(Post::class);
- Load the page, you should see a list of all the Posts in your database
- Inject the
Requestinto your action and get the'title'parameter from it (with a sensible default value of'') - Create a
QueryBuilderin order to search the database for specific Posts$posts = $this->entityManager->createQueryBuilder() ->select('post') ->from(Post:class, 'post') ->where('post.title = :title') ->setParameter('title', $title) ->getQuery() ->getResult() ;
- Now you can search for Posts by title!
- Have a play, try and the QueryBuilder doing a wildcard search with an SQL like