Skip to content

Commit 8bc638d

Browse files
committed
Merge branch '4.4' into 5.1
* 4.4: Added PHP types to the DI related articles Added PHP types to the Form related articles Added PHP types to the Doctrine related articles
2 parents fe572cc + 3fca3cb commit 8bc638d

37 files changed

+455
-359
lines changed

doctrine.rst

+116-77
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:[email protected]:5432/db_name?serverVersion=11&charset=utf8"
5757
@@ -502,46 +502,60 @@ Fetching an object back out of the database is even easier. Suppose you want to
502502
be able to go to ``/product/1`` to see your new product::
503503

504504
// src/Controller/ProductController.php
505+
namespace App\Controller;
506+
507+
use App\Entity\Product;
508+
use Symfony\Component\HttpFoundation\Response;
505509
// ...
506510

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

522-
return new Response('Check out this great product: '.$product->getName());
528+
return new Response('Check out this great product: '.$product->getName());
523529

524-
// or render a template
525-
// in the template, print things with {{ product.name }}
526-
// return $this->render('product/show.html.twig', ['product' => $product]);
530+
// or render a template
531+
// in the template, print things with {{ product.name }}
532+
// return $this->render('product/show.html.twig', ['product' => $product]);
533+
}
527534
}
528535

529536
Another possibility is to use the ``ProductRepository`` using Symfony's autowiring
530537
and injected by the dependency injection container::
531538

532539
// src/Controller/ProductController.php
533-
// ...
540+
namespace App\Controller;
541+
542+
use App\Entity\Product;
534543
use App\Repository\ProductRepository;
544+
use Symfony\Component\HttpFoundation\Response;
545+
// ...
535546

536-
/**
537-
* @Route("/product/{id}", name="product_show")
538-
*/
539-
public function show($id, ProductRepository $productRepository)
547+
class ProductController extends AbstractController
540548
{
541-
$product = $productRepository
542-
->find($id);
549+
/**
550+
* @Route("/product/{id}", name="product_show")
551+
*/
552+
public function show(int $id, ProductRepository $productRepository): Response
553+
{
554+
$product = $productRepository
555+
->find($id);
543556

544-
// ...
557+
// ...
558+
}
545559
}
546560

547561
Try it out!
@@ -607,15 +621,23 @@ for you automatically! First, install the bundle in case you don't have it:
607621
Now, simplify your controller::
608622

609623
// src/Controller/ProductController.php
624+
namespace App\Controller;
625+
610626
use App\Entity\Product;
627+
use App\Repository\ProductRepository;
628+
use Symfony\Component\HttpFoundation\Response;
629+
// ...
611630

612-
/**
613-
* @Route("/product/{id}", name="product_show")
614-
*/
615-
public function show(Product $product)
631+
class ProductController extends AbstractController
616632
{
617-
// use the Product!
618-
// ...
633+
/**
634+
* @Route("/product/{id}", name="product_show")
635+
*/
636+
public function show(Product $product): Response
637+
{
638+
// use the Product!
639+
// ...
640+
}
619641
}
620642

621643
That's it! The bundle uses the ``{id}`` from the route to query for the ``Product``
@@ -629,26 +651,37 @@ Updating an Object
629651
Once you've fetched an object from Doctrine, you interact with it the same as
630652
with any PHP model::
631653

632-
/**
633-
* @Route("/product/edit/{id}")
634-
*/
635-
public function update($id)
654+
// src/Controller/ProductController.php
655+
namespace App\Controller;
656+
657+
use App\Entity\Product;
658+
use App\Repository\ProductRepository;
659+
use Symfony\Component\HttpFoundation\Response;
660+
// ...
661+
662+
class ProductController extends AbstractController
636663
{
637-
$entityManager = $this->getDoctrine()->getManager();
638-
$product = $entityManager->getRepository(Product::class)->find($id);
664+
/**
665+
* @Route("/product/edit/{id}")
666+
*/
667+
public function update(int $id): Response
668+
{
669+
$entityManager = $this->getDoctrine()->getManager();
670+
$product = $entityManager->getRepository(Product::class)->find($id);
639671

640-
if (!$product) {
641-
throw $this->createNotFoundException(
642-
'No product found for id '.$id
643-
);
644-
}
672+
if (!$product) {
673+
throw $this->createNotFoundException(
674+
'No product found for id '.$id
675+
);
676+
}
645677

646-
$product->setName('New product name!');
647-
$entityManager->flush();
678+
$product->setName('New product name!');
679+
$entityManager->flush();
648680

649-
return $this->redirectToRoute('product_show', [
650-
'id' => $product->getId()
651-
]);
681+
return $this->redirectToRoute('product_show', [
682+
'id' => $product->getId()
683+
]);
684+
}
652685
}
653686

