# `naisi_get_runtime_environment_report`

返回运行环境诊断 JSON；不要求许可证授权。
不传、null 或 [] 返回基础报告：server.cpu 含 probe_ok、physical_core_count、logical_processor_count，
server.memory 含 probe_ok、total_bytes；server.storage 含 probe_ok、disk_count、total_bytes。
server 选择三项资源详情；server.cpu、server.memory、server.storage 分别选择单项详情，可组合且只采集一次。
旧 cpu、memory、storage 选择器已移除；未知选择器返回 null。process 仍单独选择当前 PHP 进程内存。
仅 CPU 详情等待约 1 秒，sample_interval_ms 为实际间隔；百分比保留两位小数并保持数值类型。
失败保留本次选择的字段，未知数值为 null，并附加 code、error、missing；未采集 license_binding 时为 []。
SQLCipher 和配套 OpenSSL 从固定 naisilib/bin 加载，dependencies 中的 path 表示实际加载路径。

## 函数签名

```php
function naisi_get_runtime_environment_report(?array $elements = null): string
```

## 调用前提

此诊断或许可错误接口不要求许可证明。

## 参数

### `$elements`

- 类型：`?array`
- 必填：否
- 默认值：`null`
- 方向：输入参数。

需要返回的顶层元素或 server.cpu、server.memory、server.storage；null/[] 为基础报告，server 为全部资源详情，missing 执行基础检查。

## 返回值

类型：`string`

返回 JSON 字符串；失败时包含非零 code、可读的 error 概述和 missing 明细，成功时包含环境元素且不含 code。

## 调用示例

当前请求须满足上方调用前提；请检查实际返回值和引用输出，随机结果及数据包内容以运行环境为准。

```php
$elements = ['server.memory'];
$result = naisi_get_runtime_environment_report($elements);
echo $result;
```

## 默认内容

不传参数、`null`、`[]` 等价。原有 `library`、`php`、`host`、`runtime_directory`、`license`、
`license_binding`、`dependencies`、`missing` 继续返回，`process` 仍需显式选择。
`server` 严格只含以下基础字段：

```json
{
  "server": {
    "cpu": {"probe_ok": true, "physical_core_count": 8, "logical_processor_count": 16},
    "memory": {"probe_ok": true, "total_bytes": 34359738368},
    "storage": {"probe_ok": true, "disk_count": 2, "total_bytes": 2000000000000}
  }
}
```

数值为示例。默认没有 CPU 使用率等待，但核心拓扑、磁盘设备和容量查询有实际系统调用开销。
不缓存容量或使用率，也不启动外部命令。所有容量单位为字节。

## 选择规则

| elements | 资源内容 | CPU 使用率采样 |
|---|---|---|
| 不传、null、[] | 三项基础字段 | 无 |
| ['server'] | 三项完整详情 | 一次，约 1 秒 |
| ['server.cpu'] | 仅 CPU 详情 | 一次，约 1 秒 |
| ['server.memory'] | 仅内存详情 | 无 |
| ['server.storage'] | 仅磁盘详情 | 无 |

```php
echo naisi_get_runtime_environment_report();
echo naisi_get_runtime_environment_report(['server']);
echo naisi_get_runtime_environment_report(['server.cpu', 'server.memory']);
echo naisi_get_runtime_environment_report(['library', 'dependencies', 'server.storage']);
```

结果始终在嵌套的 `server` 下，不使用点号作为输出键。重复选择只采集一次；`server` 已包含全部资源。
旧 `cpu`、`memory`、`storage` 选择器不再支持，按未知元素返回 null；更深的字段路径也不支持。
非空数组中的非字符串忽略；没有字符串时返回 `{}`。资源查询不执行无关依赖、目录、机器指纹检查。
`missing` 执行完整基础检查，不触发使用率采样；例如 `['missing','server.memory']` 的资源输出只有内存详情。

## 字段口径

