场景:调用第三方接口,需要存储上万条数据,如果在浏览器端运行,会出现超时的情况;数据存储不完整,利用centOS stream 9的no hup命令来实现;切记:在宝塔上不可采用计划任务、进程守护等来解决该问题,这些是循环往复的,会造成数据存储时,大量重复数据;
我们利用tp8文档中的自定义指令;
https://doc.thinkphp.cn/v8_0/create_php_think.html
我创建了多应用模式,在index应用下,command文件夹下,创建了hello命令:
namespace app\index\command;use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;use think\facade\Db;
use think\facade\Log;use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;class Hello extends Command
{protected function configure(){$this->setName('hello')->addArgument('name', Argument::OPTIONAL, "your name")->addOption('city', null, Option::VALUE_REQUIRED, 'city name')->setDescription('Say Hello');}protected function execute(Input $input, Output $output){$output->writeln("开始拉取数据...");$this->getFlow();$output->writeln("完成!");}public function getFlowData(int $advID){$client = new Client();$url = 'https://ad.oceanengine.com/open_api/2/advertiser/fund/daily_stat/';$headers = ['Access-Token' => '', // 替换为真实 token'Content-Type' => 'application/json'];$startDate = '2025-02-01';$endDate = '2025-02-28';$body = ['advertiser_id' => $advID, // 替换为真实ID'start_date' => $startDate,'end_date' => $endDate,'page' => 1,'page_size' => 31];try {$response = $client->request('GET', $url, ['headers' => $headers,'json' => $body,'delay' => 2 ]);$responseBody = $response->getBody()->getContents();$data = json_decode($responseBody, true);// dd($data);if($data['code'] == 0){$result = $data['data']['list'];$count = $data['data']['page_info']['total_number'];if (!empty($result)) {$records = [];foreach ($result as $key => $val){$records[] = ['advertiser_id' => $val['advertiser_id'],'date' => $val['date'],'non_grant_balance' => $val['non_grant_balance'],'frozen' => $val['frozen'],'company_wallet_cost' => $val['company_wallet_cost']];}try {Db::name('flow')->insertAll($records);} catch (\Exception $e) {Log::error('数据库插入失败:'.$e->getMessage());}}}} catch (RequestException $e) {// return json(['code'=>1,'msg'=>$e->getMessage()]);Log::error('错误信息:'.$e->getMessage());}sleep(2);}public function getFlow(){$result = Db::name('recharge')->distinct(true)->field('adv_id')->whereBetweenTime('operation_time','2025-02-01','2025-02-28')->select();foreach ($result as $val){$this->getFlowData((int) $val['adv_id']);}}
}
最后一步:在宝塔终端:输入命令:
cd /www/wwwroot/www.quweiie.cn
nohup php think hello quwei > runtime/hello.log 2>&1 &
php think hello quwei命令一定要在tp的根目录下运行;hello.log在runtime目录下查看;
部分 | 含义 |
---|---|
nohup | 防止任务因终端关闭而中断 |
php think hello quwei | 执行你的命令,传入参数 quwei |
> | 将标准输出写入 log 文件 |
2>&1 | 将错误输出也重定向到 log 文件中 |
& | 让命令在后台运行 |