Symfony
Symfony
Instalacja
Wymagania minimalne:
- PHP 7.1.3
- composer
composer create-project symfony/skeleton my_projectTitle Text
$ > tree my_project
.
├── bin
│ └── console
├── config
│ ├── bundles.php
│ ├── routes.yaml
│ ├── services.yaml
│ └── packages
│ ├── framework.yaml
│ ├── routing.yaml
│ ├── dev
│ │ └── routing.yaml
│ └── test
│ └── framework.yaml
├── public
│ └── index.php
├── src
│ ├── Kernel.php
│ └── Controller
├── var
│ ├── cache
│ └── log
└── vendor
13 directoriesbin/ - pliki wykonywalne CLI
config/ - pliki konfiguracyjne z podziałem na bundle i środowiska
public/ - publiczne assety, index.php
src/ - logika biznesowa aplikacji
var/ - przechowywanie plików tymczasowych
var/cache - skompilowane pliki statyczne (routing, di)
vendor/ - biblioteki zależności
$ > composer require annotations
$ > composer require symfony/maker-bundle --devTitle Text
$ > php bin/console list make
make:command Creates a new console command class
make:controller Creates a new controller class
make:entity Creates a new Doctrine entity class
[...]https://symfony.com/doc/current/bundles/SymfonyMakerBundle
Pierwszy Controller
$ > php bin/console make:controller FirstController
> $ vim src/Controller/FirstController.php
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FirstController extends Controller
{
/**
* @Route("/first", name="first")
*/
public function index()
{
return $this->json([
'message' => 'Welcome to your new controller!',
'path' => 'src/Controller/FirstController.php',
]);
}
} Controller pod Maską
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FirstController extends Controller // src/Controller/LuckyController.php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class LuckyController
{
/**
* @Route("/lucky/number/{max}", name="app_lucky_number")
*/
public function number($max): Response
{
$number = random_int(0, $max);
return new Response(
'<html><body>Lucky number: '.$number.'</body></html>'
);
}
}Controller pod Maską
use Symfony\Component\Routing\Annotation\Route;
//...
/**
* @Route("/first", name="first")
*/
//... vendor/symfony/routing/Annotation/Route.phpRouting
/**
* @Route(
* "/hello/{_locale}/{year}/{slug}.{_format}",
* defaults={"_format": "html"},
* requirements={
* "_locale": "en|fr",
* "_format": "html|rss",
* "year": "\d+"
* }
* )
*/
public function hello($_locale, $year, $slug)
{
}http://symfony.com/doc/current/routing.html
Pierwsza Komenda
$ > php bin/console make:command app:first
> $ vim src/Controller/FirstController.php
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
class AppFirstCommand extends Command
{
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// ...
}
}Komenda pod Maską
protected static $defaultName = 'app:first';
protected function configure()
{
$this
->setDescription('Add a short description for your command')
->addArgument('arg1', InputArgument::OPTIONAL, 'Argument description')
->addOption('option1', null, InputOption::VALUE_NONE, 'Option description')
;
}http://symfony.com/doc/current/console.html
http://symfony.com/doc/current/console/input.html
Komenda pod Maską
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$arg1 = $input->getArgument('arg1');
if ($arg1) {
$io->note(sprintf('You passed an argument: %s', $arg1));
}
if ($input->getOption('option1')) {
// ...
}
$io->success('You have a new command! Now make it your own! Pass --help to see your options.');
}http://symfony.com/doc/current/console.html
Pierwsza Encja
$ > composer require orm
$ > composer require api
$ > cat .env
# ...
###> doctrine/doctrine-bundle ###
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
# Configure your db driver and server_version in config/packages/doctrine.yaml
DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name
###< doctrine/doctrine-bundle ###
$ > php bin/console doctrine:database:create
$ > php bin/console make:entity FirstEntity --api-resource
created: src/Entity/FirstEntity.php
created: src/Repository/FirstEntityRepository.php
Entity generated! Now let's add some fields!
You can always add more fields later manually or by re-running this command.
// Id is already created.
New property name (press <return> to stop adding fields):
> name
Field type (enter ? to see all types) [string]:
> string
Field length [255]:
>
Can this field be null in the database (nullable) (yes/no) [no]:
> no
https://symfony.com/doc/current/doctrine.html
Pierwsza Encja
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
/**
* @ApiResource()
* @ORM\Entity(repositoryClass="App\Repository\FirstEntityRepository")
*/
class FirstEntity
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
// Setters ...
}https://symfony.com/doc/current/doctrine.html
Crud Api
$ > composer require form
$ > bin/console make:crud FirstEntity
created: src/Controller/FirstEntityController.php
created: src/Form/FirstEntityType.php
created: templates/first_entity/_delete_form.html.twig
created: templates/first_entity/_form.html.twig
created: templates/first_entity/edit.html.twig
created: templates/first_entity/index.html.twig
created: templates/first_entity/new.html.twig
created: templates/first_entity/show.html.twig
Success!
Next: Check your new CRUD by going to /first/entity/https://api-platform.com/docs/core/getting-started/
Crud pod Maską
$ > cat src/Controller/FirstEntityController.php
[...]
/**
* @Route("/first/entity")
*/
class FirstEntityController extends Controller
{
/**
* @Route("/", name="first_entity_index", methods="GET")
*/
public function index(FirstEntityRepository $firstEntityRepository): Response
{
return $this->render(
'first_entity/index.html.twig',
['first_entities' => $firstEntityRepository->findAll()]
);
}
/**
* @Route("/new", name="first_entity_new", methods="GET|POST")
*/
public function new(Request $request): Response
{
$firstEntity = new FirstEntity();
$form = $this->createForm(FirstEntityType::class, $firstEntity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($firstEntity);
$em->flush();
return $this->redirectToRoute('first_entity_index');
}
return $this->render('first_entity/new.html.twig', [
'first_entity' => $firstEntity,
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}", name="first_entity_show", methods="GET")
*/
public function show(FirstEntity $firstEntity): Response
{
return $this->render(
'first_entity/show.html.twig',
['first_entity' => $firstEntity]
);
}
/**
* @Route("/{id}/edit", name="first_entity_edit", methods="GET|POST")
*/
public function edit(Request $request, FirstEntity $firstEntity): Response
{
$form = $this->createForm(FirstEntityType::class, $firstEntity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute(
'first_entity_edit',
['id' => $firstEntity->getId()]
);
}
return $this->render('first_entity/edit.html.twig', [
'first_entity' => $firstEntity,
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}", name="first_entity_delete", methods="DELETE")
*/
public function delete(Request $request, FirstEntity $firstEntity): Response
{
if (
$this->isCsrfTokenValid('delete'.$firstEntity->getId(),
$request->request->get('_token'))
) {
$em = $this->getDoctrine()->getManager();
$em->remove($firstEntity);
$em->flush();
}
return $this->redirectToRoute('first_entity_index');
}
}https://api-platform.com/docs/core/getting-started/
Crud pod Maską
$ > cat src/Form/FirstEntityType.php
<?php
namespace App\Form;
use App\Entity\FirstEntity;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FirstEntityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => FirstEntity::class,
]);
}
}https://api-platform.com/docs/core/getting-started/
Crud pod Maską
$ > curl localhost/api
{"@context":"\/api\/contexts\/Entrypoint","@id":"\/api","@type":"Entrypoint","firstEntity":"\/api\/first_entities"}
https://api-platform.com/docs/core/operations
Własny system Autoryzacji
$ > composer require security
$ > php bin/console make:auth AppCustomAuthenticator$ > vim config/packages/security.yaml
security:
# ...
providers:
your_db_provider:
entity:
class: App\Entity\User
property: apiKey
firewalls:
# ...
main:
anonymous: ~
logout: ~
guard:
authenticators:
- App\Security\AppCustomAuthenticatorhttps://symfony.com/doc/current/security/guard_authentication.html
https://security.symfony.com/
Symfony
By Paweł Radzikowski
Symfony
- 284