MT5 gRPC PHP8.1 client example
Table of Contents
						
						Preparations.
Install PHP8.1

Install grpc pecl package for Linux.
sudo pecl install grpc
Add to php.ini:
extension=grpc.so
Install PHP gRPC package for Windows
- go to https://pecl.php.net/package/gRPC
 - download the package for your operation system and PHP version. For example 8.1 for Windows
 - paste it to the PHP extension folder

 - update php.ini with this package
extension=grpc - generate gRPC libraries by composer
composer install
You would see verndor folder - check mt5.proto exists in the project folder and generate MT5 client gRPC libraries.
for Windowsdocker run -v ${pwd}:/defs namely/protoc-all -f ./mt5.proto -l php -o generatedfor Linux
docker run -v PWD:/defs namely/protoc-all -f ./mt4.proto -l php -o generatedAutogenerated PHP8.1 client libraries (if you don't want to do it yorself)
 
You would see generated folder

Now we are ready for execution
php.exe -dxdebug.remote_enable=1 -dxdebug.remote_mode=req -dxdebug.remote_port=9000 -dxdebug.remote_host=127.0.0.1 -dxdebug.mode=debug -dxdebug.client_port=9000 -dxdebug.client_host=127.0.0.1 E:\MT4Repositories\grpc-proto\mt5\phpExample\index.php

Full script
<?php
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/generated/GPBMetadata/Mt5.php';
$files = glob(__DIR__ . '/generated/Mt5grpc/*.php');
foreach ($files as $file) {
    require($file);
}
// Connecting to the Mt5 server
$serviceConnectionClient = new Mt5grpc\ConnectionClient('mt5grpc.mtapi.io:443', ['credentials' => Grpc\ChannelCredentials::createSsl()]);
$connectionRequest = new Mt5grpc\ConnectRequest();
$connectionRequest -> setHost("78.140.180.198");
$connectionRequest -> setPassword("tecimil4");
$connectionRequest -> setPort("443");
$connectionRequest -> setUser(62333850);
list($connectionResponse, $status) = $serviceConnectionClient->Connect($connectionRequest)->wait();
/** @var Mt5grpc\Error $connectionError */
$connectionError = $connectionResponse->getError();
$connectionResult = $connectionResponse->getResult();
if (is_null($connectionError)) {
    print($connectionResult);
    print("\n");
} else {
    print($connectionError->getMessage() . "\n");
    print('Press enter to exit...');
    fgets(STDIN);
    exit;
}
// Getting account balance
$serviceMt5 = new Mt5grpc\MT5Client('mt5grpc.mtapi.io:443', ['credentials' => Grpc\ChannelCredentials::createSsl()]);
$req = new Mt5grpc\AccountSummaryRequest();
$req->setId($connectionResult);
list($response, $status) = $serviceMt5->AccountSummary($req)->wait();
/** @var Mt5grpc\AccountSummaryReply $reply */
$reply = $response;
/** @var Mt5grpc\Error $error */
$error = $reply->getError();
/** @var Mt5grpc\AccountSummary $result */
$result = $reply->getResult();
if (is_null($error)) {
    print($result->getBalance() . ",");
    print("\n");
} else {
    print($error->getMessage() . "\n");
    print('Press enter to exit...');
    fgets(STDIN);
    exit;
}
// Subscribing on the quote
$serviceSubscriptionClient = new Mt5grpc\SubscriptionsClient('mt5grpc.mtapi.io:443', ['credentials' => Grpc\ChannelCredentials::createSsl()]);
$subscribeReq = new Mt5grpc\SubscribeRequest();
$subscribeReq -> setId($connectionResult);
$subscribeReq -> setInterval(0);
$subscribeReq -> setSymbol("EURUSD");
list($subscriptionResponse, $status) = $serviceSubscriptionClient->Subscribe($subscribeReq)->wait();
/** @var Mt5grpc\Error $subscriptionError */
$subscriptionError = $subscriptionResponse->getError();
$subscriptionResult = $subscriptionResponse->getResult();
/** @var Mt5grpc\SubscribeReply $subscriptionResult */
if (is_null($subscriptionError)) {
    print($subscriptionResult . ",");
    print("\n");
} else {
    print($subscriptionError->getMessage() . "\n");
    print('Press enter to exit...');
    fgets(STDIN);
    exit;
}
// Receiving quotes
$streamsClient = new Mt5grpc\StreamsClient('mt5grpc.mtapi.io:443', ['credentials' => Grpc\ChannelCredentials::createSsl()]);
$OnQuoteReq = new Mt5grpc\OnQuoteRequest();
$OnQuoteReq -> setId($connectionResult);
$call = $streamsClient->OnQuote($OnQuoteReq);
$quotes = $call->responses();
foreach ($quotes as $quote) {
    // process each quote
    /** @var Mt5grpc\Error $onQuoteError */
    $onQuoteError = $quote->getError();
    if (is_null($onQuoteError)) {
        $quoteData = $quote->getResult();
        if (is_null($quoteData)) {
            print("Quote is empty");
        }
        else {
            /** @var Mt5grpc\Quote $quoteData */
            $symbol = $quoteData->getSymbol();
            $bid = $quoteData->getBid();
            $ask = $quoteData->getAsk();
            $time = $quoteData->getTime();
            $last = $quoteData->getLast();
            $volume = $quoteData->getVolume();
            print("Symbol:" . $symbol . ",");
            print("Bid:" . $bid . ",");
            print("Ask:" . $ask . ",");
            // Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive.
            $secondsSince1970 = $time->getSeconds();
            $adate="Thu Jan 1 07:59:59 1970";
            $dateinsec=strtotime($adate);
            $newdate=$dateinsec+$secondsSince1970;
            print("Time:" . date('D M H:i:s Y',$newdate) . ",");
            print("Last:" . $last . ",");
            print("Volume:" . $volume . ",");
        }
        print("\n");
    } else {
        print($onQuoteError->getMessage() . "\n");
        print('Press enter to exit...');
        fgets(STDIN);
        exit;
    }
}
print('Press enter to exit...');
fgets(STDIN);
        