php 使用php和mysql的通知系统
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32717824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Notification system using php and mysql
提问by Zalaboza
I wanted to implement a notification system for our school, it's a php/mysql webapp that is not opened for public, so it doesn't receive much traffic. "daily 500-1000 visitor".
我想为我们学校实现一个通知系统,它是一个不向公众开放的php/mysql webapp,所以它不会收到太多流量。“每天 500-1000 名访客”。
1. My initial approach was using MYSQL triggers:
1. 我最初的方法是使用 MYSQL 触发器:
I used a Mysql AFTER INSERT trigger
to add records to a table named notifications
. Something like.
我使用 MysqlAFTER INSERT trigger
将记录添加到名为notifications
. 就像是。
'CREATE TRIGGER `notify_new_homwork` AFTER INSERT ON `homeworks`
FOR EACH ROW INSERT INTO `notifications`
( `from_id`, `note`, `class_id`)
VALUES
(new.user_id,
concat('A New homework Titled: "',left(new.title,'50'),
'".. was added' )
,new.subject_id , 11);'
This kind of black magic worked very well, yet i couldn't keep track of if this notification is new "to show count of new notifications for user". so i added a page named notifications.
这种黑魔法效果很好,但我无法跟踪此通知是否是新的“向用户显示新通知的数量”。所以我添加了一个名为通知的页面。
Notifications are retrieved with something like
用类似的东西检索通知
SELECT n.* from notifications n
JOIN user_class on user_class.class_id = n.class_id where user_class.user_id = X;
Note: table user_class link user to class "user_id,class_id,subject_id" -subject is null unless user is a teacher'
注意:表 user_class 将用户链接到班级“user_id,class_id,subject_id”-subject 为空,除非用户是教师”
Now my next challenges are.
现在我的下一个挑战是。
- how to keep track of new vs old notifications per user?
- how can i aggregate notifications that are similar to user into one row ?
- 如何跟踪每个用户的新旧通知?
- 如何将与用户相似的通知汇总为一行?
example if 2 user commented on something, then do not insert a new row, just update the old one with something like 'userx and 1 other commented on hw'.
例如,如果 2 个用户评论某事,则不要插入新行,只需使用诸如“userx 和其他 1 个评论 hw”之类的内容更新旧行。
Thanks alot
非常感谢
Edit
编辑
As per answer below, to set a read/unread flag on row, i will need to have a row for each student not just a row for the whole class.. which means editing the trigger to something like
根据下面的答案,要在行上设置已读/未读标志,我需要为每个学生设置一行,而不仅仅是整个班级的一行..这意味着将触发器编辑为类似的内容
insert into notifications (from_id,note,student_id,isread)
select new.user_id,new.note,user_id,'0' from user_class where user_class.class_id = new.class_id group by user_class.user_id
回答by Mario
Well this question is 9 months old so i'm not sure if OP is still in the need of an answer but due the many views and the tasty bounty I would like to also add my mustard (German saying..).
好吧,这个问题已经 9 个月大了,所以我不确定 OP 是否仍然需要答案,但由于有很多观点和美味的赏金,我还想添加我的芥末(德语说..)。
In this post I will try to make a simple explained example on how to start building a notification system.
在这篇文章中,我将尝试制作一个关于如何开始构建通知系统的简单解释示例。
Edit:Well ok this turned out way, way, way longer than I expected it to be. I got really tired in the end, i'm sorry.
编辑:好吧,结果是这样,方式,方式比我预期的要长。最后我真的累了,对不起。
WTLDR;
WTLDR;
Question 1:have a flag on every notification.
问题 1:在每个通知上都有一个标志。
Question 2:Still store every notification as a single record inside your database and group them when they are requested.
问题 2:仍然将每个通知作为单个记录存储在数据库中,并在请求时将它们分组。
Structure
结构
I assume that the notifications will look something like:
我假设通知看起来像:
+---------------------------------------------+
| ? James has uploaded new Homework: Math 1+1 |
+---------------------------------------------+
| ? Jane and John liked your comment: Im s... |
+---------------------------------------------+
| ? The School is closed on independence day. |
+---------------------------------------------+
Behind the curtains this could look something like this:
在窗帘后面,这可能是这样的:
+--------+-----------+--------+-----------------+-------------------------------------------+
| unread | recipient | sender | type | reference |
+--------+-----------+--------+-----------------+-------------------------------------------+
| true | me | James | homework.create | Math 1 + 1 |
+--------+-----------+--------+-----------------+-------------------------------------------+
| true | me | Jane | comment.like | Im sick of school |
+--------+-----------+--------+-----------------+-------------------------------------------+
| true | me | John | comment.like | Im sick of school |
+--------+-----------+--------+-----------------+-------------------------------------------+
| false | me | system | message | The School is closed on independence day. |
+--------+-----------+--------+-----------------+-------------------------------------------+
Note:I don't recommend to group the notifications inside the database, do that on runtime this keeps things a lot more flexible.
注意:我不建议在数据库内对通知进行分组,在运行时这样做可以使事情更加灵活。
- Unread
Every notification should have a flag to indicate if the recipient has already opened the notification. - Recipient
Defines who receives the notification. - Sender
Defines who triggered the notification. - Type
Instead of having every Message in plain text inside your database create types. This way you can create special handlers for different notification types inside your backend. Will reduce the amount of data stored inside your database and gives your even more flexibility, enabled easy translating of notification, changes of past messages etc.. - Reference
Most notifications will have a Reference to a record on your database or your application.
- 未读
每个通知都应该有一个标志来指示收件人是否已经打开了通知。 - 接收者
定义接收通知的人。 - 发件人
定义谁触发了通知。 - 类型
而不是让数据库中的每条消息都以纯文本形式创建类型。通过这种方式,您可以在后端为不同的通知类型创建特殊的处理程序。将减少存储在数据库中的数据量,并为您提供更大的灵活性,启用轻松翻译通知、更改过去消息等。 - 参考
大多数通知都有对数据库或应用程序记录的参考。
Every system I have been working on had a simple 1 to 1reference relationship on a notification, you might have an 1 to nkeep in mind that I will continue my example with 1:1. This also means that I don't need a field defining what type of object is referenced because this is defined by the notification type.
我一直在研究的每个系统在通知上都有一个简单的1 对 1引用关系,您可能有1 对 n 的关系,请记住,我将继续以 1:1 举例。这也意味着我不需要定义引用什么类型的对象的字段,因为这是由通知类型定义的。
SQL Table
SQL表
Now when defining a real table structure for SQL we come to a few decisions in terms of the database design. I will go with simplest solution which will look something like this:
现在,当为 SQL 定义一个真正的表结构时,我们在数据库设计方面做出了一些决定。我将采用最简单的解决方案,它看起来像这样:
+--------------+--------+---------------------------------------------------------+
| column | type | description |
+--------------+--------+---------------------------------------------------------+
| id | int | Primary key |
+--------------+--------+---------------------------------------------------------+
| recipient_id | int | The receivers user id. |
+--------------+--------+---------------------------------------------------------+
| sender_id | int | The sender's user id. |
+--------------+--------+---------------------------------------------------------+
| unread | bool | Flag if the recipient has already read the notification |
+--------------+--------+---------------------------------------------------------+
| type | string | The notification type. |
+--------------+--------+---------------------------------------------------------+
| parameters | array | Additional data to render different notification types. |
+--------------+--------+---------------------------------------------------------+
| reference_id | int | The primary key of the referencing object. |
+--------------+--------+---------------------------------------------------------+
| created_at | int | Timestamp of the notification creation date. |
+--------------+--------+---------------------------------------------------------+
Or for the lazy folks the SQL create table commandfor this example:
或者对于懒惰的人,此示例的SQL 创建表命令:
CREATE TABLE `notifications` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`recipient_id` int(11) NOT NULL,
`sender_id` int(11) NOT NULL,
`unread` tinyint(1) NOT NULL DEFAULT '1',
`type` varchar(255) NOT NULL DEFAULT '',
`parameters` text NOT NULL,
`reference_id` int(11) NOT NULL,
`created_at` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
PHP Service
PHP服务
This implementation depends completely on the needs of your application, Note:This is an example not the golden standard on how to build an notification system in PHP.
此实现完全取决于您的应用程序的需求,注意:这不是如何在 PHP 中构建通知系统的黄金标准的示例。
Notification model
通知模型
This is an example base model of the notification itself, nothing fancy just the needed properties and the abstract methods messageForNotification
and messageForNotifications
we expected being implemented in the different notification types.
这是通知本身的示例基本模型,没有什么特别的,只是所需的属性和抽象方法messageForNotification
,messageForNotifications
我们期望在不同的通知类型中实现。
abstract class Notification
{
protected $recipient;
protected $sender;
protected $unread;
protected $type;
protected $parameters;
protected $referenceId;
protected $createdAt;
/**
* Message generators that have to be defined in subclasses
*/
public function messageForNotification(Notification $notification) : string;
public function messageForNotifications(array $notifications) : string;
/**
* Generate message of the current notification.
*/
public function message() : string
{
return $this->messageForNotification($this);
}
}
You will have to add a constructor, getters, settersand that kind of stuff by yourself in your own style, i'm not going to provide a ready to use Notification system.
您将不得不以自己的风格自行添加构造函数、getter、setter和类似的东西,我不会提供现成的通知系统。
Notification Types
通知类型
Now you can create a new Notification
subclass for every type. This following example would handle the like actionof a comment:
现在您可以Notification
为每种类型创建一个新的子类。以下示例将处理评论的类似操作:
- Ray has liked your comment. (1 notification)
- John and Jane liked your comment. (2 notifications)
- Jane, Johnny, James and Jenny liked your comment. (4 notifications)
- Jonny, James and 12 others liked your comment. (14 notifications)
- 雷喜欢你的评论。(1 条通知)
- 约翰和简喜欢你的评论。(2 条通知)
- 简、强尼、詹姆斯和珍妮喜欢你的评论。(4 条通知)
- 强尼、詹姆斯和其他 12 人喜欢你的评论。(14 条通知)
Example implementation:
示例实现:
namespace Notification\Comment;
class CommentLikedNotification extends \Notification
{
/**
* Generate a message for a single notification
*
* @param Notification $notification
* @return string
*/
public function messageForNotification(Notification $notification) : string
{
return $this->sender->getName() . 'has liked your comment: ' . substr($this->reference->text, 0, 10) . '...';
}
/**
* Generate a message for a multiple notifications
*
* @param array $notifications
* @return string
*/
public function messageForNotifications(array $notifications, int $realCount = 0) : string
{
if ($realCount === 0) {
$realCount = count($notifications);
}
// when there are two
if ($realCount === 2) {
$names = $this->messageForTwoNotifications($notifications);
}
// less than five
elseif ($realCount < 5) {
$names = $this->messageForManyNotifications($notifications);
}
// to many
else {
$names = $this->messageForManyManyNotifications($notifications, $realCount);
}
return $names . ' liked your comment: ' . substr($this->reference->text, 0, 10) . '...';
}
/**
* Generate a message for two notifications
*
* John and Jane has liked your comment.
*
* @param array $notifications
* @return string
*/
protected function messageForTwoNotifications(array $notifications) : string
{
list($first, $second) = $notifications;
return $first->getName() . ' and ' . $second->getName(); // John and Jane
}
/**
* Generate a message many notifications
*
* Jane, Johnny, James and Jenny has liked your comment.
*
* @param array $notifications
* @return string
*/
protected function messageForManyNotifications(array $notifications) : string
{
$last = array_pop($notifications);
foreach($notifications as $notification) {
$names .= $notification->getName() . ', ';
}
return substr($names, 0, -2) . ' and ' . $last->getName(); // Jane, Johnny, James and Jenny
}
/**
* Generate a message for many many notifications
*
* Jonny, James and 12 other have liked your comment.
*
* @param array $notifications
* @return string
*/
protected function messageForManyManyNotifications(array $notifications, int $realCount) : string
{
list($first, $second) = array_slice($notifications, 0, 2);
return $first->getName() . ', ' . $second->getName() . ' and ' . $realCount . ' others'; // Jonny, James and 12 other
}
}
Notification manager
通知管理器
To work with your notifications inside your application create something like a notification manager:
要在应用程序中处理通知,请创建类似通知管理器的内容:
class NotificationManager
{
protected $notificationAdapter;
public function add(Notification $notification);
public function markRead(array $notifications);
public function get(User $user, $limit = 20, $offset = 0) : array;
}
The notificationAdapter
property should contain the logic in direct communication with your data backend in the case of this example mysql.
notificationAdapter
在此示例 mysql 的情况下,该属性应包含与数据后端直接通信的逻辑。
Creating notifications
创建通知
Using mysql
triggers is not wrong, because there is no wrong solution. What works, works..But I strongly recommend to not let the database handle application logic.
使用mysql
触发器并没有错,因为没有错误的解决方案。什么有效,有效......但我强烈建议不要让数据库处理应用程序逻辑。
So inside the notification manager you might want to do something like this:
所以在通知管理器中你可能想要做这样的事情:
public function add(Notification $notification)
{
// only save the notification if no possible duplicate is found.
if (!$this->notificationAdapter->isDoublicate($notification))
{
$this->notificationAdapter->add([
'recipient_id' => $notification->recipient->getId(),
'sender_id' => $notification->sender->getId()
'unread' => 1,
'type' => $notification->type,
'parameters' => $notification->parameters,
'reference_id' => $notification->reference->getId(),
'created_at' => time(),
]);
}
}
Behind the add
method of the notificationAdapter
can be a raw mysql insert command. Using this adapter abstraction enables you to switch easily from mysql to a document based database like mongodbwhich would make sense for a Notification system.
后面的add
方法notificationAdapter
可以是一个原始的mysql插入命令。使用此适配器抽象,您可以轻松地从 mysql 切换到基于文档的数据库,如mongodb,这对通知系统很有意义。
The isDoublicate
method on the notificationAdapter
should simply check if there is already a notification with the same recipient
, sender
, type
and reference
.
在isDoublicate
对方法notificationAdapter
应该简单地检查是否已经存在具有相同的通知recipient
,sender
,type
和reference
。
I cannot point out enough that this is only a example.(Also I really have to shorten the next steps this post is getting ridiculously long -.-)
我不能充分指出这只是一个例子。(此外,我真的必须缩短接下来的步骤,这篇文章的长度太长了-.-)
So assuming you have some kind of controller with an action when a teacher uploads homework:
因此,假设您有某种控制器在教师上传作业时执行操作:
function uploadHomeworkAction(Request $request)
{
// handle the homework and have it stored in the var $homework.
// how you handle your services is up to you...
$notificationManager = new NotificationManager;
foreach($homework->teacher->students as $student)
{
$notification = new Notification\Homework\HomeworkUploadedNotification;
$notification->sender = $homework->teacher;
$notification->recipient = $student;
$notification->reference = $homework;
// send the notification
$notificationManager->add($notification);
}
}
Will create a notification for every teacher's student when he uploads a new homework.
上传新作业时,将为每位教师的学生创建通知。
Reading the notifications
阅读通知
Now comes the hard part. The problem with grouping on the PHP side is that you will have to load allnotifications of the current user to group them correctly. This would be bad, well if you have only a few users it would probably still be no problem, but that doesn't make it good.
现在是困难的部分。PHP 端分组的问题是您必须加载当前用户的所有通知才能正确分组。这会很糟糕,如果你只有几个用户,它可能仍然没有问题,但这并不好。
The easy solution is to simply limit the number of notifications requested and only grouping these. This will work fine when there are not many similar notifications (like 3-4 per 20). But lets say the post of a user / student gets about a hundred likes and you only select the last 20 notifications. The user will then only see that 20 people liked his post also that would be his only notification.
简单的解决方案是简单地限制请求的通知数量,并且只对这些进行分组。当没有很多类似的通知(例如每 20 个 3-4 个)时,这将正常工作。但是假设用户/学生的帖子获得了大约一百个赞,而您只选择了最后 20 个通知。用户然后只会看到 20 人喜欢他的帖子,这也是他唯一的通知。
A "correct" solution would be grouping the notifications already on the database and selecting only some samples per notification group. Than you would just have to inject the real count into your notification messages.
“正确”的解决方案是将数据库中已有的通知分组,并为每个通知组仅选择一些样本。比您只需将实际计数注入通知消息即可。
You probably didn't read the text below so let me continue with a snippet:
你可能没有阅读下面的文字,让我继续看一个片段:
select *, count(*) as count from notifications
where recipient_id = 1
group by `type`, `reference_id`
order by created_at desc, unread desc
limit 20
Now you know what notifications should be around for the given user and how many notifications the group contains.
现在您知道给定用户应该有哪些通知以及该组包含多少通知。
And now the shitty part. I still could not find out a better way to select a limited number of notifications for each group without doing a query for every group. All suggestions here are very welcome.
现在是糟糕的部分。我仍然找不到更好的方法来为每个组选择有限数量的通知而不对每个组进行查询。非常欢迎这里的所有建议。
So I do something like:
所以我做这样的事情:
$notifcationGroups = [];
foreach($results as $notification)
{
$notifcationGroup = ['count' => $notification['count']];
// when the group only contains one item we don't
// have to select it's children
if ($notification['count'] == 1)
{
$notifcationGroup['items'] = [$notification];
}
else
{
// example with query builder
$notifcationGroup['items'] = $this->select('notifications')
->where('recipient_id', $recipient_id)
->andWehere('type', $notification['type'])
->andWhere('reference_id', $notification['reference_id'])
->limit(5);
}
$notifcationGroups[] = $notifcationGroup;
}
I will now continue assuming that the notificationAdapter
s get
method implements this grouping and returns an array like this:
我现在将继续假设notificationAdapter
sget
方法实现了这个分组并返回一个这样的数组:
[
{
count: 12,
items: [Note1, Note2, Note3, Note4, Note5]
},
{
count: 1,
items: [Note1]
},
{
count: 3,
items: [Note1, Note2, Note3]
}
]
Because we always have at least one notification in our group and our ordering prefers Unreadand Newnotifications we can just use the first notification as a sample for rendering.
因为我们总是在我们的组中至少有一个通知,而且我们的排序更喜欢未读和新通知,所以我们可以只使用第一个通知作为渲染示例。
So to be able to work with these grouped notifications we need a new object:
因此,为了能够处理这些分组通知,我们需要一个新对象:
class NotificationGroup
{
protected $notifications;
protected $realCount;
public function __construct(array $notifications, int $count)
{
$this->notifications = $notifications;
$this->realCount = $count;
}
public function message()
{
return $this->notifications[0]->messageForNotifications($this->notifications, $this->realCount);
}
// forward all other calls to the first notification
public function __call($method, $arguments)
{
return call_user_func_array([$this->notifications[0], $method], $arguments);
}
}
And finally we can actually put most of the stuff together. This is how the get function on the NotificationManager
might look like:
最后,我们实际上可以将大部分内容放在一起。这就是 get 函数的NotificationManager
样子:
public function get(User $user, $limit = 20, $offset = 0) : array
{
$groups = [];
foreach($this->notificationAdapter->get($user->getId(), $limit, $offset) as $group)
{
$groups[] = new NotificationGroup($group['notifications'], $group['count']);
}
return $gorups;
}
And really finally inside a possible controller action:
最后在一个可能的控制器操作中:
public function viewNotificationsAction(Request $request)
{
$notificationManager = new NotificationManager;
foreach($notifications = $notificationManager->get($this->getUser()) as $group)
{
echo $group->unread . ' | ' . $group->message() . ' - ' . $group->createdAt() . "\n";
}
// mark them as read
$notificationManager->markRead($notifications);
}
回答by geggleto
Answer:
回答:
Introduce a read/unread variable on the notification. You can then pull only unread notifications by doing ... WHERE status = 'UNREAD' in your sql.
You can't really... you will want to push that notification. What you can do is still aggregate them though by using GROUP BY. You would likely want to group on something unique like a new homework so it might be something like ... GROUP BY
homework
.id
在通知中引入一个已读/未读变量。然后,您可以通过在 sql 中执行 ... WHERE status = 'UNREAD' 来仅提取未读通知。
你真的不能......你会想要推送那个通知。您可以做的仍然是使用 GROUP BY 聚合它们。您可能希望将一些独特的东西(例如新作业)分组,因此它可能类似于 ... GROUP BY
homework
。id
回答by Razor_alpha
You can solve the issue with making a NotificationsRead table, containing the ID of the user and the ID of the notification the user wanted to mark as read. (This way you can keep each students and the teacher separated.) Then you can join that table to your notification's table and you will know if it should be considered old or new.
您可以通过制作 NotificationsRead 表来解决该问题,其中包含用户的 ID 和用户想要标记为已读的通知的 ID。(通过这种方式,您可以将每个学生和老师分开。)然后您可以将该表加入通知表,您就会知道它是旧的还是新的。
geggleto's answer was right about the second part, you can grab the notifications with SELECT *, COUNT(*) AS counter WHERE ... GROUP BY 'type'
then you will know how many of the same type you have there and you can prepare the 'userx and 1 other commented on hw' on view.
geggleto 对第二部分的回答是正确的,您可以获取通知,SELECT *, COUNT(*) AS counter WHERE ... GROUP BY 'type'
然后您将知道那里有多少相同类型,并且您可以准备“userx 和 1 个其他评论 hw”的视图。
I'd also suggest you not to store the whole text you want to display, store the required information instead, like: from_id, class_id, type, name and so - this way you can change mechanisms easier later if you need to, and you have to store less.
我还建议您不要存储要显示的整个文本,而是存储所需的信息,例如:from_id、class_id、type、name 等 - 这样您以后可以在需要时更轻松地更改机制,并且您必须少存储。
回答by Blaz3ng
For those who are looking for a way to not use an app, you can use vanilla PHP and MySQL without using an application. Upon adding a piece of homework, you can add a notification. (yes I know this is open to SQL injection but I'm using regular MySQL for simplicity sake) SQL for when someone adds homework:
对于那些正在寻找一种不使用应用程序的方法的人,您可以在不使用应用程序的情况下使用 vanilla PHP 和 MySQL。添加作业后,您可以添加通知。(是的,我知道这对 SQL 注入是开放的,但为了简单起见,我使用的是常规 MySQL)当有人添加作业时的 SQL:
$noti_homework = "INSERT INTO homework(unread, username, recipient, topic) VALUES(true, user_who_added_hw, user_who_receives_notification, homework_name);
Then you can check whether the notification is unread:
然后您可以检查通知是否未读:
$noti_select = "SELECT FROM homework WHERE recipient='".$_SESSION['username']."' AND unread='true'";
$noti_s_result = $conn->query($noti_select);
$noti_s_row = $noti_s_result = $noti_s_result->fetch_assoc();
if ($noti_s_row['unread'] == true) {
}
Finally, you can echo the notification if it's true.
最后,如果通知为真,您可以回显通知。
if ($noti_s_row['unread'] == true) {
echo $noti_s_row['username'] . " has sent out the homework " . $noti_s_row['homework'] . ".";
}
The method for liking a comment is pretty similar and in fact a lot easier.
点赞评论的方法非常相似,实际上要容易得多。
$noti_like = "INSERT INTO notification_like(unread, username, recepient), VALUES(true, user_who_followed, user_who_recieves_notification);
You then just follow the same pattern of echoing the rows like so:
然后,您只需遵循相同的模式来回显行,如下所示:
$noti_like = "INSERT INTO notification_like(unread, username, recipient), VALUES(true, user_who_followed, user_who_receives_notification);
$noti_like_select = "SELECT FROM notification_like WHERE recipient='".$_SESSION['username']."' AND unread='true'";
$noti_l_result = $conn->query($noti_like_select);
$noti_l_row = $noti_s_result = $noti_l_result->fetch_assoc();
if ($noti_l_row['unread'] == true) {
echo $noti_l_row['username'] . " has liked your topic!";
}
Then for getting amount of notifications:
然后获取通知数量:
$count_like = "SELECT COUNT(*) FROM notification_like WHERE recipient='".$_SESSION['username']."' AND unread='true'";
$num_count = $count_like->fetch_row();
$count_hw = "SELECT COUNT(*) FROM homework WHERE recipient='".$_SESSION['username']."' AND unread='true'";
$num_count_hw = $count_hw->fetch_row();
Using PHP you can echo the two variables, $num_count and $num_count_hw.
使用 PHP,您可以回显 $num_count 和 $num_count_hw 这两个变量。
$num_count_real = $num_count[0];
$num_count_hw_real = $num_count_hw[0];
echo $num_count_real + $num_count_hw_real;
None of this code is tested FYI. Hope this helped :)
这些代码都没有经过测试,仅供参考。希望这有帮助:)