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/