Web Design

Symfony – Load Security Users from the Database – Doctrine

Caricare gli utenti attivi da un database con Symfony e Doctrine.
Il codice è solo teorico, non è pronto all’uso.
Vedere la lezione successiva ‘Symfony – Simple Registration Form – Doctrine’ per testare del codice pronto all’uso.

1. Creiamo il Database da PhpMyAdmin:

Database: test_project
Tabella: app_users
Campi:
– Id char(11) AUTO_INCREMENT
– username char (25) UNIQUE
– password char (60) UNIQUE
– email char (60) UNIQUE
– is_active BOOLEAN -> se l’utente è abilitato

2. Creiamo l’entità src/AppBundle/Entity/User.php


<?php

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

// namespace per usare Doctrine
use Doctrine\ORM\Mapping as ORM; 
// namespace per gestire gli Utenti e ottenere le password criptate
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * @ORM\Table(name="app_users")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 */

// implements aggiunge questi metodi a UserInterface di Symfony
class User implements UserInterface, \Serializable
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=25, unique=true)
     */
    private $username;

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

    /**
     * @ORM\Column(type="string", length=60, unique=true)
     */
    private $email;

    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive;

    public function __construct()
    {
        $this->isActive = true; // costruttore se l'utente è attivo
        // may not be needed, see section on salt below
        // $this->salt = md5(uniqid(null, true));
    }

    public function getUsername()
    {
        return $this->username;
    }

    // il seme o sale utilizzato per l'encode della password    
    // se uso bcrypt non è necessario perchè gestisce il seme automaticamente, e il metodo ritorna null
    public function getSalt() 
    {
        // you *may* need a real salt depending on your encoder
        // see section on salt below
        return null;
    }

    public function getPassword()
    {
        return $this->password;
    }

    public function getRoles()// i ruli concessi all'utente
    {
        return array('ROLE_USER');
    }

    public function eraseCredentials()// rimuove i dati sensibili dell'utente
    {
    }

    // Serialize
    // Alla fine di ogni - request - l'oggetto User viene trasformato in un array (serialize) e salvato nella sessione
    // Alla richiesta successiva viene ricaricato dalla sessione e riconvertito (unserialize)
    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
            // see section on salt below
            // $this->salt,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            // see section on salt below
            // $this->salt
        ) = unserialize($serialized);
    }
}

3. Modifichiamo app/config/security.yml


# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html

# app/config/security.yml
security:
    encoders:
        AppBundle\Entity\User:
            algorithm: bcrypt

    # http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
    providers:
        in_memory:
            memory: ~
        test_project:
            entity:
                class: AppBundle:User
                property: username
                # if you're using multiple entity managers
                # manager_name: customer

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            anonymous: ~
            # activate different ways to authenticate
            pattern:    ^/
            http_basic: ~
           

            # http://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
            #http_basic: ~

            # http://symfony.com/doc/current/cookbook/security/form_login_setup.html
            #form_login: ~

Configuro i parametri di security per puntare a User.php


security:
    encoders:
        AppBundle\Entity\User:
            algorithm: bcrypt

...

test-project:
    entity:
         class: AppBundle:User
                property: username

Bibliografia:
symfony.com/doc/current/security/entity_provider.html#security-serialize-equatable
api.symfony.com/3.2/Symfony/Component/Security/Core/User/UserInterface.html#method_getRoles

By |MySQL, PHP, Symfony, Web Design|Commenti disabilitati su Symfony – Load Security Users from the Database – Doctrine

Symfony – PHP Sessions Management

Come gestire con Symfony le variabili di sessione.

Cos’è una PHP Session?

La variabile di sessione di PHP ci permette di salvare temporaneamente le informazioni di navigazione (es: username, color etc…) all’interno del server.
La variabile sarà cancellata alla chiusura del browser.

1. pagina uno che setta le variabili


<?php
// 1. inizializzo la sessione
session_start();

// 2. con la variabile globale $_SESSION assegno alla variabile 'username' il valore 'andrea'
$_SESSION["username"] = "andrea";