CPU 详情在基础字段外增加 `uptime_seconds`、`usage_percent`、`idle_percent`、`sample_interval_ms`。
物理核心数来自系统拓扑，逻辑处理器数包含超线程，不能用逻辑数量除以二推算核心数。
Windows 覆盖所有处理器组；Linux 读取在线 CPU 的 sysfs 核心关系。虚拟机按来宾系统报告的拓扑统计，
不代表宿主机硬件或容器 CPU 配额。拓扑无法可靠取得时对应字段为 null。
CPU 使用率以两次累计计数之间约 1 秒的区间计算，不依赖前次请求；实际间隔由单调时钟测量。
计数回退、读取失败、没有有效时间增量时不伪造 0%。Linux 延续 idle+iowait 作为空闲时间的口径。

内存详情增加 `available_bytes`、`used_bytes`、`usage_percent`。
Windows 使用 GlobalMemoryStatusEx，Linux 使用 /proc/meminfo 的 MemTotal、MemAvailable；基础查询不要求 MemAvailable。

磁盘详情增加 `available_bytes`、`free_bytes`、`used_bytes`、`usage_percent`、`partition_count`、`partitions`。
`disk_count` 独立枚举当前可识别的本地固定磁盘，排除可移动介质、网络盘、光驱和软件映射层；虚拟机及 RAID
按操作系统可见设备统计。未挂载磁盘可以计数，但不贡献文件系统容量。容器无法验证设备可见性时返回 null。
`partition_count` 表示参与容量统计的卷/文件系统条目数，不是磁盘数。Windows 汇总固定盘符对应的卷；
Linux 汇总 /dev、overlay、zfs 挂载，按设备号去重相同文件系统。容量不是物理硬盘标称容量，Windows 可受用户配额影响。
详情的 `partitions` 保留成功取得的各卷路径、类型、文件系统和容量信息；汇总不完整时总量为 null。

所有百分比四舍五入至两位小数，保持 JSON 数值类型，不强制显示尾随零。`used_bytes`：内存为 total-available，
磁盘为 total-free。`process` 的 pid、resident_bytes、peak_resident_bytes 口径保持不变。

## 失败与依赖

通常的探测失败保留已选择的资源/依赖字段，同时附加非零 `code`、`error`、`missing`、`license_binding`；JSON 编码失败的特殊返回见上方说明。
没有采集许可绑定时返回空数组，不额外采集指纹。`probe_ok` 表示本次基础或完整探测全部成功；
已知字段保留，无法取得的数值为 null。磁盘数量失败不抹掉已可靠取得的容量，容量失败也不抹掉磁盘数量。

错误码按位组合：SQLCipher=1、机器指纹=2、运行目录=4、CPU=16、内存=32、磁盘=64、JSON 编码=128、进程=256、
OpenSSL 路径/可用性=512。仅本次实际执行的检查参与判断。正常成功时不附加 code/error；显式请求未知元素时的 null 字段见返回值说明。

Windows 项目依赖目录为 `C:/naisilib/bin`，Linux 为 `/etc/naisilib/bin`。SQLCipher 不回退到扩展目录或系统搜索路径；`dependencies.sqlcipher.path`、`dependencies.openssl.path` 是实际加载路径，无法取得时为 `null`。
OpenSSL 是扩展初始化所需依赖，缺失或实际路径不符会导致模块初始化失败，此时无法调用本函数，不能依赖本函数报告所有初始化错误。

`license_binding.ready` 只表示机器指纹及编译体摘要等绑定材料已取得，不表示许可证已授权；业务请求仍需调用 [naisi_is_ext_license_valid](/web/developers/naisilib/naisi-is-ext-license-valid)。

## 运行目录

Windows 根目录为 `C:/naisilib`，Linux 为 `/etc/naisilib`。`runtime_directory.exists`、`readable`、`writable` 描述根目录，`ready` 汇总必需子目录的访问检查；根目录本身不要求可写。报告不返回 `purpose` 或 `folders` 明细。

| 子目录 | 用途 | 运行账户权限 |
|---|---|---|
| `bin` | 原生可执行文件与动态库依赖 | 只读、可执行；仅管理员/root 可写 |
| `heartbeat` | 许可心跳租约与失败状态 | 读写 |
| `keys` | 加密的 SQLCipher 密钥数据库 | 只读；管理员/root 更新 |
| `license` | 签名许可证文件 | 只读；管理员/root 更新 |

## 版本信息

- 实现模块：`debug`
- 授权类别：`UNRESTRICTED` / `NONE`
- 失败回退：空字符串 `""`
- 文档同步：`2026-10-18`
