From 68f9c29f8994b62bf1aea24c48ab2ab7e517e5ab Mon Sep 17 00:00:00 2001 From: Yurun Date: Wed, 6 Apr 2022 12:51:49 +0800 Subject: [PATCH] Add php connector (#10891) * Add php connector * Add submodule * Update .gitmodules * Add test --- .gitmodules | 6 + documentation20/cn/00.index/docs.md | 1 + .../cn/08.connector/03.php/docs.md | 275 ++++++++++++++++++ tests/develop-test/3-connectors/php/.gitkeep | 0 tests/develop-test/3-connectors/php/test.sh | 24 ++ 5 files changed, 306 insertions(+) create mode 100644 documentation20/cn/08.connector/03.php/docs.md create mode 100644 tests/develop-test/3-connectors/php/.gitkeep create mode 100755 tests/develop-test/3-connectors/php/test.sh diff --git a/.gitmodules b/.gitmodules index 9c09b908ad..7a63174d3f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,3 +20,9 @@ [submodule "examples/rust"] path = examples/rust url = https://github.com/songtianyi/tdengine-rust-bindings.git +[submodule "src/connector/php-tdengine"] + path = src/connector/php-tdengine + url = https://github.com/Yurunsoft/php-tdengine.git +[submodule "src/connector/php-tdengine-restful-connector"] + path = src/connector/php-tdengine-restful-connector + url = https://github.com/Yurunsoft/tdengine-restful-connector.git diff --git a/documentation20/cn/00.index/docs.md b/documentation20/cn/00.index/docs.md index d426a74da1..bafd993b3f 100644 --- a/documentation20/cn/00.index/docs.md +++ b/documentation20/cn/00.index/docs.md @@ -81,6 +81,7 @@ TDengine 是一个高效的存储、查询、分析时序大数据的平台, - [C# Connector](/connector#csharp):给 C# 应用提供一个连接 TDengine 服务器的驱动 - [Windows 客户端](https://www.taosdata.com/blog/2019/07/26/514.html):自行编译 Windows 客户端,Windows 环境的各种连接器都需要它 - [Rust Connector](/connector/rust): Rust 语言下通过 libtaos 客户端或 RESTful 接口,连接 TDengine 服务器。 +- [PHP Connector](/connector/php): 给 PHP 应用提供一个连接 TDengine 服务器的驱动,或 RESTful 接口,连接 TDengine 服务器。 ## TDengine 组件与工具 diff --git a/documentation20/cn/08.connector/03.php/docs.md b/documentation20/cn/08.connector/03.php/docs.md new file mode 100644 index 0000000000..eb772689e4 --- /dev/null +++ b/documentation20/cn/08.connector/03.php/docs.md @@ -0,0 +1,275 @@ +# PHP 连接器 + +## php-tdengine + +这是 [Swoole](https://github.com/swoole/swoole-src) 开发组成员,[imi](https://github.com/imiphp/imi) 框架作者宇润开发的 php TDengine 客户端扩展,依赖 `libtaos`。 + +源代码: + +### 依赖 + +- [PHP](https://www.php.net/) >= 7.4 + +- [Swoole](https://github.com/swoole/swoole-src) >= 4.8 (可选) + +- [TDengine客户端](https://www.taosdata.com/cn/getting-started/#%E9%80%9A%E8%BF%87%E5%AE%89%E8%A3%85%E5%8C%85%E5%AE%89%E8%A3%85) >= 2.0 + +## 特性列表 + +- 参数绑定 +- 支持 Swoole 协程化 +- 主流操作系统支持:Windows、Linux、MacOS +- 测试用例覆盖 + +### 编译安装 + +**下载代码并解压:** + +```shell +curl -L -o php-tdengine.tar.gz https://github.com/Yurunsoft/php-tdengine/archive/refs/tags/v1.0.0.tar.gz \ +&& mkdir php-tdengine \ +&& tar -xzf php-tdengine.tar.gz -C php-tdengine --strip-components=1 +``` + +> 版本 `v1.0.0` 可替换为任意更新的版本,可在 Release 中查看最新版本。 + +**非 Swoole 环境:** + +```shell +phpize && ./configure && make -j && make install +``` + +**手动指定 tdengine 目录:** + +```shell +phpize && ./configure --with-tdengine-dir=/usr/local/Cellar/tdengine/2.4.0.0 && make -j && make install +``` + +> `--with-tdengine-dir=` 后跟上 tdengine 目录。 +> 适用于默认找不到的情况,或者 MacOS 系统用户。 + +**Swoole 环境:** + +```shell +phpize && ./configure --enable-swoole && make -j && make install +``` + +**启用扩展:** + +方法一:在 `php.ini` 中加入 `extension=tdengine` + +方法二:运行带参数 `php -dextension=tdengine test.php` + +### PHP 代码编写 + +> 所有错误都会抛出异常: `TDengine\Exception\TDengineException` + +**基本:** + +```php +use TDengine\Connection; + +// 获取扩展版本号 +var_dump(\TDengine\EXTENSION_VERSION); + +// 设置客户端选项 +\TDengine\setOptions([ + \TDengine\TSDB_OPTION_LOCALE => 'en_US.UTF-8', // 区域 + \TDengine\TSDB_OPTION_CHARSET => 'UTF-8', // 字符集 + \TDengine\TSDB_OPTION_TIMEZONE => 'Asia/Shanghai', // 时区 + \TDengine\TSDB_OPTION_CONFIGDIR => '/etc/taos', // 配置目录 + \TDengine\TSDB_OPTION_SHELL_ACTIVITY_TIMER => 3, // shell 活动定时器 +]); + +// 获取客户端版本信息 +var_dump(\TDengine\CLIENT_VERSION); +var_dump(\TDengine\getClientInfo()); + +// 以下值都是默认值,不改可以不传 +$host = '127.0.0.1'; +$port = 6030; +$user = 'root'; +$pass = 'taosdata'; +$db = null; + +// 实例化 +$connection = new Connection($host, $port, $user, $pass, $db); +// 连接 +$connection->connection(); +// 获取连接参数 +$connection->getHost(); +$connection->getPort(); +$connection->getUser(); +$connection->getPass(); +$connection->getDb(); +// 获取服务端信息 +$connection->getServerInfo(); +// 选择默认数据库 +$connection->selectDb('db1'); +// 关闭连接 +$connection->close(); +``` + +**查询:** + +```php +// 查询 +$resource = $connection->query($sql); // 支持查询和插入 +// 获取结果集时间戳字段的精度,0 代表毫秒,1 代表微秒,2 代表纳秒 +$resource->getResultPrecision(); +// 获取所有数据 +$resource->fetch(); +// 获取一行数据 +$resource->fetchRow(); +// 获取字段数组 +$resource->fetchFields(); +// 获取列数 +$resource->getFieldCount(); +// 获取影响行数 +$resource->affectedRows(); +// 获取 SQL 语句 +$resource->getSql(); +// 获取连接对象 +$resource->getConnection(); +// 关闭资源(一般不需要手动关闭,变量销毁时会自动释放) +$resource->close(); +``` + +**参数绑定:** + +```php +// 查询 +$stmt = $connection->prepare($sql); // 支持查询和插入,参数用?占位 +// 绑定参数方法1 +$stmt->bindParams( + // [字段类型, 值] + [TDengine\TSDB_DATA_TYPE_TIMESTAMP, $time1], + [TDengine\TSDB_DATA_TYPE_INT, 36], + [TDengine\TSDB_DATA_TYPE_FLOAT, 44.0], +); +// 绑定参数方法2 +$stmt->bindParams([ + // ['type' => 字段类型, 'value' => 值] + ['type' => TDengine\TSDB_DATA_TYPE_TIMESTAMP, 'value' => $time2], + ['type' => TDengine\TSDB_DATA_TYPE_INT, 'value' => 36], + ['type' => TDengine\TSDB_DATA_TYPE_FLOAT, 'value' => 44.0], +]); +// 执行 SQL,返回 Resource,使用方法同 query() 返回值 +$resource = $stmt->execute(); +// 获取 SQL 语句 +$stmt->getSql(); +// 获取连接对象 +$stmt->getConnection(); +// 关闭(一般不需要手动关闭,变量销毁时会自动释放) +$stmt->close(); +``` + +**字段类型:** + +| 参数名称 | 说明 | +| ------------ | ------------ +| `TDengine\TSDB_DATA_TYPE_NULL` | null | +| `TDengine\TSDB_DATA_TYPE_BOOL` | bool | +| `TDengine\TSDB_DATA_TYPE_TINYINT` | tinyint | +| `TDengine\TSDB_DATA_TYPE_SMALLINT` | smallint | +| `TDengine\TSDB_DATA_TYPE_INT` | int | +| `TDengine\TSDB_DATA_TYPE_BIGINT` | bigint | +| `TDengine\TSDB_DATA_TYPE_FLOAT` | float | +| `TDengine\TSDB_DATA_TYPE_DOUBLE` | double | +| `TDengine\TSDB_DATA_TYPE_BINARY` | binary | +| `TDengine\TSDB_DATA_TYPE_TIMESTAMP` | timestamp | +| `TDengine\TSDB_DATA_TYPE_NCHAR` | nchar | +| `TDengine\TSDB_DATA_TYPE_UTINYINT` | utinyint | +| `TDengine\TSDB_DATA_TYPE_USMALLINT` | usmallint | +| `TDengine\TSDB_DATA_TYPE_UINT` | uint | +| `TDengine\TSDB_DATA_TYPE_UBIGINT` | ubigint | + +### 在框架中使用 + +- imi 框架请看:[imi-tdengine](https://github.com/imiphp/imi-tdengine) + +## tdengine-restful-connector + +封装了 TDEngine 的 RESTful 接口,可以使用 PHP 轻松地操作 TDEngine 的数据插入和查询了。 + +此项目支持在 PHP >= 7.0 的项目中使用。 + +支持在 ThinkPHP、Laravel、Swoole、imi 等项目中使用 + +在 Swoole 环境中支持协程化,不会阻塞! + +Github: + +### 安装 + +`composer require yurunsoft/tdengine-restful-connector` + +### 使用 + +**使用连接管理器:** + +```php +// 增加名称为 test 的连接配置 +\Yurun\TDEngine\TDEngineManager::setClientConfig('test', new \Yurun\TDEngine\ClientConfig([ + // 'host' => '127.0.0.1', + // 'hostName' => '', + // 'port' => 6041, + // 'user' => 'root', + // 'password' => 'taosdata', + // 'db' => 'database' + // 'ssl' => false, + // 'timestampFormat' => \Yurun\TDEngine\Constants\TimeStampFormat::LOCAL_STRING, + // 'keepAlive' => true, +])); +// 设置默认数据库为test +\Yurun\TDEngine\TDEngineManager::setDefaultClientName('test'); +// 获取客户端对象(\Yurun\TDEngine\Client) +$client = \Yurun\TDEngine\TDEngineManager::getClient(); +``` + +**直接 new 客户端:** + +```php +$client = new \Yurun\TDEngine\Client(new \Yurun\TDEngine\ClientConfig([ + // 'host' => '127.0.0.1', + // 'hostName' => '', + // 'port' => 6041, + // 'user' => 'root', + // 'password' => 'taosdata', + // 'db' => 'database' + // 'ssl' => false, + // 'timestampFormat' => \Yurun\TDEngine\Constants\TimeStampFormat::LOCAL_STRING, + // 'keepAlive' => true, +])); + +// 通过 sql 方法执行 sql 语句 +var_dump($client->sql('create database if not exists db_test')); +var_dump($client->sql('show databases')); +var_dump($client->sql('create table if not exists db_test.tb (ts timestamp, temperature int, humidity float)')); +var_dump($client->sql(sprintf('insert into db_test.tb values(%s,%s,%s)', time() * 1000, mt_rand(), mt_rand() / mt_rand()))); + +$result = $client->sql('select * from db_test.tb'); + +$result->getResponse(); // 获取接口原始返回数据 + +// 获取列数据 +foreach ($result->getColumns() as $column) +{ + $column->getName(); // 列名 + $column->getType(); // 列类型值 + $column->getTypeName(); // 列类型名称 + $column->getLength(); // 类型长度 +} + +// 获取数据 +foreach ($result->getData() as $row) +{ + echo $row['列名']; // 经过处理,可以直接使用列名获取指定列数据 +} + +$result->getStatus(); // 告知操作结果是成功还是失败;同接口返回格式 + +$result->getHead(); // 表的定义,如果不返回结果集,则仅有一列“affected_rows”。(从 2.0.17 版本开始,建议不要依赖 head 返回值来判断数据列类型,而推荐使用 column_meta。在未来版本中,有可能会从返回值中去掉 head 这一项。);同接口返回格式 + +$result->getRow(); // 表明总共多少行数据;同接口返回格式 +``` diff --git a/tests/develop-test/3-connectors/php/.gitkeep b/tests/develop-test/3-connectors/php/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/develop-test/3-connectors/php/test.sh b/tests/develop-test/3-connectors/php/test.sh new file mode 100755 index 0000000000..ec58df121f --- /dev/null +++ b/tests/develop-test/3-connectors/php/test.sh @@ -0,0 +1,24 @@ +#!/bin/bash +function stopTaosd { + echo "Stop taosd" + sudo systemctl stop taosd || echo 'no sudo or systemctl or stop fail' + PID=`ps -ef|grep -w taosd | grep -v grep | awk '{print $2}'` + while [ -n "$PID" ] + do + pkill -TERM -x taosd + sleep 1 + PID=`ps -ef|grep -w taosd | grep -v grep | awk '{print $2}'` + done +} +stopTaosd +rm -rf /var/lib/taos/* +rm -rf /var/log/taos/* +nohup taosd -c /etc/taos/ > /dev/null 2>&1 & +sleep 10 +cd ../../ +WKC=`pwd` + +git clone https://github.com/Yurunsoft/php-tdengine.git +cd php-tdengine +./make.sh +./run-tests.sh -- GitLab