PHPackages                             cubiche/visitor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. cubiche/visitor

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

cubiche/visitor
===============

Visitor library

1912PHP

Since Apr 20Pushed 9y ago2 watchersCompare

[ Source](https://github.com/cubiche/visitor)[ Packagist](https://packagist.org/packages/cubiche/visitor)[ RSS](/packages/cubiche-visitor/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependenciesVersions (18)Used By (0)

Cubiche/Visitor
===============

[](#cubichevisitor)

[![Build Status](https://camo.githubusercontent.com/64b301ac5257964dc06a9c61bfb29cc6e8bbec82182c63aa2404a352cab60ef2/68747470733a2f2f7472617669732d63692e6f72672f637562696368652f76697369746f722e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/cubiche/visitor) [![Coverage Status](https://camo.githubusercontent.com/92420acc4691429063e9f0d51347d36ec3593273405834f928544eca75d8b19c/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f637562696368652f76697369746f722f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/cubiche/visitor?branch=master) [![Scrutinizer Code Quality](https://camo.githubusercontent.com/34a80e4fc9b260758b652cafc0d4964308ed68c25f2e76437c2bda41ef71680b/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f637562696368652f76697369746f722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/cubiche/visitor/?branch=master)

A [visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern) implementation in PHP, using a [Dynamic dispatch](https://en.wikipedia.org/wiki/Dynamic_dispatch)mechanism.

Installation
------------

[](#installation)

Via [Composer](http://getcomposer.org/)

```
$ composer require cubiche/visitor:dev-master
```

Basic usage
-----------

[](#basic-usage)

Arithmetic expressions calculator

```
use Cubiche\Core\Visitor\Visitee;
use Cubiche\Core\Visitor\Visitor;

abstract class Expression extends Visitee {}

abstract class Operator extends Expression
{
    protected $operator;
    protected $firstOperand;
    protected $secondOperand;

    public function __construct($operator, Expression $firstOperand, Expression $secondOperand)
    {
        $this->operator = $operator;
        $this->firstOperand = $firstOperand;
        $this->secondOperand = $secondOperand;
    }

    public function operator()
    {
        return $this->operator;
    }

    public function firstOperand()
    {
        return $this->firstOperand;
    }

    public function secondOperand()
    {
        return $this->secondOperand;
    }
}

class Sum extends Operator
{
    public function __construct(Expression $firstOperand, Expression $secondOperand)
    {
        parent::__construct('+', $firstOperand, $secondOperand);
    }
}

class Mult extends Operator
{
    public function __construct(Expression $firstOperand, Expression $secondOperand)
    {
      parent::__construct('*', $firstOperand, $secondOperand);
    }
}

class Value extends Expression
{
    protected $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function value()
    {
        return $this->value;
    }
}

class Variable extends Expression
{
    protected $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function name()
    {
        return $this->name;
    }
}

class Calculator extends Visitor
{
    public function visitSum(Sum $sum)
    {
        return $sum->firstOperand()->accept($this) + $sum->secondOperand()->accept($this);
    }

    public function visitMult(Mult $mult)
    {
        return $mult->firstOperand()->accept($this) * $mult->secondOperand()->accept($this);
    }

    public function visitValue(Value $value)
    {
        return $value->value();
    }
}

$expression = new Sum(
    new Value(5),
    new Mult(
        new Value(3),
        new Value(2)
    )
);

$calculator = new Calculator();
$result = $expression->accept($calculator);
```

Visit parent class
------------------

[](#visit-parent-class)

```
use Cubiche\Core\Visitor\Visitor;

class ExpressionToStringConverter extends Visitor
{
    public function visitOperator(Operator $op)
    {
        return '('.$op->firstOperand()->accept($this).$op->operator().$op->secondOperand()->accept($this).')';
    }

    public function visitValue(Value $value)
    {
        return (string) $value->value();
    }

    public function visitVariable(Variable $variable)
    {
        return $variable->name();
    }
}

$expression = new Sum(
    new Value(5),
    new Mult(
        new Value(3),
        new Value(2)
    )
);

$converter = new ExpressionToStringConverter();
echo $expression->accept($converter);
```

Note that the `visitOperator` method is invoked when an operator(`Sum` or `Mult`) is visited.

Passing parameters to visit methods
-----------------------------------

[](#passing-parameters-to-visit-methods)

```
class SmartExpressionToStringConverter extends ExpressionToStringConverter
{
    public function visitOperator(Operator $op, $parentOperator = null)
    {
        $currentOperator = $op->operator();
        $expression = $op->firstOperand()->accept($this, $currentOperator).
            $currentOperator.$op->secondOperand()->accept($this, $currentOperator);

        return $this->requireParentheses($currentOperator, $parentOperator) ? '('.$expression.')' : $expression;
    }

    protected function requireParentheses($currentOperator, $parentOperator)
    {
        return $currentOperator === '+' && $parentOperator === '*';
    }
}
$expression = new Sum(
    new Value(5),
    new Mult(
        new Value(3),
        new Value(2)
    )
);

$converter = new SmartExpressionToStringConverter();
echo $expression->accept($converter);
```

Extending another visitor without inheritance
---------------------------------------------

[](#extending-another-visitor-without-inheritance)

```
use Cubiche\Core\Visitor\LinkedVisitor;

class Evaluator extends LinkedVisitor
{
    protected $variables;

    public function __construct(Calculator $calculator, $variables = array())
    {
        parent::__construct($calculator);
        $this->variables = $variables;
    }

    public function visitVariable(Variable $variable)
    {
        if (isset($this->variables[$variable->name()])) {
            return $this->variables[$variable->name()];
        }
        throw new \Exception(\sprintf("Unknown variable '%s'", $variable->name()));
    }
}

$expression = new Mult(
    new Variable('x'),
    new Sum(
        new Value(5),
        new Mult(
            new Variable('y'),
            new Value(2)
        )
    )
);

$variables = array('x' => 10, 'y' => -7);
$evaluator = new Evaluator(new Calculator(), $variables);
$converter = new SmartExpressionToStringConverter();
echo $expression->accept($converter).' = '.$expression->accept($evaluator).PHP_EOL;
```

Note that the `Evaluator` can only visit the `Variable` instances and delegate in `Calculator` the others expressions.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 52.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/8a1538b807c5f51942d07ef9f1a0e3da5cdfa3de27d493edd9857fdf9e1810d4?d=identicon)[osorioramirez](/maintainers/osorioramirez)

---

Top Contributors

[![osorioramirez](https://avatars.githubusercontent.com/u/4730587?v=4)](https://github.com/osorioramirez "osorioramirez (9 commits)")[![ivannis](https://avatars.githubusercontent.com/u/754477?v=4)](https://github.com/ivannis "ivannis (8 commits)")

### Embed Badge

![Health badge](/badges/cubiche-visitor/health.svg)

```
[![Health](https://phpackages.com/badges/cubiche-visitor/health.svg)](https://phpackages.com/packages/cubiche-visitor)
```

###  Alternatives

[jjgrainger/wp-crumbs

Simple Wordpress Breadcrumbs.

3910.9k](/packages/jjgrainger-wp-crumbs)[wantp/snowflake

A package for create unique id by snowflake

399.5k1](/packages/wantp-snowflake)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
