Przetwarzanie w czasie rzeczywistym przez Cocodersów
Czyli potrzymaj mi
i zobacz jak to się robi w PHPie
Po co nam przetwarzanie w czasie rzeczywistym?
Trzeba mu było udowodnić że możemy robić to w PHPie
Jakie możliwości mamy w PHPie odnośnie przetwarzania?
Firebase, Ratchet, Mercure, Pusher, Websocekts, ...
Był sobie projekt...
i klient chciał przetwarzanie w czasie rzeczywistym
Nasz wybór Firebase (Firestore) - bardzo łatwo zintegrować z PHP i Angularem
Firebase vs Firestore
Przykładowy projekt
Beer Menu:
#language: pl
Funkcja:
Jako klient chciałbym móc zobaczyć aktualne menu piwa
Żeby nie chodzić bez sensu do baru
Scenariusz: Nowe piwo w menu
Gdy barman doda nowe piwa:
| nazwa | opis |
| California | California, czyli AIPA w naszym wykonaniu, jest małym amerykańskim snem zamkniętym pod kapslem. To kaskada cytrusowych, kwiatowych aromatów z lekką nutą żywiczności i słodowości, która przeniesie Cię na zachodnie wybrzeże jednego z najpiękniejszych stanów USA. Chmielona amerykańskimi odmianami chmielu, gwarantuje wyraźną, dobrze zbalansowaną i niezalegającą goryczkę. |
Wtedy klient powinien zobaczyć 1 piwo
#language: pl
Funkcja:
Jako klient chciałbym móc zobaczyć aktualne menu piwa
Żeby nie chodzić bez sensu do baru
Scenariusz: Piwo dostępne w menu się skończyło
Zakładając że barman dodał piwa:
| nazwa | opis |
| California | California, czyli AIPA w naszym wykonaniu, jest małym amerykańskim snem zamkniętym pod kapslem. To kaskada cytrusowych, kwiatowych aromatów z lekką nutą żywiczności i słodowości, która przeniesie Cię na zachodnie wybrzeże jednego z najpiękniejszych stanów USA. Chmielona amerykańskimi odmianami chmielu, gwarantuje wyraźną, dobrze zbalansowaną i niezalegającą goryczkę. |
| Harry | Harry wyjechał na studia do USA. Jako anglik pijał herbatę earl grey, ale musiał się dostosować do amerykanów, którzy bardziej niż herbatę, lubią piwo. Specjalnie dla Harry`ego uwarzyliśmy lekkie, jasne piwo o niskiej goryczy i wyraźnym, ale nie dominującym charakterze herbaty earl-grey.|
| Nonsens Pils | Klasyczny pils z małym twistem w postaci herbaty earl grey. Uwarzony dla Pubu Nonsens w Gdyni. |
Kiedy barman stwierdzi, że piwo "California" się skończyło
Wtedy klient powinien zobaczyć 2 piwa
Implementacja PHP
Nowy projekt firebase
composer require google/cloud-firestore
Konfiguracja kluczy dla projektu firebase w Symfony
<?php
protected function execute(
InputInterface $input,
OutputInterface $output
): void {
$beerName = $input->getArgument('beerName');
if (isset($this->availableBeers[$beerName])) {
$this->beers->inStock($this->availableBeers[strtolower($beerName)]);
}
}
<?php
declare(strict_types=1);
namespace App\BeerMenu\Model;
interface Beers
{
public function inStock(Beer $beer): void;
public function stockOut(string $beerName): void;
}
<?php
declare(strict_types=1);
namespace App\BeerMenu\Query;
interface CurrentMenuQuery
{
public function count(): int;
}
<?php
declare(strict_types=1);
namespace App\BeerMenu\Infrastructure\Firestore;
use App\BeerMenu\Model\Beer;
use App\BeerMenu\Model\Beers as BeersInterface;
use Google\Cloud\Firestore\FirestoreClient;
class Beers implements BeersInterface
{
public function inStock(Beer $beer): void
{
$firestore = new FirestoreClient();
$docRef = $firestore->collection('beers')->document($beer->name());
$docRef->set([
'name' => $beer->name(),
'description' => $beer->description(),
]);
}
public function stockOut(string $beerName): void
{
$firestore = new FirestoreClient();
$docRef = $firestore->collection('beers')->document($beerName);
$docRef->delete();
}
}
<?php
declare(strict_types=1);
namespace App\BeerMenu\Infrastructure\Firestore;
use App\BeerMenu\Query\CurrentMenuQuery as CurrentMenuQueryInterface;
use Google\Cloud\Firestore\FirestoreClient;
class CurrentMenuQuery implements CurrentMenuQueryInterface
{
public function count(): int
{
$firestore = new FirestoreClient();
return $firestore->collection('beers')->documents()->size();
}
}
Implementacja Angular
npm install @angular/fire firebase --save
Konfiguracja w połączenia do firebase w pliku environment
import { Component } from '@angular/core';
import { BeersService } from '../beers.service';
@Component({
selector: 'app-beers',
templateUrl: './beers.component.html',
styleUrls: ['./beers.component.scss']
})
export class BeersComponent {
beers$ = this.beersService.beers$;
constructor(private beersService: BeersService) { }
}
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
import { AngularFirestore } from '@angular/fire/firestore';
export interface Beer {
name: string;
description: string;
}
@Injectable({
providedIn: 'root'
})
export class BeersService {
beers$ = this.db.collection<Beer>('beers').valueChanges();
constructor(private db: AngularFirestore) { }
}
Demo
https://bit.ly/2YzJsS3
Nasze przypadki użycia
Architektura
Nasze problemy
Rozwiązanie naszych problemów
Dzięki!
Pora na piwo!
Przetwarzanie w czasie rzeczywistym przez Cocodersów - czyli potrzymaj mi piwo i zobacz jak robimy to w PHPie
By Leszek Prabucki
Przetwarzanie w czasie rzeczywistym przez Cocodersów - czyli potrzymaj mi piwo i zobacz jak robimy to w PHPie
- 712