Skip to content

Commit 3fca3cb

Browse files
committed
minor #14525 [DependencyInjection][Doctrine][Form] Add type declarations to Form, DI and Doctrine articles (wouterj)
This PR was squashed before being merged into the 4.4 branch. Discussion ---------- [DependencyInjection][Doctrine][Form] Add type declarations to Form, DI and Doctrine articles Fixes part of #12235 Now the getting started articles are fixed, this PR continues with the 3 most popular doc topics. Commits ------- 8f8621d Added PHP types to the DI related articles aec1016 Added PHP types to the Form related articles 90c83b2 Added PHP types to the Doctrine related articles
2 parents 12bc66d + 8f8621d commit 3fca3cb

37 files changed

+455
-359
lines changed

doctrine.rst

Lines changed: 116 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ The database connection information is stored as an environment variable called
5151
5252
# to use sqlite:
5353
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"
54-
54+
5555
# to use postgresql:
5656
# DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11&charset=utf8"
5757
@@ -506,46 +506,60 @@ Fetching an object back out of the database is even easier. Suppose you want to
506506
be able to go to ``/product/1`` to see your new product::
507507

508508
// src/Controller/ProductController.php
509+
namespace App\Controller;
510+
511+
use App\Entity\Product;
512+
use Symfony\Component\HttpFoundation\Response;
509513
// ...
510514

511-
/**
512-
* @Route("/product/{id}", name="product_show")
513-
*/
514-
public function show($id)
515+
class ProductController extends AbstractController
515516
{
516-
$product = $this->getDoctrine()
517-
->getRepository(Product::class)
518-
->find($id);
519-
520-
if (!$product) {
521-
throw $this->createNotFoundException(
522-
'No product found for id '.$id
523-
);
524-
}
517+
/**
518+
* @Route("/product/{id}", name="product_show")
519+
*/
520+
public function show(int $id): Response
521+
{
522+
$product = $this->getDoctrine()
523+
->getRepository(Product::class)
524+
->find($id);
525+
526+
if (!$product) {
527+
throw $this->createNotFoundException(
528+
'No product found for id '.$id
529+
);
530+
}
525531

526-
return new Response('Check out this great product: '.$product->getName());
532+
return new Response('Check out this great product: '.$product->getName());
527533

528-
// or render a template
529-
// in the template, print things with {{ product.name }}
530-
// return $this->render('product/show.html.twig', ['product' => $product]);
534+
// or render a template
535+
// in the template, print things with {{ product.name }}
536+
// return $this->render('product/show.html.twig', ['product' => $product]);
537+
}
531538
}
532539

533540
Another possibility is to use the ``ProductRepository`` using Symfony's autowiring
534541
and injected by the dependency injection container::
535542

536543
// src/Controller/ProductController.php
537-
// ...
544+
namespace App\Controller;
545+
546+
use App\Entity\Product;
538547
use App\Repository\ProductRepository;
548+
use Symfony\Component\HttpFoundation\Response;
549+
// ...
539550

540-
/**
541-
* @Route("/product/{id}", name="product_show")
542-
*/
543-
public function show($id, ProductRepository $productRepository)
551+
class ProductController extends AbstractController
544552
{
545-
$product = $productRepository
546-
->find($id);
553+
/**
554+
* @Route("/product/{id}", name="product_show")
555+
*/
556+
public function show(int $id, ProductRepository $productRepository): Response
557+
{
558+
$product = $productRepository
559+
->find($id);
547560

548-
// ...
561+
// ...
562+
}
549563
}
550564

551565
Try it out!
@@ -611,15 +625,23 @@ for you automatically! First, install the bundle in case you don't have it:
611625
Now, simplify your controller::
612626

613627
// src/Controller/ProductController.php
628+
namespace App\Controller;
629+
614630
use App\Entity\Product;
631+
use App\Repository\ProductRepository;
632+
use Symfony\Component\HttpFoundation\Response;
633+
// ...
615634

616-
/**
617-
* @Route("/product/{id}", name="product_show")
618-
*/
619-
public function show(Product $product)
635+
class ProductController extends AbstractController
620636
{
621-
// use the Product!
622-
// ...
637+
/**
638+
* @Route("/product/{id}", name="product_show")
639+
*/
640+
public function show(Product $product): Response
641+
{
642+
// use the Product!
643+
// ...
644+
}
623645
}
624646

625647
That's it! The bundle uses the ``{id}`` from the route to query for the ``Product``
@@ -633,26 +655,37 @@ Updating an Object
633655
Once you've fetched an object from Doctrine, you interact with it the same as
634656
with any PHP model::
635657

