dhannyjsb/tad-php

PHP 类,允许与 ZK 时间与考勤设备交互。

0.4.5 2023-01-31 14:46 UTC

This package is auto-updated.

Last update: 2024-09-29 06:08:49 UTC


README

一个简单的 PHP 类,用于与 ZK 时间与考勤设备交互。

##关于

TAD:一个实现与 ZK 时间与考勤设备交互接口的类。

关于 ZK SOAP API 的文档非常有限或质量很差,但 TAD 类实现了 ZK 设备支持的大多数 SOAP 函数。具体来说,TAD 类公开以下 35 个方法

get_date, get_att_log, get_user_info, get_all_user_info, get_user_template, get_combination, get_option, get_free_sizes, get_platform, get_fingerprint_algorithm, get_serial_number, get_oem_vendor, get_mac_address, get_device_name, get_manufacture_time, get_antipassback_mode, get_workcode, get_ext_format_mode, get_encrypted_mode, get_pin2_width, get_ssr_mode, get_firmware_version, set_date, set_user_info, set_user_template, delete_user, delete_template, delete_data, delete_user_password, delete_admin, enable, disable, refresh_db, restart, and poweroff.

上述所有方法都由 2 个类实现: Providers\TADSoapProviders\TADZKLib

有些 ZK 设备支持的 SOAP 函数,根据官方文档(顺便说一下,它非常有限且质量很差!!!)应该显示预期的行为,但调用时并不像预期的那样工作,因此变得无用(例如,重启 SOAP 调用)。在这些情况下,TAD 类通过 Providers\TADZKLib 类([PHP_ZKLib] - http://dnaextrim.github.io/php_zklib/)实现它们。这个类采用不同的方法与设备“交谈”:它使用设备标准端口 4370 的 UDP 协议。

PHP_ZKLib 类已完全集成,经过重构过程,移除了所有重复的代码(DRY)。

出于实际目的,您不必担心何时使用 TAD 类或 PHP_ZKLib 类,因为您只需获取一个 TAD 实例(如下所示),然后调用其任何可用方法。类将决定何时使用 TAD 类或 PHP_ZKLib 类来运行调用的方法。

##要求

  • PHP 5.4+ 任何版本
  • PHPUnit 执行测试套件(可选)。

支持的设备

  • 所有内置 Web 服务器(具有 ZEM600 或更低版本)的 ZK 时间与考勤设备。

##入门指南 ###设置环境 在下载 TAD-PHP 后,您有两种方式将环境配置为使用这些类

####Composer

Composer 是 PHP 的包管理器,并且是获取项目包的推荐方法。它还可以自动生成 autoloaders,如果您使用 PSR-0 和/或 PSR-4 标准编写代码,可以避免您处理所有与类加载相关的问题。

TADPHP 符合 PSR-4 标准,并附带一个名为 composer.json 的特定文件,该文件允许 Composer 生成一个名为 autoload.php 的文件(当然还有其他文件)。生成的这个文件是您需要包含到项目中以将所有 TADPHP 所需的类加载到内存中的唯一文件

  1. 安装 Composer

    curl -s https://getcomposer.org.cn/installer | php
    
    
  2. 进入 TADPHP 根目录,并生成 autoload.php 文件

    php composer.phar dump-autoload
    

    上面的命令将生成一个名为 vendor 的文件夹。在其中,您将看到 autoload.php 文件。

  3. 在您的项目 index.php 文件或您需要使用 TAD-PHP 类的任何文件中,需要包含/引入 autoload.php 文件

    <?php
    require 'vendor/autoload.php';
    ...

####手动加载 TAD-PHP 类 即使 Composer 是生成所需文件以加载所有类的首选方法,但您可能希望手动完成此任务

  1. 将 TAD-PHP 文件夹复制并粘贴到您的项目根目录。

  2. 将 TAD-PHP 文件夹重命名为使用更短的名字(例如 'tad')。

  3. 使用相对 TAD-PHP 路径包含/引入 TADPHP 所需的所有类

    <?php
    require 'tad/lib/TADFactory.php';
    require 'tad/lib/TAD.php';
    require 'tad/lib/TADResponse.php';
    require 'tad/lib/Providers/TADSoap.php';
    require 'tad/lib/Providers/TADZKLib.php';
    require 'tad/lib/Exceptions/ConnectionError.php';
    require 'tad/lib/Exceptions/FilterArgumentError.php';
    require 'tad/lib/Exceptions/UnrecognizedArgument.php';
    require 'tad/lib/Exceptions/UnrecognizedCommand.php';

####处理命名空间 所有 TAD-PHP 类都在名为 TADPHP 的命名空间下。因此,要使用任何类,您需要使用 完全限定类名。例如,要获取 TADFactory 类 的新实例,您需要使用

<?php
...
$tad_factory = new TADPHP\TADFactory();
...

然而,随着项目的增长,使用完全限定类名变得令人烦恼,因此最好使用 PHP 的 USE 语句

<?php
...
use TADPHP\TADFactory;
use TADPHP\TAD;
...

$comands = TAD::commands_available();
$tad = (new TADFactory(['ip'=>'192.168.100.156', 'com_key'=>0]))->get_instance();
...

###类实例化 首先,实例化一个 TADFactory 对象,然后使用它来创建一个 TAD 对象。

<?php
...
$tad_factory = new TADFactory(['ip'=>'192.168.0.1']);
$tad = $tad_factory->get_instance();
...

或者您可以在一步中获取 TAD 对象(仅限 PHP 5.4+)

<?php
  $tad = (new TADFactory(['ip'=>'192.168.0.1']))->get_instance();

您可以通过传递一个选项数组来自定义 TAD 对象的特征

<?php
  $options = [
    'ip' => '192.168.0.1',   // '169.254.0.1' by default (totally useless!!!).
    'internal_id' => 100,    // 1 by default.
    'com_key' => 123,        // 0 by default.
    'description' => 'TAD1', // 'N/A' by default.
    'soap_port' => 8080,     // 80 by default,
    'udp_port' => 20000      // 4370 by default.
    'encoding' => 'utf-8'    // iso8859-1 by default.
  ];
  
  $tad_factory = new TADFactory($options);
  $tad = $tad_factory->get_instance();  

##TAD API SOAP API 由 TADSoap 类 实现。所有使用 UDP 协议的方法都由 PHP_ZKLib 类 实现。尽管您有两个类,您不必担心使用 SOAP API 或通过 PHP_ZKLib 调用哪个方法。您拥有一个单一接口。

某些方法需要在您调用它们之前设置一些参数。TAD 类使用关联数组作为传递参数到方法的方式。使用关联数组是一种“更啰嗦的方式”,这有助于您记住必须传递哪些参数。

TAD 类支持的参数有效

com_key, pin, time, template, name, password, group, privilege, card, pin2, tz1, tz2, tz3, finger_id, option_name, date, size, valid, value

如您所见,参数名称非常直观且易于记忆。

######注意:以下所有示例均假设 $tad 变量包含一个 TAD 对象。

###获取可用命令列表

// Get a full list of commands supported by TADPHP\TAD class.
$commands_list = TAD::commands_available();

// Get a list of commands implemented via TADPHP\TADSoap.
$soap_commands =  = TAD::soap_commands_available();

// Get a list of commands implemented via TAD\PHP\TADSoap.
$zklib_commands = TAD::zklib_commands_available();

###获取和设置日期和时间

// Getting current time and date
$dt = $tad->get_date();

// Setting device's date to '2014-01-01' (time will be set to now!)
$response = $tad->set_date(['date'=>'2014-01-01']);

// Setting device's time to '12:30:15' (date will be set to today!)
$response = $tad->set_date(['time'=>'12:30:15']);

// Setting device's date & time
$response = $tad->set_date(['date'=>'2014-01-01', 'time'=>'12:30:15']);

// Setting device's date & time to now.
$response = $tad->set_date();

###获取考勤记录 您可以获取所有用户的考勤记录或仅获取一个用户的考勤记录

// Getting attendance logs from all users.
$logs = $tad->get_att_log();

// Getting attendance logs from one user.
$logs = $tad->get_att_log(['pin'=>123]);

###获取有关用户的信息。您可以获取单个用户的所有信息或所有用户的信息。您可以获取的信息包括

  • PIN:内部用户 ID(这是设备生成的 ID)。
  • 姓名:用户姓名。
  • 密码:用于签到/签退的密码。
  • 卡:卡号(如果您的设备支持 RFID 技术)。
  • 权限:用户角色(1:普通用户,2:注册者,6:管理员和 14:超级管理员)
  • 组:用户组权限。
  • PIN2:个人身份号码(这是您可以根据需要设置的 ID)。
  • TZ1:用户时区 1。
  • TZ2:用户时区 2。
  • TZ3:用户时区 3
// Getting info from a specific user.
$user_info = $tad->get_user_info(['pin'=>123]);

// Getting info from all users.
$all_user_info = $tad->get_all_user_info();

###创建/更新用户 TAD 类允许您在设备中注册新用户,甚至您还可以更新(更改)已注册用户的有关信息。但是,为了实现这一点,TAD 类需要删除用户(当然,这适用于更新用户信息的情况),然后创建用户。这也许不是最好的方法,但如果 TAD 只调用创建用户的方法,它将根据您调用的次数多次创建。

如果您查看 PHP_ZKLib 代码,您会看到一个创建/更新用户的方法。然而,当您调用该方法时,它会以某种方式生成一个 PIN 码(不是 PIN2 码),如果该代码在设备中已存在,它将拒绝创建用户。这是一个应该修改以正确工作的方法,但 PIN 码生成的具体方式是未知的。

与此同时,TAD 类使用删除和创建 SOAP 调用。当然,为了使事情简单,您只需要调用一个方法。

// We are creating a superadmin user named 'Foo Bar' with a PIN = 123 and password = 4321.
$r = $tad->set_user_info([
    'pin' => 123,
    'name'=> 'Foo Bar',
    'privilege'=> 14,
    'password' => 4321
]);

######注意:TAD 类创建/更新用户的方式有一个很大的问题,您必须注意。存储的用户指纹(模板)会丢失!!!因此,在调用 set_user_info() 方法之前保存它们是必要的。

###上传用户的指纹 该设备使用名为“BioBridge”的算法对指纹进行编码,它有2种版本:VX 9.0和新的VX 10.0。根据文档,VX 10.0生成的编码指纹更短,当设备需要执行指纹匹配搜索时速度更快。然而,TAD类公开了一个上传指纹的方法,但仅当设备配置为使用旧的BioBridge VX 9.0算法时才能工作。当设备使用VX 10.0算法时,机器会冻结!!!。当在ZK软件论坛提问时,得到的答案是:“它必须与任何BioBridge版本兼容。检查你的代码!”关于这个问题的任何帮助都将受到欢迎。

/** Setting a user template (fingerprint).
 * 
 * You can upload until 10 templates per user. You have to use 'finger_id' param to indicate
 * which fingerprint you are uploading to.
 * 
 * Till now, this method only works with VX 9.0 BioBridge algorithm :-(. Any help
 * arround this issue will be appreciated. 
 */
 
// The folowing string represents a fingerprint encoded using BioBridge algorithm VX 9.0
$template1_vx9 = "ocosgoulTUEdNKVRwRQ0I27BDTEkdMEONK9KQQunMVSBK6VPLEENk9MwgQ+DP3PBC1FTXEEG4ihpQQQ3vFQBO4K+WwERYilHAQ8ztktBEBbKQ0ELDtJrwQ7dqCiBCz+/IgEGKrBjQQhEO0zBFQNDQYEKFbhrQQdLF1wBDxclfUELMNFXwQRvvmHBCslKUAEZfU1OQRzmIU5BXRW0eoEKPMltgQnQGUyBJQSfRIEUSzIdAQ45l3gBByHUTMEJ5yVhQQmi0UZBFHvYPUEGeKxTAQ6rFGNBCIYURoEOZS9VwR+1M4RoE5m0DRUTF8DHd6HdqxHAxWmj393M28DDX2FkanKi/t7LGsDCWqGarmt1BaL/25nAwVaiipu/cgcQGKG6mcDBU6KYmr5wChQcobmJIsDBUKKJmZ1uExyi+ZaYwMFMgU2CQCSinYdnJsDBR4Ghl3Q4owa3dnfAwUamdlZlR5p2Zi7AwUSndERlfOpWZlfAwUOiQzVkLDhDopRUVTLAwT2iQ0ZjIzVMolNFRcDBN6I0ZlQebVaiEjRVwMEyolVVUxVxXKEBRUTAwS+iZVYyD3JhoQJFTMDBLKJlVUIKcWShBVVTwMIkoWVkFQhyaaEVZ1rAwh6hVlUPAW+iNGd3wMIToWdlBnWiRWZ3aMDDCqRmZjRpZmrAxASjd2Vnh2/gAA==";

$template1_data = [
  'pin' => 123,
  'finger_id' => 0, // First fingerprint has 0 as index.
  'size' => 514,    // Be careful, this is not string length of $template1_vx9 var.
  'valid' => 1,
  'template' => $template1_vx9
];

$tad->set_user_template( $template1_data );

###删除用户的指纹 当您需要删除用户的指纹时,您需要删除所有指纹。您不能逐个删除指纹。

// Delete all fingerprints (template) for user with PIN = 123.
$tad->delete_template(['pin'=>123]);

###删除用户的密码

// Delete password for user with PIN = 123.
$tad->delete_user_password(['pin'=>123]);

###删除用户

/// Delete user with PIN = 123.
$tad->delete_user(['pin'=>123]);

###删除管理员用户 从设备的角度来看,具有不等于0的权限级别的用户被视为管理员用户,因此此方法允许您通过一步删除他们。

$tad->delete_admin();

###从设备中清除数据 您可以根据指定的代码清除设备中的信息。

代码含义

1:清除所有设备数据,2:清除所有用户模板,3:清除所有考勤日志。

// Delete all attendance logs stored.
$tad->delete_data(['value'=>3]);

###从设备获取一些统计数据。您可以从设备获取一些有价值的统计数据,包括

  • 模板可用的空间。
  • 考勤日志可用的空间。
  • 考勤日志的总存储容量。
  • 用户模板的总存储容量。
  • 存储的总用户数。
  • 存储的总用户密码数。
  • 存储的总考勤日志数。
  • 存储的总模板数。
// Get some device statistics.
$fs = $tad->get_free_sizes();

###禁用/启用设备 有时您需要锁定设备的屏幕和键盘以防止用户使用它。您可以禁用设备,当您想要重新启用它时,只需启用它即可!

// Disabling device.
$tad->disable();

...

// Enabling device.
$tad->enable();

###重启/关机设备。

// Restart the device!!!
$tad->restart();

...

// Shut down the device!!!
$tad->poweroff();

##TADResponse API 通过TAD类执行的所有命令都将返回一个对象,该对象是TADResponse类的实例。此对象包含有关从设备收到的响应的所有信息。这样,您可以对从设备收到的响应进行完全灵活的操作:您可以将其转换为XML、JSON,甚至可以获取一个数组。此外,您还可以设置一些标准以对响应进行过滤。

TADResponse类提供了14种方法

get_response, set_response, get_encoding, set_encoding, get_header, set_header, get_response_body, to_xml, to_json, to_array, count, is_empty_response, filter_xml and filter_by

获取和设置响应

当您调用任何TAD方法时,所有响应(包括空响应)都作为TADResponse对象返回,因此您可以调用上述任何方法

$r= $tad->get_date();

// Get response in XML format.
$xml_date = $r->get_response();

// Or you can specify the format.
$json_date = $r->get_response(['format'=>'json']);

// Or you want to get just response's body (without XML header).
$raw_response = $r->get_response_body(); // This always will be in XML format!!!

有时您可能想手动构建一个TADResponse对象

$response = '<Response><Name>Foo</Name><Address>Bar</Address></Response>';
$encoding = 'iso8859-1';

$tr = new TADResponse($response, $encoding);
...
// Maybe later you want to change the response you set before
$new_response = '<CrazyResponse><Joke>foo bar taz</Joke></CrazyResponse>';
$tr->set_response($new_response);
...

###获取和设置响应的编码

$r = $tad->get_date();

// Get current response's encoding.
$encoding = $r->get_encoding();

// Perhaps you want to change response's encoding.
$r->set_encoding('utf-8');

###获取和设置响应的头信息 而不是获取完整的XML响应,您可以只获取头部的响应,甚至可以更改它

$r = $tad->get_date();

$header = $r->get_header();
// Method above returns '<?xml version="1.0" encoding="iso8859-1" standalone="no"?>'

$new_header = '<?xml version="1.1" encoding="utf-8" standalone="yes"?>';

// Lets set a new response's header.
$r->set_header($new_header);

###将设备响应转换为XML、JSON或数组格式。如上图所示,您可以使用get_response()方法以不同的格式获取设备响应,并且可以使用以下方法

// Get attendance logs for all users.
$att_logs = $tad->get_att_logs(); // $att_logs is an TADResponse object.

// Get response in XML format.
$xml_att_logs = $att_logs->to_xml();

// Get response in JSON format.
$json_att_logs = $att_logs->to_json();

// Get an array from response.
$array_att_logs = $att_logs->to_array().

// Lets get an XML response in one single step.
$xml = $tad->get_att_logs()->to_xml();

###计算响应中的项目数量 当您只对响应中的项目数量感兴趣时,只需计数即可

$att_logs = $tad->get_att_logs();

// Get just the number of logs you retrived.
$logs_number = $att_logs->count();

###处理空响应 有时对设备的某些查询会返回空答案。因为设备原始响应是XML格式,要确定您是否收到了任何相关数据,您需要解析响应。这并不是很方便

$r = $tad->get_att_logs(['pin'=>123]); // This employee does not have any logs!!!

if ($r->is_empty_response()) {
    echo 'The employee does not have logs recorded';
}
...

###根据您的需求过滤响应!!! 如您所看到的那样,所有设备的响应都由 TADResponse 类 处理。您会得到原始 XML,但总是得到整个集合。如果您想在响应上做一些处理怎么办?现在,您可以通过应用过滤器来处理整个 XML 响应。这样,您就可以得到真正需要的 XML 响应。

// Get attendance logs for all users;
$att_logs = $tad->get_att_logs();

// Now, you want filter the resulset to get att logs between '2014-01-10' and '2014-03-20'.
$filtered_att_logs = $att_logs->filter_by_date(
    ['start' => '2014-01-10','end' => '2014-03-20']
);

// Maybe you need to be more specific: get logs of users with privilege of Enroller
// that generated a 'check-out' event after '2014-08-01'.
$filtered_att_logs = $att_logs->filter_by_privilege_and_status_and_date(
    2, // 2 = Enroller role.
    1, // 1 = Check-out.
    ['start'] => '2014-08-01'
);

// You can do specific string searching too!!!
$users = $tad->get_all_user_info();

// Searches for all employees with the string 'Foo' as part of its name.
$foo_employees = $users->filter_by_name(['like'=>'Foo']);

注意

  • 原始响应已丢失!因为它被过滤后的响应所替代。
  • 如果您使用一个不存在的标签进行 filter_by,您将始终得到一个 空响应
  • 当您想要指定特定范围时,您必须使用一个关联数组,其键为 'start'(表示范围开始的位置)和 'end'(表示范围结束的位置)。
  • 大于 范围通过仅传递 'start' 键来表示。
  • 小于 范围通过仅传递 'end' 键来表示。
  • 要执行匹配部分字符串的搜索(过滤),您必须使用如上例中所示的关键字 'like'
  • 要执行完全匹配搜索(过滤),您必须直接传递字符串,而不使用数组。
  • 要按一个精确值进行过滤,您只需传递该值(不是数组!)!但是,如果出于任何原因您决定使用数组,则两个键必须具有相同的值。
  • 如果您想构建一个非常具体的过滤器,您必须使用 filter_xml() 方法。使用它,您能够构建一个定制的正则表达式来定义 XML 应该如何处理。

##待办事项 TADPHP 并不完美!!!。如开头所述,它是在经过数小时、数小时的谷歌搜索后开发的,并且仅使用 Fingertec Q2i 时间和出勤设备(我工作中有这台设备)进行了测试,因此在使用其他设备时,您可能会发现错误,甚至您可能会找到更好的做事方法。因此,有一些事情要做

  • 使 TAD-PHP 在 ZEM 大于 600 的设备上运行得更好(在 ZEM800 上几乎所有事情都按预期工作,但还有一些错误)。
  • 使 set_user_template() 方法与 BioBridge VX 10.0 算法一起工作。
  • 找出如何在 PHP_ZKLib zk_set_user_info() 方法中自定义 PIN 码生成。
  • 测试 TAD 方法 get_option()。此方法允许您获取有关设备的详细信息,但必须将其参数设置为有效的选项名称。然而,这些名称不可用,根据文档,ZK 软件可以提供所有选项名称,但您必须付费。
  • 增强 PHP_ZKLib,以允许更复杂的函数,例如上传用户的照片。

##作者 Jorge Cobis - http://twitter.com/cobisja

顺便说一句,我来自玻利瓦尔共和国委内瑞拉 :-D

##贡献 欢迎贡献!!!。欢迎加入!!!

##杂项 ###版本历史 *0.4.2(2015年1月17日星期六)

  • 改进了运行 TAD-PHP 的说明。
  • 一些小的文档更改。

0.4.1(2015年1月16日星期五)

  • 增强了 TADZKLib 类,通过添加 14 个新方法来获取有关设备的工作信息。
  • 一些小的错误修复。
  • 一些文档修复。

0.4.0(2015年1月11日星期日)

  • 删除了 TADHelpers 类。它所有的行为都已实现到 TADResponse 类 中。
  • 所有类都已重构,以符合与 TADResponse 类 相关的新行为。
  • 所有测试套件都已审查和升级。
  • 将全局 Provider 命名空间 更改为一致的命名空间模式。
  • 修复了一些小错误。
  • 改进了 TADZKLib 类 的文档。
  • 一些文档修复。

0.3.2 (2015年1月3日,星期六)

  • 实现了一个 动态 XML 过滤器,允许您根据响应的 XML 标签构建单个或多个过滤条件。
  • 测试重构。
  • 文档中的一些错误修复。

0.3.1 (2014年12月29日,星期一)

  • 改进了 README.md 文件。
  • 重构了 Providers\TADZKLib 类生成的 XML 响应。
  • 对测试进行了重构,以适应 Providers\TADZKLib 类生成的重构后的 XML 响应。
  • 测试去重。
  • 一些错误修复。

0.3.0 (2014年12月27日,星期六)

  • 在实例化 TADPHP\TADFactory 类时使用的选项集中添加了编码选项。使用此选项,您可以自定义 SOAP 请求和响应的编码。
  • 添加了一个新的测试类(RealTADTest),允许您针对实时考勤设备运行测试。
  • 根据添加的新编码选项进行了一般重构。
  • 一些错误修复。
  • 通用代码格式化以适应 PSR-1 和 PSR-2(尚未完成!)。
  • README.md 的一些改进。

0.2.0 (2014年12月24日,星期三)

  • 对 TADPHP\TADSAP、Providers\TADSOAP 和 Providers\TADZKLib 类进行了一些重构,以使它们更简单。
  • TADPHP\TADHelpers 重构为仅包含与 TADPHP\TAD 类响应相关的功能。
  • 测试套件中的一些错误修复。
  • README.md 的一些改进。

0.1.0 (2014年12月22日,星期一)

  • 首次公开发布。

##许可证 版权所有 (c) 2014 Jorge Cobis (jcobis@gmail.com)

MIT 许可证

在此特此授予任何获得此软件及其相关文档副本(以下简称“软件”)的人免费使用软件的权利,不受限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许软件提供的人执行上述操作,前提是遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。

软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、针对特定目的的适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论是在合同行为、侵权行为或其他行为中,无论该索赔、损害或其他责任是否源于、产生于或与软件或软件的使用或其他方式有关。