简介:一份基于PHP的自动阅读挂机任务系统源码,面向具备PHP基础的中小站长和Web开发者,用于搭建广告新闻浏览、积分赚取、支付宝提现及三级团队推广于一体的任务平台。系统将自动挂机浏览与积分激励结合,并通过“小熊阅读”和三级团队机制提升留存、带动社交推广,适合流量变现与会员运营场景。
资源包共4个文件,约41.27MB,包含源码zip包、SQL数据库脚本、安装说明txt和htm页面说明。SQL脚本可初始化会员、积分、提现数据表,txt与htm辅助完成环境配置和部署。目前已有1198人学习/下载,适合作为学习PHP任务系统的完整案例。
通过这套源码,读者可获得可直接部署的PHP程序、数据库建表语句和部署文档,理解积分结算、支付宝提现流程、三级团队分成等实现思路;对想低成本搭建阅读挂机或广告任务平台的站长,也是一套可二次开发的现成方案。
1. 挂机阅读任务系统到底拆出了什么
这套源码包的核心,是把“用户手动浏览广告新闻”这件事替换成“服务器自动模拟浏览”。从压缩包里的文件结构来看,readme.htm 是项目说明,Data.sql 是完整数据库备份,Server.zip 里装的是核心 PHP 服务端逻辑。整个系统的业务闭环是:用户注册登录后,后台任务队列自动为其执行阅读动作,完成后系统按规则给用户账户增加积分,积分累计到指定阈值后,用户可以在前台发起支付宝提现申请,管理员审核后打款。用户还可以通过邀请链接发展下级,形成三级团队,团队成员的阅读收益会给上级按比例返佣。
值得先说明的是,这类源码本质上是一个带任务调度、积分账务、支付对接、分销关系链的完整业务系统,而不是一个简单的“模拟点击器”。开发者在拿到源码后,真正需要关注的是四个层面:PHP 任务守护进程怎么写、积分流水如何保证不混乱、支付宝异步回调怎么验签、三级分销的层级关系如何设计。下面的篇幅按这几个模块逐个拆。
2. 任务调度与自动阅读挂机逻辑的实现
2.1 挂机浏览的底层原理
自动阅读挂机,本质上就是服务端用 HTTP 客户端去请求新闻或广告的 URL,并在请求中携带用户的会话标识,让服务端认为这是一个真实用户在访问。与浏览器自动化(如 Puppeteer、Selenium)相比,PHP 环境里更常见的做法是使用 cURL 扩展,配合 Cookie 保持登录态、User-Agent 伪装浏览器标识,并通过 Referer 字段模拟从站内跳转过来的访问路径。
源码里这一模块的典型工作流程是:任务调度器从任务表中拉取当前待执行的阅读任务,读取任务对应的文章 URL、阅读时长、用户标识,然后向目标地址发起请求。请求完成后,脚本更新任务状态,并调用积分服务为对应用户增加积分。整个流程不涉及浏览器渲染,因此对服务器资源开销比较小,一台低配云主机就能扛住几百个并发任务。
// 自动阅读任务的单个执行单元 public function runReadTask($taskId) { $task = Db::name('read_task')->where('id', $taskId)->find(); if (!$task || $task['status'] != 0) { return false; // 已执行或不存在,跳过 } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $task['article_url']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIE, $task['user_cookie']); // 用户登录态 curl_setopt($ch, CURLOPT_USERAGENT, $this->randomUserAgent()); // 随机UA,避免被识别 curl_setopt($ch, CURLOPT_REFERER, $task['referer_url']); // 模拟站内来源 curl_setopt($ch, CURLOPT_TIMEOUT, 30); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode == 200) { // 请求成功后加工积分(延时模拟阅读时长为15秒) sleep(15); $this->awardPoints($task['uid'], $task['points'], '阅读任务'); Db::name('read_task')->where('id', $taskId)->update(['status' => 1]); return true; } // 失败则保留任务,等待下次调度重试 return false; }这段逻辑中CURLOPT_COOKIE传入的是用户在前台登录后保存的会话 Cookie,CURLOPT_USERAGENT是随机生成的浏览器标识,防止目标服务器按 UA 特征做反爬限制。sleep(15)的目的是模拟真实用户阅读文章消耗的时长,防止文章阅读记录被判定为秒刷。实际生产环境中,阅读时长通常是可配置的,存到任务表或系统参数表里。
2.2 调度器的选型与实现
有了单个执行单元,接下来要解决的问题是“谁把任务喂给这个执行单元”。PHP 环境下主流的方案有两种:crontab 定时触发和常驻队列消费。从 Server.zip 的源码结构来看,二者都有涉及,但核心的跑任务逻辑更适合用常驻 CLI 脚本来跑。
crontab 方案比较直观,直接在服务器上配置一个每分钟执行一次的调度入口。因为 crontab 的最小粒度是分钟,所以时间判断逻辑要写在脚本内部。队列方案则更稳妥,任务生成端把阅读任务写入队列表,消费端循环拉取并执行。源码中使用的是基于 MySQL 的队列表来实现,而不是 Redis,原因很简单:部署环境默认不强制要求 Redis,MySQL 队列表零依赖就能跑起来。
# crontab 配置示例,每分钟检查一次是否有待执行阅读任务 * * * * * /usr/bin/php /www/wwwroot/read/server/think queue:work --queue read_task --sleep 5 --tries 3queue:work是 ThinkPHP 框架的命令行队列消费指令,--sleep 5表示队列空闲时休眠 5 秒再检查下一轮,--tries 3表示单条任务执行失败最多重试 3 次。如果直接走 crontab 调消费端,这个命令会常驻内存持续消费,如果走定时脚本方式,则需要额外加--once参数让消费端执行单次后退出,否则 crontab 会叠加多个常驻进程。
需要特别注意的一点是,PHP 命令行模式下的memory_limit默认可能只有 128M,长驻进程跑久了容易内存溢出。在启动消费端之前,建议在脚本入口处显式调用ini_set('memory_limit', '512M'),或者在/usr/local/php/etc/php-cli.ini里单独调大命令行模式的内存限制。另外 PHP 的max_execution_time对 CLI 模式默认是 0,即不限制,但部分面板环境可能会强制改成 30 秒,这会导致长任务被中断,排查时要先确认这个配置项。
3. 积分系统设计:流水账、防重复与任务校验
3.1 积分账务模型怎么建
积分系统的第一原则是“流水优先,余额其次”。任何积分变动都要记录一条流水,用户表里的积分余额只是流水汇总后的结果。这样做的目的是在出现争议时能够追溯每一步变动,也是后续接支付宝提现做对账的前提。源码的 Data.sql 里已经预设了三张关键表:用户表、积分流水表、积分规则表。
-- 积分流水表结构(按源码Data.sql精简) CREATE TABLE `points_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL COMMENT '用户ID', `points` int(11) NOT NULL DEFAULT '0' COMMENT '变动积分数,正数为增加,负数为扣减', `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '类型:1阅读奖励 2团队返佣 3提现扣减 4提现退回', `rel_id` int(11) NOT NULL DEFAULT '0' COMMENT '关联业务ID,如任务ID、提现申请ID', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注说明', `create_time` int(11) NOT NULL COMMENT '创建时间', PRIMARY KEY (`id`), KEY `idx_uid` (`uid`), KEY `idx_rel_id` (`rel_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分流水表';type字段里直接标出了四类最常见变动,其中rel_id是关联业务 ID,用于把流水和具体业务绑定。比如用户阅读了一篇文章获得积分,rel_id就存那篇文章的任务 ID;提现扣减时rel_id存提现申请表的 ID。这样在运营后台搜索某笔提现时,可以顺藤摸瓜找到对应的积分扣减记录。
3.2 防重复发放的核心手段
自动阅读场景里最大的风险是同一篇文章被重复计积分。源码的做法是在任务表中增加一个状态字段,任务从待执行变为已完成时,发放积分和更新状态放到同一个数据库事务里执行。这个方案的原理是:先把任务状态从 0 更新为 1(带条件WHERE status = 0),如果影响行数为 1,说明当前进程拿到了发放资格,再执行积分发放;如果影响行数为 0,说明已经有其他进程抢先将任务置为已完成,当前进程直接退出。
// 事务内防重复发放核心代码 Db::startTrans(); try { // 乐观锁更新,status=0 且 id=任务ID 才会被更新成功 $updated = Db::name('read_task') ->where('id', $taskId) ->where('status', 0) ->update(['status' => 1, 'finish_time' => time()]); if ($updated == 0) { Db::rollback(); return; // 已被处理,直接返回 } // 写入积分流水 Db::name('points_log')->insert([ 'uid' => $uid, 'points' => $points, 'type' => 1, 'rel_id' => $taskId, 'remark' => '阅读奖励', 'create_time' => time() ]); // 更新用户积分余额 Db::name('users')->where('uid', $uid)->setInc('points', $points); Db::commit(); } catch (\Exception $e) { Db::rollback(); // 记录异常日志 }这里使用setInc做数据库层面的原子自增,比先 SELECT 再 UPDATE 的方式更安全,因为后者在并发场景下可能丢更新。而isset 判断用户是否存在这类操作也要放在事务内完成,防止用户注销等极端情况。
除了任务表的状态校验,实际运营维度还要加两道防线:单日积分上限和阅读间隔限制。这两项在积分规则表里可以配置,比如每日阅读收益最多 2000 积分,连续两次自动阅读之间的最小间隔是 30 秒。因为自动挂机是服务端模拟行为,没有浏览器指纹等客户端特征,一旦任务调度过于频繁,很容易被新闻源判定为采集攻击,导致对方封禁服务器 IP。合理控制频率既保护系统,也保护对方的内容源。
3.3 积分规则的参数化配置
源码的积分规则表points_rule里,每一行定义了一个业务动作对应的积分值。通常包括:基础阅读奖励 5 积分、每多阅读一篇递增 1 积分、阅读时长超过 60 秒额外奖励 2 积分、三级推荐关系中对上级的返佣比例分别设置。这些规则不要写死在 PHP 代码里,改成数据库配置后,运营人员可以自行调参,不必每次改动都发布新版本。
points_rule表的关键字段建议为:action(代表业务动作,如read_reward)、points_value、extra_condition(附加条件)、status(是否启用)。在发放积分前用action查询出规则并校验extra_condition,这种设计能覆盖后续新增的积分玩法,避免频繁改表结构和业务代码。
4. 支付宝提现流程:验签、状态机与并发控制
4.1 提现申请到打款的完整链路
提现模块在业务流程上分为三步:用户申请提现、管理员审核、支付宝批量转账或单笔转账。用户在积分余额充足的情况下,填写提现金额和支付宝账号、姓名,系统创建一条提现申请记录,冻结对应积分;管理员在后台审核通过后,调用支付宝转账接口打款;支付宝异步通知返回结果后更新提现记录状态,打款成功则扣减冻结积分,打款失败则解冻积分并退回用户余额。
源码中提现申请表的典型状态字段用status表示,0为待审核、1为审核通过待打款、2为打款成功、3为打款失败、4为已拒绝。每次状态变更都要记录操作日志,特别是在打款失败时,要保留支付宝返回的错误码,方便后续人工排查。
4.2 支付宝异步通知的验签处理
支付宝的转账结果是通过异步通知(异步回调)推送到服务端的。收到通知后,第一件事是验签,确认通知确实来自支付宝,而不是伪造请求。源码中使用的是支付宝官方 SDK,验签逻辑集中在AlipayNotify类中,核心代码大致如下:
// 支付宝异步通知验签 public function notify() { $params = $_POST; // 支付宝异步通知以POST方式推送 // 调用SDK验签 $alipay = new \Alipay\AlipayTradeService($this->config); $result = $alipay->check($params); if (!$result) { // 验签失败,记录日志并返回失败标识 file_put_contents('/tmp/alipay_fail.log', json_encode($params) . PHP_EOL, FILE_APPEND); echo 'fail'; return; } // 验签通过后检查业务参数 $outBizNo = $params['out_biz_no']; // 商户转账订单号,也就是提现申请表里的提现单号 $status = $params['status']; // 转账状态:SUCCESS/FAIL/DEALING if ($this->updateWithdrawStatus($outBizNo, $status)) { echo 'success'; // 告诉支付宝不再重发通知 } else { echo 'fail'; } }check()方法内部会自动使用支付宝公钥对通知内容做 RSA2 验签,开发者不需要自己实现签名算法。out_biz_no与提现申请记录强关联,这里要注意它只能使用字母、数字和下划线,不能用原名或其他带特殊字符的字符串拼接。
在updateWithdrawStatus中,状态流转要做到幂等——同一笔通知重复到达时,不能重复给用户加钱或改状态。幂等实现方式是在更新 SQL 里加上前置状态条件:UPDATE withdraw SET status = 2 WHERE id = $id AND status = 1,只有当前状态仍然是“待打款”时才能变为“已打款”,防止并发通知导致重复入账。
4.3 并发控制与对账提醒
提现并发最常见的问题是:用户在极短时间内重复提交提现申请,或者同一笔提现在后台和管理员手动操作打款的同时收到支付宝自动通知。处理办法是在创建提现申请时加“处理中”状态,通过数据库唯一索引或 Redis 锁限制同一用户同时只能有一笔提现在途。
源码在提现申请表中使用了UNIQUE KEY uk_uid_status (uid, status)配合业务实现,但更稳妥的方式是单独增加一个lock字段,置 1 表示处理中,处理完成后再置 0。每一次状态变更都强制带上前置状态条件,在Application_Service层再做一层校验,双保险防止异常情况下资金重复结算。
管理员后台的“打款成功”操作也建议保留手动确认入口,用户反馈未到账时,可以凭支付宝转账订单号去商户后台核验,避免直接改数据库。如果系统接入的是支付宝单笔转账到余额接口,建议单独建一张转账记录表,保存接口返回的支付宝单号,与业务提现单号一一对应,后续对账全部以转账记录表为准。
5. 三级团队分销:层级算法与部署落地技巧
5.1 推荐关系与分佣计算
三级分销的数据库落点是一张用户推荐关系表,存储每个用户的直接上级pid,再通过联表查询得到上二级和上三级。源码的实现方式比较直接,关系表字段为uid、pid、level、create_time,用户注册时带上邀请码参数,系统根据邀请码找到邀请人写入记录。
-- 推荐关系表核心字段 CREATE TABLE `user_relation` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL COMMENT '用户ID', `pid` int(11) NOT NULL COMMENT '直接上级ID', `p_level` tinyint(1) NOT NULL DEFAULT '1' COMMENT '上级层级:1直接上级 2二级上级 3三级上级', `create_time` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_uid_pid` (`uid`, `pid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;分佣计算逻辑是:当用户完成一次阅读获得积分后,系统同时查询他的上三级关系。一级上级返佣 10%、二级 5%、三级 2%,比例存在系统配置表中。返佣同样走积分流水,type字段记为 2,remark里写明被推荐人昵称和推荐关系层级,方便用户在前台查看每一笔团队收益来源。
性能层面的优化点在查询上三级关系时不要递归去查,而是通过一次 JOIN 将三级用户一次性取出。源码中的做法是先查出直接上级,再用IN查询一次拿到上二级和上三级。层级固定为三级的业务不必为了“优雅”引入递归 CTE,简单直接的关联查询性能更好,也更容易维护。
5.2 LNMP 环境部署与任务进程监控
源码压缩包里自带安装说明,部署路径基本是 LNMP 环境:Nginx + MySQL + PHP 7.x + ThinkPHP 框架。解压后把站点根目录指向 public 目录,配置伪静态规则,导入 Data.sql 并修改数据库配置文件,然后设置定时任务启动队列消费即可跑通。
实际部署中优先建议使用宝塔面板或 OneinStack 这类运维工具。入口文件有跨目录调用需求的,要关闭防跨站攻击(open_basedir)选项,或把open_basedir配置为/www/wwwroot/根目录。PHP 需要安装fileinfo、curl、openssl扩展,缺少 fileinfo 时阿里云支付接口文档类业务会报错,这是安装新版源码最常见的环境坑。
# 任务进程守护(systemd unit 片段) [Unit] Description=PHP Queue Worker for ReadTask After=network.target [Service] User=www Group=www ExecStart=/usr/bin/php /www/wwwroot/read/server/think queue:work --queue read_task --sleep 5 --tries 3 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target用 systemd 管理队列进程比直接用 nohup 更可靠,进程挂了会自动拉起,服务器重启后也会自动恢复。在 bash 里tail -f /var/log/messages或查看journalctl -u read-task可以排查任务进程的输出日志。日常维护只需关注两件事:任务队列表里堆积的未执行任务数量是否持续增长,以及积分流水表中单位时间内产生的流水是否在合理区间。任务表堆积通常意味着消费进程异常,积分流水突增则多半是调度频率过快或刷量行为,需要通过限流参数来调整。
5.3 数据安全与反作弊的经验
自动阅读挂机这类项目天然带着被恶意刷量的风险。源码所带的二维校验(任务状态 + 单日上限)能拦住普通用户,但防不住专业工作室用脚本批量注册账号刷积分。部署上线前,最好在用户注册链路里加上同 IP 注册数量限制、同一设备指纹(User Agent + Accept 头组合)限制,并且把提现门槛设置成年化收益大于投入成本的水平,这样能过滤掉大量低质量刷量账号。
关于支付宝账号的实名核验,因为小项目通常不会直接接支付宝实名认证接口,保守做法是后台审核时人工比对提现人姓名与支付宝账号是否一致,更能保护平台资金安全。数据库备份建议每天自动导出,同时把points_log流水表按月分区,防止单表数据量过大后提现对账查询变慢。这套组合落地后,项目从源码到可运营状态的完整链路才算彻底跑通。
本文还有配套的精品资源,点击获取