654687
Using Doctrine to edit an existing product consists of three steps:
@@ -724,7 +757,7 @@ a new method for this to your repository::
724757
/**
725758
* @return Product[]
726759
*/
727-
public function findAllGreaterThanPrice($price): array
760+
public function findAllGreaterThanPrice(int $price): array
728761
{
729762
$entityManager = $this->getEntityManager();
730763

@@ -769,25 +802,28 @@ based on PHP conditions)::
769802
// src/Repository/ProductRepository.php
770803

771804
// ...
772-
public function findAllGreaterThanPrice($price, $includeUnavailableProducts = false): array
805+
class ProductRepository extends ServiceEntityRepository
773806
{
774-
// automatically knows to select Products
775-
// the "p" is an alias you'll use in the rest of the query
776-
$qb = $this->createQueryBuilder('p')
777-
->where('p.price > :price')
778-
->setParameter('price', $price)
779-
->orderBy('p.price', 'ASC');
780-
781-
if (!$includeUnavailableProducts) {
782-
$qb->andWhere('p.available = TRUE');
783-
}
807+
public function findAllGreaterThanPrice(int $price, bool $includeUnavailableProducts = false): array
808+
{
809+
// automatically knows to select Products
810+
// the "p" is an alias you'll use in the rest of the query
811+
$qb = $this->createQueryBuilder('p')
812+
->where('p.price > :price')
813+
->setParameter('price', $price)
814+
->orderBy('p.price', 'ASC');
815+
816+
if (!$includeUnavailableProducts) {
817+
$qb->andWhere('p.available = TRUE');
818+
}
784819

785-
$query = $qb->getQuery();
820+
$query = $qb->getQuery();
786821

787-
return $query->execute();
822+
return $query->execute();
788823

789-
// to get just one result:
790-
// $product = $query->setMaxResults(1)->getOneOrNullResult();
824+
// to get just one result:
825+
// $product = $query->setMaxResults(1)->getOneOrNullResult();
826+
}
791827
}
792828

793829
Querying with SQL
@@ -798,20 +834,23 @@ In addition, you can query directly with SQL if you need to::
798834
// src/Repository/ProductRepository.php
799835

800836
// ...
801-
public function findAllGreaterThanPrice($price): array
837+
class ProductRepository extends ServiceEntityRepository
802838
{
803-
$conn = $this->getEntityManager()->getConnection();
804-
805-
$sql = '
806-
SELECT * FROM product p
807-
WHERE p.price > :price
808-
ORDER BY p.price ASC
809-
';
810-
$stmt = $conn->prepare($sql);
811-
$stmt->execute(['price' => $price]);
812-
813-
// returns an array of arrays (i.e. a raw data set)
814-
return $stmt->fetchAllAssociative();
839+
public function findAllGreaterThanPrice(int $price): array
840+
{
841+
$conn = $this->getEntityManager()->getConnection();
842+
843+
$sql = '
844+
SELECT * FROM product p
845+
WHERE p.price > :price
846+
ORDER BY p.price ASC
847+
';
848+
$stmt = $conn->prepare($sql);
849+
$stmt->execute(['price' => $price]);
850+
851+
// returns an array of arrays (i.e. a raw data set)
852+
return $stmt->fetchAllAssociative();
853+
}
815854
}
816855

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

0 commit comments

Comments
 (0)