Con session_start(); il server assegna al mio PC un codice chiave simile a ‘765487cf34ert8dede5a562e4f3a7e12’ che distruggerà alla chiusura del browser.

Una volta assegnato l’identificativo la variabile e il suo valore saranno salvati sul server, ora potremo recuperare i dati da qualsiasi altra pagina con il codice seguente:

2. pagina due che ottiene le variabili


<?php
// 1. inizializzo la sessione
session_start();

// 2.
echo "Username is " . $_SESSION["username"];
print_r($_SESSION); // debug visualizza tutte le variabili di sessione

// 3. to change a session variable, just overwrite it 
$_SESSION["username"] = "Gianni";

// 4. remove all session variables
session_unset(); 

// 5. destroy the session 
session_destroy();

Symfony PHP Session senza sessioni ereditate (NO Legacy Sessions)

IMPORTANTE:
– NON deve essere già presente una sessione già inizializzata.
– NON utilizzare la sintassi PHP classica, è incompatibile con Symfony!!!

Symfony NON accede direttamente alla funzione globale $_SESSION di php perchè gestiche i dati tramite un oggetto proprietario ‘FlashBag()’ sebbene Symfony salvi anche il contenuto di $_SESSION quando la sessione viene salvata.


<?php

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

use Symfony\Component\HttpFoundation\Response; // namespace di Symfony per response()
use Symfony\Component\HttpFoundation\Session\Session; // namespace per le sessioni

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;// namespace per utilizzare @Route

class SessionsTest{
    
    /**
    * @Route("/sessiontest")
    */
    public function sessionAction()
    {
        echo 'Test Sessioni INIZIO<br>';
        
        // istanzio la classe di Symfony per le sessioni
        $session = new Session();
        // inizio la sessione
        $session->start();

        // salvo la variabile 'name' con il valore 'Andrea'
        $session->set('name', 'Andrea');
        // ottengo la variabile 'name'
        $username = $session->get('name');
        
        echo  'Username = ' . $username;

        // FlashBag() è un metodo di Symfony per gestire messaggi al visitatore inerenti le sessioni
        // setto un flash messages, assegno a 'notice' il valore 'Profile updated'
        $session->getFlashBag()->add('notice', 'Profile updated');

        // richiamo il messaggio
        //                              -> assegno $message='notice'
        foreach ($session->getFlashBag()->get('notice', array()) as $message) {
            echo '<div class="flash-notice">'.$message.'</div>';
        }
        
        // Renderizza
        /* 
        Test Sessioni INIZIO
        Username = Andrea
        Profile updated
        Test Sessioni FINE
         */
       
        return new Response('Test Sessioni FINE');
    }// END sessionAction()
} // END class SessionsTest {}

Puntare il browser a: http://localhost/symfonytest/first_test_symfony/web/sessiontest

Symfony PHP Session con sessioni ereditate (YES Legacy Sessions)

Se stiamo lavorando con una sessione aperta da un’applicazione PHP che non utilizza il componente HttpFoundation dovremo aggiungere alla nostra pagina Symfony il componente PhpBridgeSessionStorage che ci permette di utilizzare sessioni ereditate da $_SESSION[] di php classico.


// componenti obbligatori per la gestione delle sessioni
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage;

// configua la sessione ereditata 
ini_set('session.save_handler', 'files');
ini_set('session.save_path', '/tmp');
session_start();

// instanzia la classe Session(istanzia la classe PhpBridgeSessionStorage)
$session = new Session(new PhpBridgeSessionStorage());

// symfony ora è compatibile con la sessione precedente ed inizializzo la sessione
$session->start();

Bibliografia:

Sessioni:
http://symfony.com/doc/current/session.html

Sessioni no Legacy:
symfony.com/doc/current/components/http_foundation/sessions.html

Sessioni with Legacy:
symfony.com/doc/current/components/http_foundation/session_php_bridge.html

By |PHP, Symfony, Web Design|Commenti disabilitati su Symfony – PHP Sessions Management

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

Symfony – Sign In – Simple Form with Object – Json – Array

Come creare un semplice form Sign In ed ottenere i dati in JSon

