PHP Conference Japan 2024

SNMP 类

(PHP 5 >= 5.4.0, PHP 7, PHP 8)

简介

表示 SNMP 会话。

类概要

class SNMP {
/* 常量 */
public const int VERSION_1;
public const int VERSION_2c;
public const int VERSION_2C;
public const int VERSION_3;
public const int ERRNO_NOERROR;
public const int ERRNO_ANY;
public const int ERRNO_GENERIC;
public const int ERRNO_TIMEOUT;
/* 属性 */
public readonly array $info;
public ?int $max_oids;
/* 方法 */
public __construct(
    int $version,
    string $hostname,
    string $community,
    int $timeout = -1,
    int $retries = -1
)
public close(): bool
public get(array|string $objectId, bool $preserveKeys = false): mixed
public getErrno(): int
public getError(): string
public getnext(array|string $objectId): mixed
public set(array|string $objectId, array|string $type, array|string $value): bool
public setSecurity(
    string $securityLevel,
    string $authProtocol = "",
    string $authPassphrase = "",
    string $privacyProtocol = "",
    string $privacyPassphrase = "",
    string $contextName = "",
    string $contextEngineId = ""
): bool
public walk(
    array|string $objectId,
    bool $suffixAsKey = false,
    int $maxRepetitions = -1,
    int $nonRepeaters = -1
): array|false
}

属性

max_oids

每个 GET/SET/GETBULK 请求的最大 OID 数

valueretrieval

控制 SNMP 值的返回方式

SNMP_VALUE_LIBRARY返回值将与 Net-SNMP 库返回的一致。
SNMP_VALUE_PLAIN返回值将是纯值,不包含 SNMP 类型信息。
SNMP_VALUE_OBJECT返回值将是包含“value”和“type”属性的对象,其中后者是 SNMP_OCTET_STR、SNMP_COUNTER 等常量之一。“value”的返回方式取决于SNMP_VALUE_LIBRARYSNMP_VALUE_PLAIN 中哪个被设置。
quick_print

NET-SNMP 库中 quick_print 的值

设置 NET-SNMP 库中 quick_print 的值。当此值设置为 (1) 时,SNMP 库将返回“快速打印”的值。这意味着只打印值。当 quick_print 未启用(默认)时,NET-SNMP 库会打印额外的信息,包括值的类型(例如 IpAddress 或 OID)。此外,如果未启用 quick_print,库还会为所有长度为三个字符或更少的字符串打印额外的十六进制值。

enum_print

控制枚举值的打印方式

参数切换 walk/get 等是否应自动在 MIB 中查找枚举值,并将其与人类可读的字符串一起返回。

oid_output_format

控制 OID 输出格式

对于各种 oid_output_format 值,OID .1.3.6.1.2.1.1.3.0 的表示形式
SNMP_OID_OUTPUT_FULL.iso.org.dod.internet.mgmt.mib-2.system.sysUpTime.sysUpTimeInstance
SNMP_OID_OUTPUT_NUMERIC.1.3.6.1.2.1.1.3.0
SNMP_OID_OUTPUT_MODULEDISMAN-EVENT-MIB::sysUpTimeInstance
SNMP_OID_OUTPUT_SUFFIXsysUpTimeInstance
SNMP_OID_OUTPUT_UCDsystem.sysUpTime.sysUpTimeInstance
SNMP_OID_OUTPUT_NONE未定义
oid_increasing_check

控制在遍历 OID 树时禁用对递增 OID 的检查

一些 SNMP 代理以乱序返回 OID 的方式而闻名,但仍可以完成遍历。其他代理返回乱序的 OID,并可能导致 SNMP::walk() 无限循环,直到达到内存限制。PHP SNMP 库默认执行 OID 递增检查,并在检测到可能的循环时停止遍历 OID 树,并发出有关遇到的非递增 OID 的警告。将 oid_increasing_check 设置为 false 以禁用此检查。

exceptions_enabled

控制哪些错误将引发 SNMPException 而不是警告。使用按位或运算的 SNMP::ERRNO_* 常量。默认情况下,所有 SNMP 异常都已禁用。

info

包含远程代理配置的只读属性:主机名、端口、默认超时、默认重试次数

预定义常量

SNMP 错误类型

SNMP::ERRNO_NOERROR

没有发生任何 SNMP 特定的错误。

SNMP::ERRNO_GENERIC

发生了 SNMP 通用错误。

SNMP::ERRNO_TIMEOUT

SNMP 代理的请求超时。

SNMP::ERRNO_ERROR_IN_REPLY

SNMP 代理在回复中返回错误。

SNMP::ERRNO_OID_NOT_INCREASING

在执行 (BULK)WALK 命令时,SNMP 代理遇到 OID 循环,报告非递增 OID。这表示远程 SNMP 代理存在问题。

SNMP::ERRNO_OID_PARSING_ERROR

库在解析 OID(以及/或者 SET 命令的类型)时失败。没有发出任何查询。

SNMP::ERRNO_MULTIPLE_SET_QUERIES

库将对请求的 SET 操作使用多个查询。这意味着操作将以非事务方式执行,如果遇到类型或值错误,则第二个或后续块可能会失败。

SNMP::ERRNO_ANY

所有 SNMP::ERRNO_* 代码按位或运算的结果。

内容目录

添加注释

用户贡献的注释 2 个注释

