doctrine

Symfony for Beginners – Doctrine – Fetch Database

Come prelevare facilmente i dati da un database con Symfony e Doctrine.

1. Creiamo il DB da phpMyAdmin

Name: test_project
Codifica caratteri: utf8mb4_bin

Creiamola tabella: product
– Id integer auto increment
– name char lenght=100
– price decimal scale=2 (10,2)
– description text

NB: phpMyAdmin a volte non imposta correttamente 10,2 convertendolo in automatico in 10,0, in questo caso selezionare il tab SQL e digitale

ALTER TABLE `product` CHANGE `price` `price` DECIMAL(10,2) NOT NULL;

Inseriamo dei prodotti

2. Creiamo la Entity Product in src/AppBundle/Entity/Product.php
Notare che le proprietà di questa classe saranno public o non riuscirò ad accedervi per visualizzare il Fetch del DB.


<?php

// src/AppBundle/Entity/Product.php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="product")
 */
class Product
{
    
    // -------------------------------------------------------------------------    
    // Proprietà ---------------------------------------------------------------
    // -------------------------------------------------------------------------
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    public $name;

    /**
     * @ORM\Column(type="decimal", scale=2)
     */
    public $price;

    /**
     * @ORM\Column(type="text")
     */
    public $description;
    
    // -------------------------------------------------------------------------
    // Metodi ------------------------------------------------------------------
    // -------------------------------------------------------------------------
    public function getId() // ottieni
    {
        return $this->id; // assegna il valore che proviene dall'istanza $this->
    }
 
    public function setId($id) // setta
    {
        $this->id = $id;
    }
    // -------------------------------------------------------------------------
    public function getName() // ottieni
    {
        return $this->name; // assegna il valore che proviene dall'istanza $this->
    }
 
    public function setName($name) // setta
    {
        $this->name = $name;
    }
    // -------------------------------------------------------------------------
    public function getPrice() // ottieni
    {
        return $this->price; // assegna il valore che proviene dall'istanza $this->
    }
 
    public function setPrice($price) // setta
    {
        $this->price = $price;
    }
    // -------------------------------------------------------------------------
    public function getDescription() // ottieni
    {
        return $this->description; // assegna il valore che proviene dall'istanza $this->
    }
 
    public function setDescription($description) // setta
    {
        $this->description = $description;
    }
}// end class Product

3. Creiamo il Controller in src/AppBundle/Controller/LoadProduct.php


<?php

// src/AppBundle/Controller/LoadProduct.php
namespace AppBundle\Controller;

use AppBundle\Entity\Product;// Product.php che ho creato io
use Symfony\Bundle\FrameworkBundle\Controller\Controller; // il bundle controller Symfont
use Symfony\Component\HttpFoundation\Response; // namespace di Symfony per response()
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;// namespace per utilizzare @Route


class LoadProduct extends Controller {
    
    /**
    * @Route("/loadproduct")
    */
    public function createAction()
    {
    
    echo ('Carica dal DB');
    // metodo di Doctrine getRepository('AppBundle/Entity/Product.php') -> shortcut -> ('AppBundle:Product')
    // crea lo schema dell'oggetto
    $repository = $this->getDoctrine()->getRepository('AppBundle:Product');
    // cerca per il prezzo - findByNomevariabile(valore) -
    $productExtracted = $repository->findByPrice(12.99);
    var_dump($productExtracted); // renderizza l'array di oggetti creato
    
    // renderizza tutto il contenuto dell'array di oggetti
    for ($i = 0; $i < count($productExtracted); $i++)// conteggia tutto il contenuto
    {
        echo $i . " " . ($productExtracted[$i]->name) . "<br>";
    }
    
    // send var to a template...
    return new Response(
            'End of the Script'
            );
 
    }// END createAction()
    
}// END class Saveproduct

Come funziona?

