@@ -48,7 +48,7 @@ The database connection information is stored as an environment variable called
48
48
49
49
# to use sqlite:
50
50
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"
51
-
51
+
52
52
# to use postgresql:
53
53
# DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11&charset=utf8"
54
54
@@ -503,46 +503,60 @@ Fetching an object back out of the database is even easier. Suppose you want to
503
503
be able to go to ``/product/1 `` to see your new product::
504
504
505
505
// src/Controller/ProductController.php
506
+ namespace App\Controller;
507
+
508
+ use App\Entity\Product;
509
+ use Symfony\Component\HttpFoundation\Response;
506
510
// ...
507
511
508
- /**
509
- * @Route("/product/{id}", name="product_show")
510
- */
511
- public function show($id)
512
+ class ProductController extends AbstractController
512
513
{
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
+ }
522
528
523
- return new Response('Check out this great product: '.$product->getName());
529
+ return new Response('Check out this great product: '.$product->getName());
524
530
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
+ }
528
535
}
529
536
530
537
Another possibility is to use the ``ProductRepository `` using Symfony's autowiring
531
538
and injected by the dependency injection container::
532
539
533
540
// src/Controller/ProductController.php
534
- // ...
541
+ namespace App\Controller;
542
+
543
+ use App\Entity\Product;
535
544
use App\Repository\ProductRepository;
545
+ use Symfony\Component\HttpFoundation\Response;
546
+ // ...
536
547
537
- /**
538
- * @Route("/product/{id}", name="product_show")
539
- */
540
- public function show($id, ProductRepository $productRepository)
548
+ class ProductController extends AbstractController
541
549
{
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);
544
557
545
- // ...
558
+ // ...
559
+ }
546
560
}
547
561
548
562
Try it out!
@@ -608,15 +622,23 @@ for you automatically! First, install the bundle in case you don't have it:
608
622
Now, simplify your controller::
609
623
610
624
// src/Controller/ProductController.php
625
+ namespace App\Controller;
626
+
611
627
use App\Entity\Product;
628
+ use App\Repository\ProductRepository;
629
+ use Symfony\Component\HttpFoundation\Response;
630
+ // ...
612
631
613
- /**
614
- * @Route("/product/{id}", name="product_show")
615
- */
616
- public function show(Product $product)
632
+ class ProductController extends AbstractController
617
633
{
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
+ }
620
642
}
621
643
622
644
That's it! The bundle uses the ``{id} `` from the route to query for the ``Product ``
@@ -630,26 +652,37 @@ Updating an Object
630
652
Once you've fetched an object from Doctrine, you interact with it the same as
631
653
with any PHP model::
632
654
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
637
664
{
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);
640
672
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
+ }
646
678
647
- $product->setName('New product name!');
648
- $entityManager->flush();
679
+ $product->setName('New product name!');
680
+ $entityManager->flush();
649
681
650
- return $this->redirectToRoute('product_show', [
651
- 'id' => $product->getId()
652
- ]);
682
+ return $this->redirectToRoute('product_show', [
683
+ 'id' => $product->getId()
684
+ ]);
685
+ }
653
686
}
654
687
655
688
Using Doctrine to edit an existing product consists of three steps:
@@ -725,7 +758,7 @@ a new method for this to your repository::
725
758
/**
726
759
* @return Product[]
727
760
*/
728
- public function findAllGreaterThanPrice($price): array
761
+ public function findAllGreaterThanPrice(int $price): array
729
762
{
730
763
$entityManager = $this->getEntityManager();
731
764
@@ -770,25 +803,28 @@ based on PHP conditions)::
770
803
// src/Repository/ProductRepository.php
771
804
772
805
// ...
773
- public function findAllGreaterThanPrice($price, $includeUnavailableProducts = false): array
806
+ class ProductRepository extends ServiceEntityRepository
774
807
{
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
+ }
785
820
786
- $query = $qb->getQuery();
821
+ $query = $qb->getQuery();
787
822
788
- return $query->execute();
823
+ return $query->execute();
789
824
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
+ }
792
828
}
793
829
794
830
Querying with SQL
@@ -799,20 +835,23 @@ In addition, you can query directly with SQL if you need to::
799
835
// src/Repository/ProductRepository.php
800
836
801
837
// ...
802
- public function findAllGreaterThanPrice($price): array
838
+ class ProductRepository extends ServiceEntityRepository
803
839
{
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
+ }
816
855
}
817
856
818
857
With SQL, you will get back raw data, not objects (unless you use the `NativeQuery `_
0 commit comments