Advertisement
Google Ad Slot: content-top
Zend OneToOne Relationship
OneToOne Relationship: User ↔ Profile
This means : One User has one Profile, and one Profile belongs to one User.
Step-by-Step Demo (Zend + Doctrine)
1. Inject EntityManager in Controller
Inject EntityManager link
2. Create User Entity (module\Application\src\Entity\User.php)
namespace Application\Entity;
use Application\Entity\Profile;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\OneToOne(targetEntity="Profile", mappedBy="user", cascade={"persist", "remove"})
*/
protected $profile;
// Getters and setters...
public function getId(): ?int { return $this->id; }
public function getName(): ?string { return $this->name; }
public function setName(string $name): self { $this->name = $name; return $this; }
public function getProfile(): ?Profile { return $this->profile; }
public function setProfile(Profile $profile): self { $this->profile = $profile; return $this; }
}
3. Create Profile Entity (module\Application\src\Entity\Profile.php)
namespace Application\Entity;
use Application\Entity\User;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="profiles")
*/
class Profile
{
/** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue */
protected $id;
/** @ORM\Column(type="string") */
protected $phone;
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="profile")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $user;
// Getters and setters...
public function getId(): ?int { return $this->id; }
public function getPhone(): ?string { return $this->phone; }
public function setPhone(string $phone): self { $this->phone = $phone; return $this; }
public function getUser(): ?User { return $this->user; }
public function setUser(User $user): self { $this->user = $user; return $this; }
}
4. Generate Migration
Run this in terminal:
php vendor/bin/doctrine-migrations diff
5. Run Migration
php vendor/bin/doctrine-migrations migrate
This will create:
usersprofiles
Create (Insert) – Saving User with Profile
$user = new User();
$user->setName("Sathish");
$profile = new Profile();
$profile->setPhone("9876543210");
// Set bi-directional relationship
$user->setProfile($profile);
$profile->setUser($user);
$this->entityManager->persist($user);
// No need to persist profile separately if cascade={"persist"} is used
$this->entityManager->flush();
Fetch all users with profiles:
$users = $this->entityManager->getRepository(User::class)->findAll();
foreach ($users as $user) {
echo "User: " . $user->getName() . "<br>";
$profile = $user->getProfile();
if ($profile) {
echo "Phone: " . $profile->getPhone() . "<br>";
}
}
Update User and Profile:
$user = $this->entityManager->getRepository(User::class)->find(1);
if ($user) {
$user->setName("Updated Name");
$profile = $user->getProfile();
if ($profile) {
$profile->setPhone("1234567890");
}
$this->entityManager->flush();
}
Delete User (Profile will auto-delete because of cascade={"remove"})
$user = $entityManager->getRepository(User::class)->find(1);
if ($user) {
$entityManager->remove($user);
$entityManager->flush();
}
This also deletes the profile because of the cascade={"remove"} and onDelete="CASCADE".
Optional: Repository DQL to Join for eager loading
$query = $entityManager->createQuery(
'SELECT u, p
FROM Application\Entity\User u
JOIN u.profile p
WHERE u.id > 0'
);
$users = $query->getResult();
foreach ($users as $user) {
echo $user->getName();
echo $user->getProfile()->getPhone();
}