State Pattern example in PHP
Tags: php, beginners, tutorial, webdev
Published: 2017-09-28 15:12:34

---
title: State Pattern example in PHP
published: true
description: The State pattern is a solution to the problem of how to make behavior depend on state.
tags: PHP,beginner,tutorial,webdev
---

The State pattern is excellent for making the behavior of an object dependent on its state. In my example, it is an elevator that can have the following states:

* Open (Open)
* Closed (Close)
* In Motion (Move)
* Stand (Stop)

From this, the following interface can be derived

```
<?php

namespace Elevator;

interface ElevatorStateInterface
{
    public function open();
    public function close();
    public function move();
    public function stop();
}
```

Now we need a class _ElevatorState_ that implements the interface

```
<?php

namespace Elevator;

class ElevatorState implements ElevatorStateInterface
{
    public function close()
    {
        throw new \Elevator\Exception\IllegalStateTransitionException();
    }

    public function move()
    {
        throw new \Elevator\Exception\IllegalStateTransitionException();
    }

    public function open()
    {
        throw new \Elevator\Exception\IllegalStateTransitionException();
    }

    public function stop()
    {
        throw new \Elevator\Exception\IllegalStateTransitionException();
    }
}
```

By default, all methods throw an exception. In my case it is an _IllegalStateTransitionException_ which inherits from _LogicException_.

Now we can implement the individual states. In this example, the _Move_ state.


```
<?php

namespace Elevator\State;

class Move extends \Elevator\ElevatorState
{
    public function move()
    {
        return new Move();
    }

    public function stop()
    {
        return new Stop();
    }
}
```

As you can see, not all methods are implemented from _ElevatorState_. 
Exactly this, which are not allowed for the current state.

The class _Elevator_

```
<?php

namespace Elevator;

class Elevator
{
    private $state;

    function getState()
    {
        return $this->state;
    }

    function setState(ElevatorStateInterface $state)
    {
        $this->state = $state;
        print "set state to : " . get_class($state) . PHP_EOL;
    }

    public function __construct()
    {
        $this->setState(new \Elevator\State\Stop());
    }

    public function isOpen()
    {
        return $this->state instanceof \Elevator\State\Open;
    }

    public function open()
    {
        $this->setState($this->state->open());
    }

    public function close()
    {
        $this->setState($this->state->close());
    }

    public function move()
    {
        $this->setState($this->state->move());
    }

    public function stop()
    {
        $this->setState($this->state->stop());
    }
}
```

If you call the class with

```
<?php
$elevator = new Elevator\Elevator();
```

it gets the state _Stop_ by the constructor. This means we can switch from this state to the _Open_ state.

```
<?php
$elevator->open();
```

Now, I try this

```
<?php
$elevator->move();
```

An error will happen

```
PHP Fatal error: Uncaught Elevator\Exception\IllegalStateTransitionException
```

because the door must first be closed.

```
<?php
$elevator->close();
```

The complete source of this example is available on [GitHub](https://github.com/mnlwldr/State-Pattern).