1. Per utilizzare il DB dobbiamo avere una Entity che fornisca a Symfony uno schema sul quale creare le query.
metodo di Doctrine getRepository(‘AppBundle:Product’) -> che è l’equivalenmte di -> getRepository((‘AppBundle/Entity/Product.php’)

$repository = $this->getDoctrine()->getRepository('AppBundle:Product');

2. Ora basta lanciare le query con la sintassi findByNomevariabile(valore) dove findBy è la keyword

$productExtracted = $repository->findByPrice(12.99); 

$productExtracted = un array di oggetti, gli oggetti sono le singole colonne del database

3. Renderizza


Carica dal DB
C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\LoadProduct.php:26:
array (size=2)
  0 => 
    object(AppBundle\Entity\Product)[307]
      public 'id' => int 36
      public 'name' => string 'USB Pen Sandisk' (length=15)
      public 'price' => string '12.99' (length=5)
      public 'description' => string 'Ergonomic and stylish!' (length=22)
  1 => 
    object(AppBundle\Entity\Product)[309]
      public 'id' => int 30
      public 'name' => string 'USB Pen Kingston' (length=16)
      public 'price' => string '12.99' (length=5)
      public 'description' => string 'Ergonomic and stylish!' (length=22)

0 USB Pen Sandisk
1 USB Pen Kingston

End of the Script

By |MySQL, PHP, Symfony, Web Design|Commenti disabilitati su Symfony for Beginners – Doctrine – Fetch Database

Symfony – Databases and the Doctrine ORM

Symfony non integra al suo interno componenti per lavorare con i databases, ma è integrato con la libreria di terze party ‘Doctrine’.
Possiamo trovare le librerie in Sources Files/vendor/doctrine

1. Aprire app/config/parameters.yml, questi sono i dati di accesso al DB, sono stati creati in fase di creazione del progetto


# app/config/parameters.yml

parameters:
    database_host:      localhost
    database_name:      test_project
    database_user:      root
    database_password:  

2. Aprire app/config/config.yml, qui settiamo i parametri per la corretta scrittura e charset che DEVE essere utf8mb4
utf8mb4 è stata introdotta dalla versione 5.5.3
Il vecchio utf8 usa al massimo 3 bytes, utf8mb4 usa al massimo 4 bytes per carattere, supportando quindi un maggior numero di caratteri.


doctrine:
    dbal:
        ...
        charset: utf8mb4
        default_table_options:
            charset: utf8mb4
            collate: utf8mb4_unicode_ci

3. Creiamo il DB da phpMyAdmin

Name: test_project
Codifica caratteri: utf8mb4_bin

4. Creiamola tabella: product
– Id integer auto increment
– name char lenght=100
– price decimal scale=2 (10,2)
– description text

NB: phpMyAdmin a volte non imposta correttamente 10,2 convertendolo in automatico in 10,0, in questo caso selezionare il tab SQL e digitale


ALTER TABLE `product` CHANGE `price` `price` DECIMAL(10,2) NOT NULL;

5. src/AppBundle/Entity/Product.php


<?php

// src/AppBundle/Entity/Product.php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="product")
 */
class Product
{
    
    // -------------------------------------------------------------------------    
    // Proprietà ---------------------------------------------------------------
    // -------------------------------------------------------------------------
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;

    /**
     * @ORM\Column(type="decimal", scale=2)
     */
    private $price;

    /**
     * @ORM\Column(type="text")
     */
    private $description;
    
    // -------------------------------------------------------------------------
    // Metodi ------------------------------------------------------------------
    // -------------------------------------------------------------------------
    public function getId() // ottieni
    {
        return $this->id; // assegna il valore che proviene dall'istanza $this->
    }
 
    public function setId($id) // setta
    {
        $this->id = $id;
    }
    // -------------------------------------------------------------------------
    public function getName() // ottieni
    {
        return $this->name; // assegna il valore che proviene dall'istanza $this->
    }
 
    public function setName($name) // setta
    {
        $this->name = $name;
    }
    // -------------------------------------------------------------------------
    public function getPrice() // ottieni
    {
        return $this->price; // assegna il valore che proviene dall'istanza $this->
    }
 
    public function setPrice($price) // setta
    {
        $this->price = $price;
    }
    // -------------------------------------------------------------------------
    public function getDescription() // ottieni
    {
        return $this->description; // assegna il valore che proviene dall'istanza $this->
    }
 
    public function setDescription($description) // setta
    {
        $this->description = $description;
    }
}// end class Product

Notare che nel creare l’oggetto aggiungo le specifiche per il salvaggio nel DB con la notazione /**


use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="product")
 */

6. src/AppBundle/Controller/SaveProduct.php


<?php

// src/AppBundle/Controller/SaveProduct.php
namespace AppBundle\Controller;

use AppBundle\Entity\Product;// Product.php che ho creato io
use Symfony\Bundle\FrameworkBundle\Controller\Controller; // il bundle controller Symfont
use Symfony\Component\HttpFoundation\Response; // namespace di Symfony per response()
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;// namespace per utilizzare @Route


class SaveProduct extends Controller {
    
    /**
    * @Route("/saveproduct")
    */
    public function createAction()
    {
    // 1. Crea i prodotti
    // primo prodotto ----------------------------------------------------------    
    $product = new Product();
    $product->setName('Keyboard');
    $product->setPrice(19.99);
    $product->setDescription('Ergonomic and stylish!');
    // -------------------------------------------------------------------------
    // secondo prodotto --------------------------------------------------------
    $anotherProduct = new Product();
    $anotherProduct->setName('Mouse');
    $anotherProduct->setPrice(5.99);
    $anotherProduct->setDescription('Really cool!');
    // -------------------------------------------------------------------------
    
    // debug code --------------------------------------------------------------
    echo 'Primo Debug';
    var_dump($product); // debug notare che id = 'null', non è un problema
    // il campo Id lo gestisce Doctrine automaticamente, Id resta nel DB anche alla cancellazione del prodotto
    var_dump($anotherProduct);
    // die('Stop Here'); // debug 
    
    // 2. accesso al DB --------------------------------------------------------
    $em = $this->getDoctrine()->getManager(); // carica il metodo di Doctrin per la gestione del DB
    // 3. INSERIMENTO PRIMO OGGETTO --------------------------------------------
    // tells Doctrine you want to (eventually) save the Product (no queries yet)
    $em->persist($product); // prepara l'oggetto in Cache per velocizzarsi ma NON salva ancora
    // actually executes the queries (i.e. the INSERT query)
    $em->flush(); // metodo flush() esegue INSERT
    // 4. INSERIMENTO SECONDO OGGETTO ------------------------------------------
    $em->persist($anotherProduct);
    $em->flush();
    // 5. RIMOZIONE SECONDO OGGETTO --------------------------------------------
    $em->remove($anotherProduct);
    $em->flush();
    
    // mostra id prelevandolo dall'oggetto $product, non sta leggendo dal DB
    return new Response(
            'Saved new product with id '.$product->getId()
            );
 
    }// END createAction()
    
}// END class Saveproduct

Come funziona?

1. Istanzio per creare 2 prodotti $product = new Product(); – $anotherProduct = new Product();

2. $em = $this->getDoctrine()->getManager(); – richiamo il metodo di Doctrine per la gestione del DB

3a. $em->persist($product); – richiamo il metodo persist per creare una query temporanea in cache
3b. $em->flush(); – avvia la query INSERT

4a. $em->remove($anotherProduct); – richiamo il metodo remove per creare una query temporanea in cache
4b. $em->flush(); – avvia la query DELETE

Bibliografia:
symfony.com/doc/current/doctrine.html
docs.doctrine-project.org
docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#quoting-reserved-words

By |MySQL, PHP, Symfony, Web Design|Commenti disabilitati su Symfony – Databases and the Doctrine ORM