Hendrik Pilz
<?php print_r($me); ?>
stdClass Object
(
[name] => Hendrik
[worksAt] => rundum.digital
[codingSince] => 1998
[languages] => Array
(
[0] => PHP
[1] => HTML
[2] => CSS
[3] => JS
[4] => Java
[5] => SQL
[6] => ...
)
)
«Symfony is
a set of PHP Components,
a Web Application framework,
a Philosophy,
and a Community —
all working together in harmony.»
php 7.3 (www.php.net)composer - PHP Paket Manager (getcomposer.org)
$ mkdir bookdb
$ cd bookdb
$ composer create-project symfony/website-skeleton .
$ php bin/console server:run
DATABASE_URL=mysql://user:password@127.0.0.1:3306/dbname
.env-Datei im Projektverzeichnis
$ php bin/console doctrine:database:create
optional
$ php bin/console make:user
$ php bin/console make:migration
$ php bin/console doctrine:migrations:migrate
$ php bin/console make:registration-form
http://localhost:8000/register
$ php bin/console doctrine:query:sql "SELECT * FROM user"
$ php bin/console make:auth
http://localhost:8000/login
$ php bin/console make:controller
onAuthenticationSuccess() in Authenticator-Klasse anpassen
$ php bin/console make:entity
$ php bin/console make:migration
$ php bin/console doctrine:migrations:migrate
$ php bin/console make:entity
$ php bin/console make:migration
$ php bin/console doctrine:migrations:migrate

$ php bin/console make:crud

public function __toString() {
return $this->title;
}
Book.php, bei anderen Entities entsprechend anpassen
<link rel="stylesheet" type="text/css"
href="{{ asset('css/bootstrap.min.css') }}" />
im <head> in templates/base.html.twig
<script type="text/javascript"
src="{{ asset('js/bootstrap.min.js') }}"></script>
{% block javascripts %}{% endblock %}
vor </body> in templates/base.html.twig
{% form_theme form 'bootstrap_4_layout.html.twig' %}
in allen _form.html.twig
{% form_theme form 'bootstrap_3_layout.html.twig' %}
{% form_theme form 'bootstrap_3_horizontal_layout.html.twig' %}
{% form_theme form 'bootstrap_4_horizontal_layout.html.twig' %}
alternative Form-Templates
public function buildForm(FormBuilderInterface $builder,
array $options) {
$builder->add('title')
->add('text')
->add('rating', NumberType::class, [
'html5' => true
])
->add('book');
}
ReviewType.php
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Column(type="integer")
* @Assert\Range(min = 1, max = 10)
*/
private $rating;
Review.php
/**
* @Route("/new", name="review_new", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$review = new Review();
$review->setUser($this->getUser());
$form = $this->createForm(ReviewType::class, $review);
// [...]
}
ReviewController.php
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
/**
* @Route("/new", name="review_new", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER')")
*/
public function new(Request $request): Response
{
// [...]
}
in allen Controller-Klassen nach Bedarf
$ php bin/console make:voter
class ReviewVoter extends Voter {
protected function supports($attribute, $subject) {
return in_array($attribute, ['EDIT'])
&& $subject instanceof Review;
}
protected function voteOnAttribute($attribute, $subject,
TokenInterface $token) {
/* @var $subject Review */
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
switch ($attribute) {
case 'EDIT':
return $subject->getUser()->getUsername()
=== $user->getUsername();
}
return false;
}
}
ReviewVoter.php
public function edit(Request $request,
Review $review): Response
{
$this->denyAccessUnlessGranted('EDIT', $review);
// ...
}
ReviewController.php
$ composer require api
/**
* @ORM\Entity(repositoryClass="App\Repository\BookRepository")
* @ApiResource
*/
class Book {
// ...
}
$ php bin/console api:openapi:export > api.json
$ php bin/console api:openapi:export --yaml > api.yaml
Diese Präsentation ist hier verfügbar
www.hepisec.de/swk-symfony/