使用 ZkLibrary PHP 从考勤设备获取AttLog 数据(解决方案 C1)

问题描述 投票:0回答:2

我目前正在开发一项功能,使用 ZkLibrarySolution 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']); ?>&nbsp;</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']); ?>&nbsp;</td>
    </tr>
  <?php
}

echo var_dump($absensi);
?>
</tbody>
</table>

<?php

$zk->enableDevice();
$zk->disconnect();

?>


                        
            

如何使用ZkLibrary从机器上检索4000条考勤数据?或者还有其他办法可以从机器上获取考勤日志吗?我恳请您的帮助,我真的很困惑。我搜索了一些教程,但似乎都不起作用。 :-(

php sockets soap xml-rpc laragon
2个回答
0
投票

也许您可以使用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 负载。


0
投票

我在 python 中使用它时遇到了同样的问题 你解决问题了吗 您能否分享一下您是如何解决它的,以便我也可以在我的代码中使用它

© www.soinside.com 2019 - 2024. All rights reserved.