我目前正在开发一项功能,使用 ZkLibrary 从 Solution C1 考勤机检索考勤日志数据。我正在使用 LARAGON 并在 LARAGON 的 php.ini 文件中启用了 SOAP 和 SOCKET 扩展。本机是读取RFID卡的类型。我尝试使用内置的 PHP 脚本示例从机器的 SOAP SDK 下载 LogData。但是,我总是无法连接到机器。该机器的 IP 地址 为 192.168.XX.XX,端口为 4370。
使用ZkLibrary,我已成功连接到机器并检索了今天总共20,704条记录中的16,499条记录。但是,在这 16,499 条记录中,我没有看到 2023 年的出勤数据。有趣的是,2000 年有 12,000 条记录。我对可能导致此问题的原因感到困惑。使用桌面应用程序下载时,2023 年的所有数据都存在,大约 4,000 条记录,但我无法找到它。即使是 2022 年的数据也非常有限。然而,该机器自 2014 年起一直在使用。以下是 SOAP 手册指南中提到的 SOAP 请求 XMLRPC 的示例:
**4.1.3.1 Get all information log**
**[Function]**
Read out the attendance record from attendance machines.
**[XML protocols]
Request Xml:**
<GetAttLog>
<ArgComKey xsi:type="xsd:integer”>ComKey</ArgComKey>
<Arg>
<PIN xsi:type="xsd:integer”>Job Number</PIN>
</Arg>
</GetAttLog>
**Response Xml:**
<GetAttLogResponse>
<Row>
<PIN>XXXXX</PIN>
<DateTime >YYYY-MM-DD HH:MM:SS</DateTime>
<Verified>X</Verified>
<Status>X</Status>
<WorkCode>XXXXX</WorkCode>
</Row>
</GetAttLogResponse>
**[Parameters]**
ComKey: communications Password
PIN: User ID (Registration).
**[Return value]**
If successful, return log information, or return Null.
Pin: User ID (Registration).
DateTime: Date Time.
Verified: Authentication method.
Status: Attendance status.
WorkCode: work code
我尝试了从SDK中检索考勤日志的脚本,如下所示:
<html>
<head><title>Contoh Koneksi Mesin Absensi Mengunakan SOAP Web Service</title></head>
<body bgcolor="#caffcb">
<H3>Download Log Data</H3>
<
$IP=$HTTP_GET_VARS["ip"];
$Key=$HTTP_GET_VARS["key"];
if($IP=="") $IP="192.168.XX.XX";
if($Key=="") $Key="0";
?>
<form action="tarik-data.php">
IP Address: <input type="Text" name="ip" value="<?=$IP?>" size=15><BR>
Comm Key: <input type="Text" name="key" size="5" value="<?=$Key?>"><BR><BR>
<input type="Submit" value="Download">
</form>
<BR>
<?
if($HTTP_GET_VARS["ip"]!=""){?>
<table cellspacing="2" cellpadding="2" border="1">
<tr align="center">
<td><B>UserID</B></td>
<td width="200"><B>Tanggal & Jam</B></td>
<td><B>Verifikasi</B></td>
<td><B>Status</B></td>
</tr>
<?
$Connect = fsockopen($IP, "4370", $errno, $errstr, 1);
if($Connect){
$soap_request="<GetAttLog><ArgComKey xsi:type=\"xsd:integer\">".$Key."</ArgComKey><Arg><PIN xsi:type=\"xsd:integer\">All</PIN></Arg></GetAttLog>";
$newLine="\r\n";
fputs($Connect, "POST /iWsService HTTP/1.0".$newLine);
fputs($Connect, "Content-Type: text/xml".$newLine);
fputs($Connect, "Content-Length: ".strlen($soap_request).$newLine.$newLine);
fputs($Connect, $soap_request.$newLine);
$buffer="";
while($Response=fgets($Connect, 1024)){
$buffer=$buffer.$Response;
}
}else echo "Koneksi Gagal";
include("parse.php");
$buffer=Parse_Data($buffer,"<GetAttLogResponse>","</GetAttLogResponse>");
$buffer=explode("\r\n",$buffer);
for($a=0;$a<count($buffer);$a++){
$data=Parse_Data($buffer[$a],"<Row>","</Row>");
$PIN=Parse_Data($data,"<PIN>","</PIN>");
$DateTime=Parse_Data($data,"<DateTime>","</DateTime>");
$Verified=Parse_Data($data,"<Verified>","</Verified>");
$Status=Parse_Data($data,"<Status>","</Status>");
?>
<tr align="center">
<td><?echo $PIN?></td>
<td><?=$DateTime?></td>
<td><?=$Verified?></td>
<td><?=$Status?></td>
</tr>
<?}?>
</table>
<?}?>
</body>
</html>
并且我总是收到这样的错误:警告:fsockopen():无法连接到192.168.xx.xx:4370(连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机无法响应。)。最后,我决定使用 ZKLibrary,是的,正如我之前提到的,我成功检索了 16,499 条数据。然而,这些数据中有很多日期不正确,因为 2000 年有 12,000 条记录。下面是一个例子:
这是 ZkLibrary 的脚本和文件结构及其 example.php:
Zklibrary.php:
<?php
error_reporting(0);
define('CMD_CONNECT', 1000);
define('CMD_EXIT', 1001);
define('CMD_ENABLEDEVICE', 1002);
define('CMD_DISABLEDEVICE', 1003);
define('CMD_RESTART', 1004);
define('CMD_POWEROFF', 1005);
define('CMD_SLEEP', 1006);
define('CMD_RESUME', 1007);
define('CMD_TEST_TEMP', 1011);
define('CMD_TESTVOICE', 1017);
define('CMD_VERSION', 1100);
define('CMD_CHANGE_SPEED', 1101);
define('CMD_ACK_OK', 2000);
define('CMD_ACK_ERROR', 2001);
define('CMD_ACK_DATA', 2002);
define('CMD_PREPARE_DATA', 1500);
define('CMD_DATA', 1501);
define('CMD_USER_WRQ', 8);
define('CMD_USERTEMP_RRQ', 9);
define('CMD_USERTEMP_WRQ', 10);
define('CMD_OPTIONS_RRQ', 11);
define('CMD_OPTIONS_WRQ', 12);
define('CMD_ATTLOG_RRQ', 13);
define('CMD_CLEAR_DATA', 14);
define('CMD_CLEAR_ATTLOG', 15);
define('CMD_DELETE_USER', 18);
define('CMD_DELETE_USERTEMP', 19);
define('CMD_CLEAR_ADMIN', 20);
define('CMD_ENABLE_CLOCK', 57);
define('CMD_STARTVERIFY', 60);
define('CMD_STARTENROLL', 61);
define('CMD_CANCELCAPTURE', 62);
define('CMD_STATE_RRQ', 64);
define('CMD_WRITE_LCD', 66);
define('CMD_CLEAR_LCD', 67);
define('CMD_GET_TIME', 201);
define('CMD_SET_TIME', 202);
define('USHRT_MAX', 65535);
define('LEVEL_USER', 0); // 0000 0000
define('LEVEL_ENROLLER', 2); // 0000 0010
define('LEVEL_MANAGER', 12); // 0000 1100
define('LEVEL_SUPERMANAGER', 14); // 0000 1110
class ZKLibrary
{
public $ip = null;
public $port = null;
public $socket = null;
public $session_id = 0;
public $received_data = '';
public $user_data = array();
public $attendance_data = array();
public $timeout_sec = 30;
public $timeout_usec = 30000000;
public function __construct($ip = null, $port = null)
{
if ($ip != null) {
$this->ip = $ip;
}
if ($port != null) {
$this->port = $port;
}
$this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$this->setTimeout($this->timeout_sec, $this->timeout_usec);
}
//other public function
................
..............
..............
................
..............
..............
................
..............
..............
public function getUserData()
{
$uid = 1;
$command = CMD_USERTEMP_RRQ;
$command_string = chr(5);
$chksum = 0;
$session_id = $this->session_id;
$u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, 0, 8));
$reply_id = hexdec($u['h8'] . $u['h7']);
$buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string);
socket_sendto($this->socket, $buf, strlen($buf), 0, $this->ip, $this->port);
try {
socket_recvfrom($this->socket, $this->received_data, 1024, 0, $this->ip, $this->port);
$u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6', substr($this->received_data, 0, 8));
$bytes = $this->getSizeUser();
if ($bytes) {
while ($bytes > 0) {
socket_recvfrom($this->socket, $received_data, 1032, 0, $this->ip, $this->port);
array_push($this->user_data, $received_data);
$bytes -= 1024;
}
$this->session_id = hexdec($u['h6'] . $u['h5']);
socket_recvfrom($this->socket, $received_data, 1024, 0, $this->ip, $this->port);
}
$users = array();
$retdata = "";
if (count($this->user_data) > 0) {
for ($x = 0; $x < count($this->user_data); $x++) {
if ($x > 0) {
$this->user_data[$x] = substr($this->user_data[$x], 8);
}
if ($x > 0) {
$retdata .= substr($this->user_data[$x], 0);
} else {
$retdata .= substr($this->user_data[$x], 12);
}
}
}
return $retdata;
} catch (ErrorException $e) {
return false;
} catch (exception $e) {
return false;
}
}
public function getAttendance()
{
$command = CMD_ATTLOG_RRQ;
$command_string = '';
$chksum = 0;
$session_id = $this->session_id;
$u = unpack('H2h1/H2h2/H2h3/H2h4/H2h5/H2h6/H2h7/H2h8', substr($this->received_data, 0, 8));
$reply_id = hexdec($u['h8'] . $u['h7']);
$buf = $this->createHeader($command, $chksum, $session_id, $reply_id, $command_string);
socket_sendto($this->socket, $buf, strlen($buf), 0, $this->ip, $this->port);
try {
socket_recvfrom($this->socket, $this->received_data, 1024, 0, $this->ip, $this->port);
$bytes = $this->getSizeAttendance();
if ($bytes) {
while ($bytes > 0) {
socket_recvfrom($this->socket, $received_data, 1032, 0, $this->ip, $this->port);
array_push($this->attendance_data, $received_data);
$bytes -= 1024;
}
$this->session_id = hexdec($u['h6'] . $u['h5']);
socket_recvfrom($this->socket, $received_data, 1024, 0, $this->ip, $this->port);
}
$attendance = array();
if (count($this->attendance_data) > 0) {
for ($x = 0; $x < count($this->attendance_data); $x++) {
if ($x > 0) {
$this->attendance_data[$x] = substr($this->attendance_data[$x], 8);
}
}
$attendance_data = implode('', $this->attendance_data);
$attendance_data = substr($attendance_data, 10);
echo var_dump($attendance_data);
while (strlen($attendance_data) > 40) {
$u = unpack('H78', substr($attendance_data, 0, 39));
$u1 = hexdec(substr($u[1], 4, 2));
$u2 = hexdec(substr($u[1], 6, 2));
$uid = $u1 + ($u2 * 256);
$id = str_replace("\0", '', hex2bin(substr($u[1], 8, 16)));
$state = hexdec(substr($u[1], 56, 2));
$timestamp = $this->decodeTime(hexdec($this->reverseHex(substr($u[1], 58, 8))));
array_push($attendance, array($uid, $id, $state, $timestamp));
$attendance_data = substr($attendance_data, 40);
}
}
return $attendance;
} catch (exception $e) {
return false;
}
}
public function clearAttendance()
{
$command = CMD_CLEAR_ATTLOG;
return $this->execCommand($command);
}
}
TEST2.php:
<?php
require 'zklibrary.php';
$zk = new ZKLibrary('192.168.XX.XX', 4370);
$zk->connect();
$zk->disableDevice();
$users = $zk->getUser();
$log_kehadiran = $zk->getAttendance();
$absensi = $zk->getAbsensi();
//cek isi attendance isinya apa saja.
echo var_dump($users);
?>
<table width="100%" border="1" cellspacing="0" cellpadding="0" style="border-collapse:collapse;">
<thead>
<tr>
<td width="25">No</td>
<td>UID</td>
<td>ID</td>
<td>Name</td>
<td>Role</td>
<td>Password</td>
</tr>
</thead>
<tbody>
<?php
$no = 0;
foreach($log_kehadiran as $key => $uItem)
{
$no++;
?>
<tr>
<td><?php echo $no; ?></td>
<td><?php echo($uItem['uid']); ?></td>
<td><?php echo($uItem['id']); ?></td>
<td><?php echo($uItem['state']); ?></td>
<td><?php echo($uItem['timestamp']); ?></td>
<td><?php echo($uItem['type']); ?> </td>
</tr>
<?php
}
?>
</tbody>
</table>
<table width="100%" border="1" cellspacing="0" cellpadding="0" style="border-collapse:collapse;">
<thead>
<tr>
<td width="25">No</td>
<td>UID</td>
<td>ID</td>
<td>State</td>
<td>Date</td>
<td>Time</td>
</tr>
</thead>
<tbody>
<?php
$no = 0;
foreach($absensi as $key => $item)
{
$no++;
?>
<tr>
<td><?php echo $no; ?></td>
<td><?php echo($item['uid']); ?></td>
<td><?php echo($item['id']); ?></td>
<td><?php echo($item['state']); ?></td>
<td><?php echo($item['date']); ?></td>
<td><?php echo($item['time']); ?> </td>
</tr>
<?php
}
echo var_dump($absensi);
?>
</tbody>
</table>
<?php
$zk->enableDevice();
$zk->disconnect();
?>
如何使用ZkLibrary从机器上检索4000条考勤数据?或者还有其他办法可以从机器上获取考勤日志吗?我恳请您的帮助,我真的很困惑。我搜索了一些教程,但似乎都不起作用。 :-(
也许您可以使用ZK Soap PHP Library中的ZK Soap PHP Library。
可以获取带日期范围的考勤记录。
只需使用:
// reference the ZK Soap PHP namespace
use Fahriztx\Zksoapphp\Fingerprint;
// initial
$machine = Fingerprint::connect('192.168.1.175', '80', '123456');
// get machine status
echo "Machine Status : ".$machine->getStatus(); // connect | disconnect
// get all log data
print_r($machine->getAttendance()); // return Array of Attendance Log
// get all log data with date
print_r($machine->getAttendance('all', '2022-05-01')); // return Array of Attendance Log
// get all log data with date range
print_r($machine->getAttendance('all', '2022-05-01', '2022-05-10')); // return Array of Attendance Log
// get specific pin log data
print_r($machine->getAttendance(1)); // return Array of Attendance Log
// OR Array
print_r($machine->getAttendance([1, 2])); // return Array of Attendance Log
无需编写套接字连接和 XML 负载。
我在 python 中使用它时遇到了同样的问题 你解决问题了吗 您能否分享一下您是如何解决它的,以便我也可以在我的代码中使用它