// +---------------------------------------------------------------------- declare(strict_types=1); namespace addon\haonav\command; use think\console\Command; use think\console\Input; use think\console\input\Option; use think\console\Output; use addon\haonav\model\Links as LinksModel; /** * haonav 死链巡检命令 * * 用法: * php think haonav:checklinks # 全量检测 * php think haonav:checklinks --limit=50 # 只检测最久未检测的 50 条 * * crontab 示例(每天凌晨 3 点全量): * 0 3 * * * cd /path/to/site && php think haonav:checklinks >> runtime/haonav_check.log 2>&1 */ class CheckLinks extends Command { protected function configure() { $this->setName('haonav:checklinks') ->addOption('limit', null, Option::VALUE_OPTIONAL, '本次最多检测条数(0=全部,按最久未检测优先)', '0') ->addOption('timeout', null, Option::VALUE_OPTIONAL, '单条检测超时秒数', '8') ->setDescription('haonav 网址导航死链巡检(更新 status_code / last_check_at)'); } protected function execute(Input $input, Output $output) { $limit = max(0, (int)$input->getOption('limit')); $timeout = max(1, (int)$input->getOption('timeout')); set_time_limit(0); $output->writeln('[haonav] 开始死链巡检 limit=' . ($limit ?: '全部') . ' timeout=' . $timeout . 's ...'); $start = microtime(true); $stats = $limit > 0 ? LinksModel::checkBatch($limit, $timeout) : LinksModel::checkAllLinks($timeout); $output->writeln(sprintf( '[haonav] 完成:共 %d 条,正常 %d,异常 %d,耗时 %.1fs', $stats['total'], $stats['ok'], $stats['dead'], microtime(true) - $start )); if (!empty($stats['offlined'])) { $output->writeln('[haonav] 已自动下线 ' . $stats['offlined'] . ' 条死链(阈值见 deadlink_threshold 配置)'); } if (!empty($stats['recovered'])) { $output->writeln('[haonav] 已自动恢复 ' . $stats['recovered'] . ' 条(deadlink_recover 已开启)'); } return 0; } }