Il template .twig in app/Resources/views/default/new.html.twig


{# app/Resources/views/default/new.html.twig #}
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}

L’entità in src/AppBundle/Entity/Person.php


<?php

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

use Symfony\Component\Validator\Constraints as Assert; // serve per @Assert\...

class Person // dichiarazione esplicita dell'oggetto
{
    // -------------------------------------------------------------------------    
    // Proprietà ---------------------------------------------------------------
    // -------------------------------------------------------------------------
    
    /**
     * @Assert\NotBlank()
     */
    public $name;    
     /**
     * @Assert\NotBlank()
     */
    public $surname; 
    /**
     * @Assert\Email(
     *     message = "The email '{{ value }}' is not a valid email.",
     *     checkMX = true
     * )
     */
    public $email; 
    
    // -------------------------------------------------------------------------
    // Metodi ------------------------------------------------------------------
    // -------------------------------------------------------------------------
    
    // NB metodi get e set obbligatori per permettere a 'Form component' di symfony di funzionare correttamente
    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 getSurname() // ottieni 
    {
        return $this->surname;
    }

    public function setSurname($surname) // setta 
    {
        $this->surname = $surname;
    }
    
    // -------------------------------------------------------------------------
    
     public function getEmail() // ottieni 
    {
        return $this->email;
    }

    public function setEmail($email) // setta 
    {
        $this->email = $email;
    }
    
    // -------------------------------------------------------------------------
}

La classe SignIn in src/AppBundle/Controller/SignIn.php


<?php

// src/AppBundle/Controller/SignIn.php
namespace AppBundle\Controller;
 
use AppBundle\Entity\Person; // carica Person.php creato da me
use Symfony\Bundle\FrameworkBundle\Controller\Controller; // il bundle controller Symfont
use Symfony\Component\HttpFoundation\Request; // capacità do renderizzare html
use Symfony\Component\Form\Extension\Core\Type\TextType; // form di Symfony
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;// NECESSARIO per utilizzare @Route

class SignIn extends Controller // estende la classe Controller di Symfony
{
    /**
    * @Route("/signin")
    */
    public function signInAction(Request $request)
   {
       // creo il nuovo oggetto 
       $person = new Person();
      
       // 1. creo i contenuti HTML del form
       // invio Andrea, Tonin, andrea@email.it
       $form = $this->createFormBuilder($person)
           ->add('name', TextType::class) // il nome delle varibili è lo stesso di Person.php
           ->add('surname', TextType::class) 
           ->add('email', TextType::class) 
           ->add('save', SubmitType::class, array('label' => 'Create Person'))
           ->getForm();
        
       // 3. riconosce che il form non è stato inviato e non fa nulla
       $form->handleRequest($request); 
        
       // 4. se il form è inviato AND valido
       if ($form->isSubmitted() && $form->isValid()) {
           // $form->getData() holds the submitted values
           // but, the original `$person` variable has also been updated
           $person = $form->getData();// ottieni i dati dal form
           
           // debug START ######################################################
           // Oggetto originale
           var_dump($person);  // mostra l'oggetto
           var_dump($person->name);  // mostra la varianbile name all'interno dell'oggetto
           // Conversione Json - NOTAZIONE JSON - è utile per trasportare i dati all'interno di una stringa
           $personJson = json_encode($person); // oggetto convertito in json format
           var_dump ($personJson); // mostra in json
           // Decodifica JSon - TORNA AD ESSERE UN OGGETTO
           $personDecoded = json_decode($personJson);
           var_dump ($personDecoded);
           var_dump($personDecoded->name);  // mostra la varianbile name all'interno dell'oggetto
           
           // Dummy Data, instanzio la classe inviando dei dati di esempio
            $anotherPerson = new Person();
            $anotherPerson->name = "Erica";
            $anotherPerson->surname = "Tonin";
            $anotherPerson->email = "erica@email.it";
           
           // Array
           $people =[]; // creo un array di persone vuoto
           array_push($people,$anotherPerson); // aggiungo id=0 dell'array
           array_push($people,$person); // aggiungo id=1 dell'array
           var_dump ($people); // visualizza il contenuto dell'array
           var_dump ($people[1]->name); // visualizzerà Andrea, array id 1 chiave name
           
           // altre operazioni con gli array
           // conta gli oggetti all'interno dell'array, visualizzerà 2
           var_dump(count($people)); 
           
           // renderizza tutto il contenuto dell'array di oggetti
           for ($i = 0; $i < count($people); $i++)// conteggia tutto il contenuto
           {
            echo $i . " " . ($people[$i]->name) . " " . ($people[$i]->surname) . " " . ($people[$i]->email) . "<br>";
           }
           
           // renderizza solo ad una particolare condizione
           for ($i = 0; $i < count($people); $i++)// conteggia tutto il contenuto
           {
                if (($people[$i]->name) === 'Erica') // se il valore è identico
                {
                echo 'La email di Erica è: ' . ($people[$i]->email) . "<br>";
                }
           }
           
           die ("Stop Here");  // interrompi qui la funzione
           // debug END ########################################################
       }// END validation
 
       // 2. Il form viene creato e renderizzato
       return $this->render('default/new.html.twig', array(
           'form' => $form->createView(),
       ));
   }   
    
}// END class SignIn

