Może zdarzyć się, że zaczniesz pracę nad istniejącym projektem, który korzysta z bazy danych. Model jest gotowy, tabele wypełnione danymi, a Ty musisz przygotować CRUDa w frameworku Symfony 🙂 . Na szczęście Doctrine udostępnia magiczne polecenie, które potrafi wygenerować klasy modelu z istniejącej bazy danych.
1 |
php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity |
Dla przykładu wygenerujemy model, a potem CRUDa dla dwóch relacyjnych tabel: user i user_details powiązanych kluczem obcym user_id. Pierwsza tabela przechowuje informacje o użytkowniku i zawiera podstawowe dane, takie jak: id, username i password; a druga – dane personalne, m.in.: firstname, lastname, email.
Zakładam, że masz utworzoną bazę danych i skonfigurowane dostępy w pliku .env. Jeśli tak, to zaczniemy od utworzenia tabel za pomocą polecenia SQL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
CREATE TABLE `user` ( `id` int(10) NOT NULL AUTO_INCREMENT, `username` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; CREATE TABLE `user_details` ( `id` int(10) NOT NULL AUTO_INCREMENT, `user_id` int(10) NOT NULL, `firstname` varchar(50) COLLATE utf8_unicode_ci NULL, `lastname` varchar(50) COLLATE utf8_unicode_ci NULL, `email` varchar(100) COLLATE utf8_unicode_ci NOT NULL, `created_at` datetime NOT NULL, PRIMARY KEY (`id`), KEY `user_details_id_idx` (`user_id`), CONSTRAINT `user__id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; |
Jeśli tabele zostały utworzone prawidłowo, to wygeneruj modele z konsoli wiersza poleceń:
1 |
php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity |
W katalogu src/Entity powinieneś mieć zapisane dwie nowe klasy, a oto ich zawartość:
– src/Entity/User.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * User * * @ORM\Table(name="user") * @ORM\Entity */ class User { /** * @var int * * @ORM\Column(name="id", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; /** * @var string * * @ORM\Column(name="username", type="string", length=50, nullable=false) */ private $username; /** * @var string * * @ORM\Column(name="password", type="string", length=255, nullable=false) */ private $password; } |
– src/Entity/UserDetails.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * UserDetails * * @ORM\Table(name="user_details", indexes={@ORM\Index(name="user_id_idx", columns={"user_id"})}) * @ORM\Entity */ class UserDetails { /** * @var int * * @ORM\Column(name="id", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; /** * @var string|null * * @ORM\Column(name="firstname", type="string", length=50, nullable=true) */ private $firstname; /** * @var string|null * * @ORM\Column(name="lastname", type="string", length=50, nullable=true) */ private $lastname; /** * @var string * * @ORM\Column(name="email", type="string", length=100, nullable=false) */ private $email; /** * @var \DateTime * * @ORM\Column(name="created_at", type="datetime", nullable=false) */ private $createdAt; /** * @var \User * * @ORM\ManyToOne(targetEntity="User") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="user_id", referencedColumnName="id") * }) */ private $user; } |
Jak widać, brakuje nam w klasach tzw. „metod dostępowych”: setterów i getterów, ale możemy je wygenerować również w prosty sposób:
1 |
php bin/console make:entity --regenerate |
Kiedy otworzysz źródło, zobaczysz, że pliki obu klas zostały zaktualizowane o brakujące metody:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * User * * @ORM\Table(name="user") * @ORM\Entity */ class User { /** * @var int * * @ORM\Column(name="id", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; /** * @var string * * @ORM\Column(name="username", type="string", length=50, nullable=false) */ private $username; /** * @var string * * @ORM\Column(name="password", type="string", length=255, nullable=false) */ private $password; public function getId(): ?int { return $this->id; } public function getUsername(): ?string { return $this->username; } public function setUsername(string $username): self { $this->username = $username; return $this; } public function getPassword(): ?string { return $this->password; } public function setPassword(string $password): self { $this->password = $password; return $this; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * UserDetails * * @ORM\Table(name="user_details", indexes={@ORM\Index(name="user_id_idx", columns={"user_id"})}) * @ORM\Entity */ class UserDetails { /** * @var int * * @ORM\Column(name="id", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; /** * @var string|null * * @ORM\Column(name="firstname", type="string", length=50, nullable=true) */ private $firstname; /** * @var string|null * * @ORM\Column(name="lastname", type="string", length=50, nullable=true) */ private $lastname; /** * @var string * * @ORM\Column(name="email", type="string", length=100, nullable=false) */ private $email; /** * @var \DateTime * * @ORM\Column(name="created_at", type="datetime", nullable=false) */ private $createdAt; /** * @var \User * * @ORM\ManyToOne(targetEntity="User") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="user_id", referencedColumnName="id") * }) */ private $user; public function getId(): ?int { return $this->id; } public function getFirstname(): ?string { return $this->firstname; } public function setFirstname(?string $firstname): self { $this->firstname = $firstname; return $this; } public function getLastname(): ?string { return $this->lastname; } public function setLastname(?string $lastname): self { $this->lastname = $lastname; return $this; } public function getEmail(): ?string { return $this->email; } public function setEmail(string $email): self { $this->email = $email; return $this; } public function getCreatedAt(): ?\DateTimeInterface { return $this->createdAt; } public function setCreatedAt(\DateTimeInterface $createdAt): self { $this->createdAt = $createdAt; return $this; } public function getUser(): ?User { return $this->user; } public function setUser(?User $user): self { $this->user = $user; return $this; } } |
W klasie User.php musimy jeszcze dopisać magiczną funkcję PHP: __toString(), która potrafi przekonwertować każdy obiekt na ciąg tekstowy. W naszym przykładzie musimy to zrobić dla nazwy użytkownika: username. Symfony niestety nie zrobi za nas wszystkiego 🙂
1 2 3 4 |
public function __toString() { return $this->username; } |
Na koniec wygenerujmy CRUDa dla klas User i UserDetails:
1 |
php bin/console make:crud |
Polecenie stworzy prymitywny system do zarządzania użytkownikami.
I to wszystko, testuj i do następnego –>