Skip to content

Instantly share code, notes, and snippets.

@garethellis36
Last active February 25, 2019 12:38
Show Gist options
  • Save garethellis36/a98f41274f85993bcc8d15b3d1667106 to your computer and use it in GitHub Desktop.
Save garethellis36/a98f41274f85993bcc8d15b3d1667106 to your computer and use it in GitHub Desktop.
LSP example in PHP
LSP: "Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program."
<?php
namespace App\User;
// imagine the following interface
interface Repository
{
public function getById($id);
}
// without parameter type-hints, return types, or even a doc-block, it is impossible for client code to be able
// to rely on the correctness of the implementation
// a programmer trying to implement this interface will be having to guess at what to return, what to accept, etc.
// it would be very easy to inadvertently create an implementation which breaches LSP and causes problems for client code
// We can address this by adding parameter type-hints and a return type
interface Repository
{
/**
* @throws \App\User\Error\NotFound
*/
public function getById(int $id): User;
}
// Note that we have also added a @throws annotation.
// According to the definition of the interface, client code should be able to reliably work as follows:
try {
$user = $repository->getById($id);
} catch (NotFound $e) {
// handle exception
}
// It is still possible to breach LSP even with parameter type-hints and return types in place
// The following implementation would be a breach of LSP
// Even though it meets the interface implementation according to PHP's language-level requirements,
// it throws something which is not defined by the behaviour of the `Repository` type.
// The above client code would break because it is not expecting to need to catch an exception of type \Exception
class Database implements Repository
{
public function getById(int $id): User
{
$row = $this->db->query("SELECT * FROM users WHERE id = ?", [$id]);
if ($row) {
return User::fromRow($row);
}
throw new \Exception("User not found!");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment