Skip to content

Commit 813f173

Browse files
committed
Added PHP types to the Doctrine related articles
1 parent 59bee3e commit 813f173

File tree

6 files changed

+186
-122
lines changed

6 files changed

+186
-122
lines changed

doctrine.rst

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

505505
// src/Controller/ProductController.php
506+
namespace App\Controller;
507+
508+
use App\Entity\Product;
509+
use Symfony\Component\HttpFoundation\Response;
506510
// ...
507511

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

523-
return new Response('Check out this great product: '.$product->getName());
529+
return new Response('Check out this great product: '.$product->getName());
524530

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

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

533540
// src/Controller/ProductController.php
534-
// ...
541+
namespace App\Controller;
542+
543+
use App\Entity\Product;
535544
use App\Repository\ProductRepository;
545+
use Symfony\Component\HttpFoundation\Response;
546+
// ...
536547

537-
/**
538-
* @Route("/product/{id}", name="product_show")
539-
*/
540-
public function show($id, ProductRepository $productRepository)
548+
class ProductController extends AbstractController
541549
{
542-
$product = $productRepository
543-
->find($id);
550+
/**
551+
* @Route("/product/{id}", name="product_show")
552+
*/
553+
public function show(int $id, ProductRepository $productRepository): Response
554+
{
555+
$product = $productRepository
556+
->find($id);
544557

545-
// ...
558+
// ...
559+
}
546560
}
547561

548562
Try it out!
@@ -608,15 +622,23 @@ for you automatically! First, install the bundle in case you don't have it:
608622
Now, simplify your controller::
609623

610624
// src/Controller/ProductController.php
625+
namespace App\Controller;
626+
611627
use App\Entity\Product;
628+
use App\Repository\ProductRepository;
629+
use Symfony\Component\HttpFoundation\Response;
630+
// ...
612631

613-
/**
614-
* @Route("/product/{id}", name="product_show")
615-
*/
616-
public function show(Product $product)
632+
class ProductController extends AbstractController
617633
{
618-
// use the Product!
619-
// ...
634+
/**
635+
* @Route("/product/{id}", name="product_show")
636+
*/
637+
public function show(Product $product): Response
638+
{
639+
// use the Product!
640+
// ...
641+
}
620642
}
621643

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

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

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

647-
$product->setName('New product name!');
648-
$entityManager->flush();
679+
$product->setName('New product name!');
680+
$entityManager->flush();
649681

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

655688
Using Doctrine to edit an existing product consists of three steps:
@@ -725,7 +758,7 @@ a new method for this to your repository::
725758
/**
726759
* @return Product[]
727760
*/
728-
public function findAllGreaterThanPrice($price): array
761+
public function findAllGreaterThanPrice(int $price): array
729762
{
730763
$entityManager = $this->getEntityManager();
731764

@@ -770,25 +803,28 @@ based on PHP conditions)::
770803
// src/Repository/ProductRepository.php
771804

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

786-
$query = $qb->getQuery();
821+
$query = $qb->getQuery();
787822

788-
return $query->execute();
823+
return $query->execute();
789824

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

794830
Querying with SQL
@@ -799,20 +835,23 @@ In addition, you can query directly with SQL if you need to::
799835
// src/Repository/ProductRepository.php
800836

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

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

0 commit comments

Comments
 (0)