Skip to content

Commit

Permalink
Add CurlTransport (#142)
Browse files Browse the repository at this point in the history
  • Loading branch information
vjik authored Feb 11, 2025
1 parent e5d336c commit 20dbc52
Show file tree
Hide file tree
Showing 14 changed files with 634 additions and 35 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# phpstorm
# PhpStorm
.idea

# composer
# Composer
/vendor
/composer.lock

# PhpUnit
# PHPUnit
/phpunit.phar
/phpunit.xml
/.phpunit.cache
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Telegram Bot API for PHP Change Log

## 0.7.1 under development

- New #142: Add `CurlTransport`.

## 0.7.0 February 10, 2025

- New #139: Add `RawValue` value processor.
Expand Down
41 changes: 13 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,46 +26,30 @@ composer require vjik/telegram-bot-api
## General usage

To make requests to the Telegram Bot API, you need to create an instance of the `TelegramBotApi` class
that requires an instance of the `TransportInterface` implementation. Out of the box, the package provides
`PsrTransport` based on the [PSR-18](https://www.php-fig.org/psr/psr-18/) HTTP client and [PSR-17](https://www.php-fig.org/psr/psr-17/) HTTP factories.
that requires an implementation of the `TransportInterface`.

For example, you can use the [php-http/curl-client](https://github.com/php-http/curl-client) and [httpsoft/http-message](https://github.com/httpsoft/http-message):
The package provides two transport out of the box:

```shell
composer require php-http/curl-client httpsoft/http-message
```
- [`CurlTransport`](docs/transport.md#curl) that requires PHP [cURL](https://www.php.net/manual/book.curl.php) extension;
- [`PsrTransport`](docs/transport.md#psr) based on the [PSR-18](https://www.php-fig.org/psr/psr-18/) HTTP client and [PSR-17](https://www.php-fig.org/psr/psr-17/) HTTP factories.

In this case, a `TelegramBotApi` instance can be created as follows:
Since the cURL extension is included in most PHP installations, `CurlTransport` is often the easiest choice.

```php
use Http\Client\Curl\Client;
use HttpSoft\Message\RequestFactory;
use HttpSoft\Message\ResponseFactory;
use HttpSoft\Message\StreamFactory;
use Vjik\TelegramBot\Api\Transport\PsrTransport;
use Vjik\TelegramBot\Api\Transport\Curl\CurlTransport;
use Vjik\TelegramBot\Api\TelegramBotApi;

// Telegram bot authentication token
$token = '110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw';

// Dependencies
$streamFactory = new StreamFactory();
$responseFactory = new ResponseFactory();
$requestFactory = new RequestFactory();
$client = new Client($responseFactory, $streamFactory);

// API
$api = new TelegramBotApi(
new PsrTransport(
$token,
$client,
$requestFactory,
$streamFactory,
),
new CurlTransport(
// Telegram bot authentication token
'110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw'
)
);
```

Now you can use the `$api` instance to interact with the Telegram Bot API. Method names are the same as in the [Telegram Bot API documentation](https://core.telegram.org/bots/api). For example:
Now you can use the `$api` instance to interact with the Telegram Bot API. Method names are the same as in
the [Telegram Bot API documentation](https://core.telegram.org/bots/api). For example:

```php
use Vjik\TelegramBot\Api\Type\InputFile
Expand Down Expand Up @@ -95,6 +79,7 @@ $updates = $api->getUpdates();

## Documentation

- [Transport](docs/transport.md)
- [Logging](docs/logging.md)
- [Webhook handling](docs/webhook-handling.md)
- [Custom requests](docs/custom-requests.md)
Expand Down
17 changes: 17 additions & 0 deletions composer-require-checker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"symbol-whitelist" : [],
"php-core-extensions" : [
"Core",
"date",
"json",
"hash",
"pcre",
"Phar",
"Reflection",
"SPL",
"random",
"standard",
"curl"
],
"scan-files" : []
}
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"psr/http-message": "^1.1 || ^2.0"
},
"require-dev": {
"ext-curl": "*",
"bamarni/composer-bin-plugin": "^1.8.2",
"httpsoft/http-message": "^1.1.6",
"php-http/curl-client": "^2.3.3",
Expand All @@ -36,7 +37,8 @@
"yiisoft/test-support": "^3.0.1"
},
"suggest": {
"psr/log": "To log requests to Telegram Bot API and response handling errors."
"psr/log": "To log requests to Telegram Bot API and response handling errors.",
"ext-curl": "To use `CurlTransport`."
},
"autoload": {
"psr-4": {
Expand All @@ -49,7 +51,8 @@
}
},
"scripts": {
"cs-fix": "php-cs-fixer fix"
"cs-fix": "php-cs-fixer fix",
"infection": "infection --only-covered"
},
"extra": {
"bamarni-bin": {
Expand Down
2 changes: 1 addition & 1 deletion docs/internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The package is tested with [PHPUnit](https://phpunit.de/). To run tests:
The package tests are checked with [Infection](https://infection.github.io/) mutation framework. To run it:

```shell
./vendor/bin/infection
composer infection
```

## Static analysis
Expand Down
70 changes: 70 additions & 0 deletions docs/transport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Transport

`TelegramBotApi` requires a transport implementation to make requests to the Telegram Bot API. Out of the box, available two transport implementations: cURL and PSR.

## cURL

The `CurlTransport` class is a transport implementation for making requests to the Telegram Bot API using the [cURL](https://www.php.net/manual/book.curl.php) extension in PHP. This transport is often the easiest choice since the cURL extension is included in most PHP installations.

General usage:

```php
use Vjik\TelegramBot\Api\TelegramBotApi;
use Vjik\TelegramBot\Api\Transport\Curl\CurlTransport;

$transport = new CurlTransport(
// Telegram bot authentication token
'110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw'
);

$api = new TelegramBotApi($transport);
```

Constructor parameters:

- `$token` — Telegram bot authentication token;
- `$baseUrl` — the base URL for Telegram Bot API requests (default `https://api.telegram.org`).

## PSR

PSR transport requires the [PSR-18](https://www.php-fig.org/psr/psr-18/) HTTP client and [PSR-17](https://www.php-fig.org/psr/psr-17/) HTTP factories.

For example, you can use the [php-http/curl-client](https://github.com/php-http/curl-client) and [httpsoft/http-message](https://github.com/httpsoft/http-message):

```shell
composer require php-http/curl-client httpsoft/http-message
```

General usage:

```php
use Http\Client\Curl\Client;
use HttpSoft\Message\RequestFactory;
use HttpSoft\Message\ResponseFactory;
use HttpSoft\Message\StreamFactory;
use Vjik\TelegramBot\Api\TelegramBotApi;
use Vjik\TelegramBot\Api\Transport\PsrTransport;

$streamFactory = new StreamFactory();
$responseFactory = new ResponseFactory();
$requestFactory = new RequestFactory();
$client = new Client($responseFactory, $streamFactory);

$transport = new PsrTransport(
$token,
$client,
$requestFactory,
$streamFactory,
);

$api = new TelegramBotApi($transport);
```

Constructor parameters:

- `$token` — Telegram bot authentication token;
- `$client` — PSR-18 HTTP client;
- `$requestFactory` — PSR-17 HTTP request factory;
- `$streamFactory` — PSR-17 HTTP stream factory;
- `$baseUrl` — the base URL for Telegram Bot API requests (default `https://api.telegram.org`).

64 changes: 64 additions & 0 deletions src/Transport/Curl/Curl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace Vjik\TelegramBot\Api\Transport\Curl;

use CurlHandle;
use RuntimeException;

use function curl_close;
use function curl_errno;
use function curl_error;
use function curl_exec;
use function curl_getinfo;
use function curl_init;
use function curl_setopt_array;

/**
* @internal
* @codeCoverageIgnore
*/
final class Curl implements CurlInterface
{
public function close(CurlHandle $handle): void
{
curl_close($handle);
}

public function exec(CurlHandle $handle): ?string
{
$result = curl_exec($handle);
if ($result === false) {
throw new RuntimeException(
'CURL error: ' . curl_error($handle),
curl_errno($handle),
);
}

return $result === true ? null : $result;
}

public function getinfo(CurlHandle $handle, ?int $option = null): mixed
{
return curl_getinfo($handle, $option);
}

public function init(): CurlHandle
{
$result = curl_init();
if ($result === false) {
throw new RuntimeException('Failed to initialize CURL.');
}

return $result;
}

public function setopt_array(CurlHandle $handle, array $options): void
{
$result = curl_setopt_array($handle, $options);
if ($result === false) {
throw new RuntimeException('Failed to set CURL options.');
}
}
}
23 changes: 23 additions & 0 deletions src/Transport/Curl/CurlInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Vjik\TelegramBot\Api\Transport\Curl;

use CurlHandle;

/**
* @internal
*/
interface CurlInterface
{
public function close(CurlHandle $handle): void;

public function exec(CurlHandle $handle): ?string;

public function getinfo(CurlHandle $handle, ?int $option = null): mixed;

public function init(): CurlHandle;

public function setopt_array(CurlHandle $handle, array $options): void;
}
Loading

0 comments on commit 20dbc52

Please sign in to comment.