636-
/**
637-
* @Route("/product/edit/{id}")
638-
*/
639-
public function update($id)
658+
// src/Controller/ProductController.php
659+
namespace App\Controller;
660+
661+
use App\Entity\Product;
662+
use App\Repository\ProductRepository;
663+
use Symfony\Component\HttpFoundation\Response;
664+
// ...
665+
666+
class ProductController extends AbstractController
640667
{
641-
$entityManager = $this->getDoctrine()->getManager();
642-
$product = $entityManager->getRepository(Product::class)->find($id);
668+
/**
669+
* @Route("/product/edit/{id}")
670+
*/
671+
public function update(int $id): Response
672+
{
673+
$entityManager = $this->getDoctrine()->getManager();
674+
$product = $entityManager->getRepository(Product::class)->find($id);
643675

644-
if (!$product) {
645-
throw $this->createNotFoundException(
646-
'No product found for id '.$id
647-
);
648-
}
676+
if (!$product) {
677+
throw $this->createNotFoundException(
678+
'No product found for id '.$id
679+
);
680+
}
649681

650-
$product->setName('New product name!');
651-
$entityManager->flush();
682+
$product->setName('New product name!');
683+
$entityManager->flush();
652684

653-
return $this->redirectToRoute('product_show', [
654-
'id' => $product->getId()
655-
]);
685+
return $this->redirectToRoute('product_show', [
686+
'id' => $product->getId()
687+
]);
688+
}
656689
}
657690

658691
Using Doctrine to edit an existing product consists of three steps:
@@ -728,7 +761,7 @@ a new method for this to your repository::
728761
/**
729762
* @return Product[]
730763
*/
731-
public function findAllGreaterThanPrice($price): array
764+
public function findAllGreaterThanPrice(int $price): array
732765
{
733766
$entityManager = $this->getEntityManager();
734767

@@ -773,25 +806,28 @@ based on PHP conditions)::
773806
// src/Repository/ProductRepository.php
774807

775808
// ...
776-
public function findAllGreaterThanPrice($price, $includeUnavailableProducts = false): array
809+
class ProductRepository extends ServiceEntityRepository
777810
{
778-
// automatically knows to select Products
779-
// the "p" is an alias you'll use in the rest of the query
780-
$qb = $this->createQueryBuilder('p')
781-
->where('p.price > :price')
782-
->setParameter('price', $price)
783-
->orderBy('p.price', 'ASC');
784-
785-
if (!$includeUnavailableProducts) {
786-
$qb->andWhere('p.available = TRUE');
787-
}
811+
public function findAllGreaterThanPrice(int $price, bool $includeUnavailableProducts = false): array
812+
{
813+
// automatically knows to select Products
814+
// the "p" is an alias you'll use in the rest of the query
815+
$qb = $this->createQueryBuilder('p')
816+
->where('p.price > :price')
817+
->setParameter('price', $price)
818+
->orderBy('p.price', 'ASC');
819+
820+
if (!$includeUnavailableProducts) {
821+
$qb->andWhere('p.available = TRUE');
822+
}
788823

789-
$query = $qb->getQuery();
824+
$query = $qb->getQuery();
790825

791-
return $query->execute();
826+
return $query->execute();
792827

793-
// to get just one result:
794-
// $product = $query->setMaxResults(1)->getOneOrNullResult();
828+
// to get just one result:
829+
// $product = $query->setMaxResults(1)->getOneOrNullResult();
830+
}
795831
}
796832

797833
Querying with SQL
@@ -802,20 +838,23 @@ In addition, you can query directly with SQL if you need to::
802838
// src/Repository/ProductRepository.php
803839

804840
// ...
805-
public function findAllGreaterThanPrice($price): array
841+
class ProductRepository extends ServiceEntityRepository
806842
{
807-
$conn = $this->getEntityManager()->getConnection();
808-
809-
$sql = '
810-
SELECT * FROM product p
811-
WHERE p.price > :price
812-
ORDER BY p.price ASC
813-
';
814-
$stmt = $conn->prepare($sql);
815-
$stmt->execute(['price' => $price]);
816-
817-
// returns an array of arrays (i.e. a raw data set)
818-
return $stmt->fetchAllAssociative();
843+
public function findAllGreaterThanPrice(int $price): array
844+
{
845+
$conn = $this->getEntityManager()->getConnection();
846+
847+
$sql = '
848+
SELECT * FROM product p
849+
WHERE p.price > :price
850+
ORDER BY p.price ASC
851+
';
852+
$stmt = $conn->prepare($sql);
853+
$stmt->execute(['price' => $price]);
854+
855+
// returns an array of arrays (i.e. a raw data set)
856+
return $stmt->fetchAllAssociative();
857+
}
819858
}
820859

821860
With SQL, you will get back raw data, not objects (unless you use the `NativeQuery`_

0 commit comments

Comments
 (0)