swannie at swannie dot net
3 年前
希望这对其他人有所帮助,因为这让我困扰了整整两个小时。看起来 valueretrieval 和 enum_print 以我预料之外的方式协同工作,并且在重新阅读后可能是设计使然,但我不确定。如果您无法打印枚举,这可能是原因。

<?php
$snmp
= new SNMP(SNMP::VERSION_2C,'192.168.1.9','test');
$snmp->oid_output_format = SNMP_OID_OUTPUT_SUFFIX;
$snmp->valueretrieval = SNMP_VALUE_PLAIN;
$snmp->enum_print = 0;
echo
$snmp->get('IF-MIB::ifOperStatus.10110') . "\n";
$snmp->enum_print = 1;
echo
$snmp->get('IF-MIB::ifOperStatus.10110') . "\n";
$snmp->quick_print = 1;
echo
$snmp->get('IF-MIB::ifOperStatus.10110') . "\n";
$snmp->valueretrieval = SNMP_VALUE_LIBRARY;
echo
$snmp->get('IF-MIB::ifOperStatus.10110') . "\n";
$snmp->enum_print = 0;
echo
$snmp->get('IF-MIB::ifOperStatus.10110') . "\n";
?>

输出
1
1
1
1
向上
madjev1990 at gmail dot com
8 年前
我的毕业论文的一部分是创建通过 SNMP 命令控制设备的 Web 界面。因此,我在 SNMP 类之上创建了自己的抽象级别。



<?php

/**
* SNMP 库,为 SNMP 原生库添加了一层抽象。
* 它添加了与 PicoIP 模块交互的功能。使用此库,您可以:
* 1.激活/禁用已定义的引脚;
* 2.获取所有引脚的状态。
*
* 创建实例时,应将关键字传递给构造函数,这将
* 使库创建一个具有必要属性和访问权限的对象。
*
* 私有属性设置一些配置:
* Host 是我们将要控制的设备的 IP 地址。
* 设置了两个密码用于读取和写入。
* 我们将使用的 SNMP 协议版本为版本 1。
*
* @author Radoslav Madjev
* @year 2016
* @version 1.0 beta
*
*
*/
class snmp_lib {

private
$snmpInstance;
private
$VERSION = SNMP::VERSION_1;
private
$HOST = '192.168.0.150';
private
$passwordRead = '000000000000';
private
$passwordWrite = 'private';
private
$releys = array(1 => '1.3.6.1.4.1.19865.1.2.1.1.0',
2 => '1.3.6.1.4.1.19865.1.2.1.2.0');
private
$allPorts = array('3' => '1.3.6.1.4.1.19865.1.2.1.33.0',
'5' => '1.3.6.1.4.1.19865.1.2.2.33.0');

/**
* 基于我们将执行的操作,创建 SNMP 原生类的实例。
*
* @param string $action
*/
public function __construct($action) {
if (
in_array($action, array('read', 'write'))) {
if (
strcmp($action, 'read') === 0) {
$this->_read();
} else {
$this->_write();
}
}
}

/**
* 创建具有读取权限的实例。
*/
private function _read() {
$this->snmpInstance = new SNMP($this->VERSION, $this->HOST, $this->passwordRead);
}

/**
* 创建具有写入权限的实例。
*/
private function _write() {
$this->snmpInstance = new SNMP($this->VERSION, $this->HOST, $this->passwordWrite);
}

/**
* 关闭 SNMP 会话。
*
* @return boolean
*/
public function closeSession() {
return
$this->snmpInstance->close();
}

/**
* 将整数 1 作为已定义引脚的值。
*/
public function activate($relay) {
$this->snmpInstance->set($this->releys[$relay], 'i', '1');
}

/**
* 将整数 0 作为已定义引脚的值。
*/
public function deactivate($relay) {
$this->snmpInstance->set($this->releys[$relay], 'i', '0');
}

/**
* 获取模块所有端口的引脚状态。
*
* @return array
*/
public function getAllPortsStatus() {
$allPins = array();
foreach (
$this->allPorts as $number => $port) {
//获取已定义端口的 8 位整数形式的活动引脚
$getbits = $this->snmpInstance->get($port);
$bits = str_replace('INTEGER: ', '', $getbits);
//获取引脚状态
$pinsStatus = $this->_getActivePins($bits);
$allPins[$number] = $pinsStatus;
}

return
$allPins;
}

/**
* 进行位运算,以确定
* 哪些引脚处于活动状态。
*
* @param int $bits
* @return array
*/
private function _getActivePins($bits) {

$bitMapping = array(
1 => 1,
2 => 2,
3 => 4,
4 => 8,
5 => 16,
6 => 32,
7 => 64,
8 => 128
);

$pinsStatus = array();

foreach (
$bitMapping as $int => $bit) {
if ((
$bits & $bit) == $bit) {
$pinsStatus[$int] = true;
continue;
}
$pinsStatus[$int] = false;
}

return
$pinsStatus;
}

}

?>

我有一个模块可以接收 SNMP 请求并向继电器发送命令。这些也是使用此库的示例脚本。
打开脚本
<?php
require_once 'snmp_lib.php';

$snmp = new snmp_lib('write');
$snmp->activate($getRelayNumber);
$snmp->closeSession();
?>

关闭脚本
<?php
require_once 'snmp_lib.php';

$snmp = new snmp_lib('write');
$snmp->deactivate($getRelayNumber);
$snmp->closeSession();
?>

获取所有端口状态的脚本
<?php
require_once 'snmp_lib.php';

$snmp = new snmp_lib('read');
$getActive = $snmp->getAllPortsStatus();
?>
To Top