Christophe Meneses - Développeur
  • Liste des articles
  • Contact
  • Linkedin
  • Viadeo
  • Github
Tous les articles PHP / Design Pattern Exemple d'utilisation du Proxy
PHP Design Pattern

Exemple d'utilisation du Proxy

Publié le 23/01/2017.

Vous trouverez dans cet article un exemple d'utilisation du patron de conception Proxy en PHP.

Définition

Un proxy est un intermédiaire entre la partie cliente et un objet. Le proxy implémente la même interface que la classe à laquelle il se substitue.

L'utilisation du proxy permet de contrôler l'accès aux méthodes de la classe substituée. Il permet aussi de simplifier l'utilisation d'un objet complexe ou d'éviter de manipuler un objet qui est trop consommateur de ressource.

Exemple

On veut manipuler un objet image. Cependant, on veut éviter de consommer trop de mémoire car nos images peuvent être très lourdes. Le patron de conception Proxy va nous être utile ici.

On commence par créer notre interface qui va être commune au proxy et à l'objet image :

/**
 * Interface ImageInterface
 */
interface ImageInterface
{
    public function display();
}

Elle demande d'implémenter une méthode permettant d'afficher l'image.

Ensuite on crée notre classe Image qui va implémenter cette interface :

/**
 * Class Image
 */
class Image implements ImageInterface
{
    /**
     * @var string
     */
    private $fileName;

    /**
     * Image constructor.
     *
     * @param string $fileName
     */
    public function __construct(string $fileName)
    {
        $this->fileName = $fileName;
        $this->load($fileName);
    }

    /**
     * @inheritdoc
     */
    public function display()
    {
        echo "Affichage de l'image : {$this->fileName}";
    }

    /**
     * @param string $fileName
     */
    private function load(string $fileName)
    {
        // Ici se trouve le code de chargement de l'image
        echo "Chargement de l'image : $fileName";
    }
}

Comme vous pouvez le voir, lorsque l'on instancie la classe Image, le constructeur va automatiquement charger l'image en mémoire. Dans certains cas, on veut pouvoir manipuler un objet image sans que l'image soit chargée directement. La deuxième problématique est que le temps de chargement peut être long. On veut éviter de faire attendre l'utilisateur, surtout si au final, l'image ne va pas être affichée.

L'utilisation d'un proxy va nous permettre de régler ces 2 problèmes :

/**
 * Class ImageProxy
 */
class ImageProxy implements ImageInterface
{
    /**
     * @var string
     */
    private $fileName;

    /**
     * @var Image
     */
    private $image;

    /**
     * ImageProxy constructor.
     *
     * @param string $fileName
     */
    public function __construct(string $fileName)
    {
        $this->fileName = $fileName;
    }

    /**
     * @inheritdoc
     */
    public function display()
    {
        if (!$this->image) {
            $this->image = new Image($this->fileName);
        }

        $this->image->display();
    }
}

Avec ce proxy, l'image va être chargée uniquement si on décide de l'afficher et pas avant. Pour cela, l'objet image est instancié au premier appel de la méthode display().

Il ne reste plus qu'à écrire le code client qui va manipuler le proxy à la place de l'objet lui-même :

$imageProx = new ImageProxy('/home/images/77.png');
$imageProx->display();
$imageProx->display();

On obtient l'affichage ci-dessous. L'image est bien chargée uniquement lors du premier affichage :

Chargement de l'image : /home/images/77.png
Affichage de l'image : /home/images/77.png
Affichage de l'image : /home/images/77.png

Début de l'article

Tous les articles PHP / Design Pattern Exemple d'utilisation du Proxy

Liste des articles par catégorie

  1. Tous 111
  2. Apache2
  3. APC1
  4. Assetic2
  5. Bash2
  6. CentOS9
  7. Composer5
  8. CSS1
  9. Deployer1
  10. Design Pattern11
  11. Docker5
  12. Doctrine13
  13. Elasticsearch3
  14. Git6
  15. Google Charts1
  16. Hardware1
  17. Hébergement1
  18. JavaScript1
  19. jQuery4
  20. Kibana2
  21. Logstash1
  22. Machine Learning1
  23. MariaDB2
  24. Memcached2
  25. MySQL3
  26. Nginx1
  27. PHP56
  28. PHP_CodeSniffer1
  29. PHP-FPM2
  30. PhpMyAdmin1
  31. PhpStorm3
  32. PHPUnit3
  33. PostgreSQL2
  34. RabbitMQ1
  35. SQL1
  36. SVN4
  37. Sybase ASE1
  38. Symfony50
  39. Twig3
  40. Ubuntu14
  41. Vue.js1
  42. Vuex1
  43. Webpack Encore1
  44. Xdebug5

Derniers articles publiés

Vue.js / Vuex
Store : propager une action qui est située dans un module différent

Composer
Composer require se termine par l'erreur "PHP Fatal error : Allowed memory size of x bytes exhausted (tried to allocate x bytes)"

PHP / Design Pattern / PHPUnit
Gérer le temps comme un service pour pouvoir le "mocker" et faciliter les tests unitaires

PHP / Doctrine
Trier une collection d'objet en fonction de la valeur d'un attribut

Ubuntu / MariaDB
Création d'un tunnel SSH avec redirection locale de port

PHP Symfony HTML5 CSS3 JavaScript Bootstrap MySQL

© 2014 - 2019 réalisé par Christophe MENESES