PHP code example of mbolli / php-via

1. Go to this page and download the library: Download mbolli/php-via library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

mbolli / php-via example snippets



Mbolli\PhpVia\Via;
use Mbolli\PhpVia\Config;
use Mbolli\PhpVia\Context;

$config = new Config();
$config->withTemplateDir(__DIR__ . '/templates');
$app = new Via($config); // every with* call goes before this line

$app->page('/', function (Context $c): void {
    $count = $c->signal(0, 'count');
    $step  = $c->signal(1, 'step');

    $c->action(function () use ($count, $step): void {
        $count->setValue($count->int() + $step->int()); // sent to the tab after the action
    }, 'increment');

    $c->view('counter.html.twig');
});

$app->start();

$name = $c->signal('Alice', 'name');
$name->string();          // read
$name->setValue('Bob');    // write; an action sends it to the tab when it ends

$save = $c->action(function () use ($c): void {
    $c->sync();
}, 'save');

$c->view(fn (): string => "<main id=\"hello\">Hello {$name->string()}</main>");
$c->view('dashboard.html.twig', fn (): array => ['user' => $user]);       // needs twig/twig
$c->view('board.html.twig', fn (): array => ['cells' => $cells->array()], block: 'board', shareRender: true);

$app->page('/blog/{year}/{slug}', function (Context $c, string $year, string $slug): void {
    // ...
});

$a = $c->component($counterWidget, 'a');
$b = $c->component($counterWidget, 'b');

$c->onCleanup(fn () => $app->log('info', 'tab closed'));
$c->setInterval(fn () => $c->sync(), 2000);   // stops with the context
$c->spawn(function (Context $c): void {       // work that outlives the action
    $c->getSignal('report')?->setValue(buildReport());
    $c->syncSignals();
});
$app->onClientConnect(fn (Context $c) => $app->broadcast('presence'));
$app->onError(fn (\Throwable $e, ?Context $c, ErrorPhase $phase, ?string $action) => error_log("{$phase->value}: {$e->getMessage()}"));
$app->setInterval(fn () => $app->broadcast(Scope::GLOBAL), 5000); // server-wide timer, on one worker

$app->group('/admin', function (Via $app): void {
    $app->page('/', fn(Context $c) => ...);      // → /admin
    $app->page('/users', fn(Context $c) => ...); // → /admin/users
})->middleware(new AuthMiddleware());

$c->broadcast();                                // the context's primary scope; only this tab when it is TAB
$app->broadcast(Scope::GLOBAL);                 // all contexts
$app->broadcast(Scope::routeScope('/board'));   // one route
$app->broadcast('room:lobby');                  // custom scope
$app->countClients('room:lobby');               // connected tabs it reaches, on every worker

use Mbolli\PhpVia\Broker\RedisBroker;
use Mbolli\PhpVia\Broker\NatsBroker;

// Redis (config->withBroker(new RedisBroker('127.0.0.1', 6379));

// Redis with auth and TLS
$config->withBroker(new RedisBroker(
    host: 'redis.internal',
    password: $_ENV['REDIS_PASSWORD'],
    tls: true,
));

// NATS (raw OpenSwoole socket, no extra extension)
$config->withBroker(new NatsBroker('127.0.0.1', 4222));

// NATS with token auth and TLS
$config->withBroker(new NatsBroker(
    host: 'nats.internal',
    authToken: $_ENV['NATS_TOKEN'],
    tls: true,
));

// Error observability: called on every connection drop
$config->onBrokerError(fn(\Throwable $e) => error_log('Broker: ' . $e->getMessage()));

use Mbolli\PhpVia\Testing\TestApp;

$app = new TestApp(new Config(), function (Via $via): void {
    $via->page('/', function (Context $c): void {
        $count = $c->signal(0, 'count');
        $c->action(fn () => $count->setValue($count->int() + 1), 'increment');
        $c->view(fn (): string => "<main id=\"counter\">{$count->int()}</main>");
    });
});
$tab = $app->open('/');
$tab->action('increment');
assert($tab->signal('count') === 1);
$app->shutdown();

composer  

php app.php
# → http://localhost:3000