Puntare il browser a: http://localhost/symfonytest/first_test_symfony/web/signin

Inserire i dati ed inviare, verrà stampato a video:


C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\SignIn.php:45:
object(AppBundle\Entity\Person)[316]
  public 'name' => string 'Andrea' (length=6)
  public 'surname' => string 'Tonin' (length=5)
  public 'email' => string 'andrea@email.it' (length=15)

C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\SignIn.php:46:string 'Andrea' (length=6)

C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\SignIn.php:49:string '{"name":"Andrea","surname":"Tonin","email":"andrea@email.it"}' (length=61)

C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\SignIn.php:52:
object(stdClass)[390]
  public 'name' => string 'Andrea' (length=6)
  public 'surname' => string 'Tonin' (length=5)
  public 'email' => string 'andrea@email.it' (length=15)

C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\SignIn.php:53:string 'Andrea' (length=6)

C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\SignIn.php:65:
array (size=2)
  0 => 
    object(AppBundle\Entity\Person)[372]
      public 'name' => string 'Erica' (length=5)
      public 'surname' => string 'Tonin' (length=5)
      public 'email' => string 'erica@email.it' (length=14)
  1 => 
    object(AppBundle\Entity\Person)[316]
      public 'name' => string 'Andrea' (length=6)
      public 'surname' => string 'Tonin' (length=5)
      public 'email' => string 'andrea@email.it' (length=15)

C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\SignIn.php:66:string 'Andrea' (length=6)

C:\wamp64\www\symfonytest\first_test_symfony\src\AppBundle\Controller\SignIn.php:70:int 2

0 Erica Tonin erica@email.it
1 Andrea Tonin andrea@email.it
La email di Erica è: erica@email.it

Stop Here

Come funziona?

1. Istanziata la classe $person = new Person(); e creato l’oggetto $person, vuoto, cone le sole chiavi.

2. Creato il form con il metodo di Symfony createFormBuilder()

3. Renderizzato il form con il metodo di Symfony return $this->render()

4. Invio i dati dal form, il metodo handleRequest($request); verifica che è stato inviato e aggiorna $person

5. Il contenuto di $person viene validato nell’entità Person.php

6. In signIn.php se $person è stato inviato ed è valido: $person = $form->getData();

7. nella sezione di debug gioco un po con i dati:
– mostro il dato come oggetto
– codifico il dato come json
– decodifico il dato da json
– creo un nuovo oggetto istanziando $anotherPerson = new Person();
– creo un array vuoto $people =[]
– inserisco nell’array i 2 oggetti precedentemente creati
– visualizzo i contenuti secondo la sintassi:

$people[1]->name
nomearray[id]->keyword

Il mio sito ufficiale: lucedigitale.com

By |JSON, PHP, Symfony, Web Design|Commenti disabilitati su Symfony – Sign In – Simple Form with Object – Json – Array