温馨提示:本文翻译自stackoverflow.com,查看原文请点击:php - Laravel call method and pass value when got an exception
curl function laravel php conditional-statements

php - Laravel调用方法并在发生异常时传递值

发布于 2020-03-27 15:47:15

我有获取访问令牌的方法,这是

   public $token; //I declare global var to read in every func

    public function getToken(){
        $key = 'xxxxxxxxxxxxxx';
        $secret = 'xxxxxxxxxxxxxxxxxx';
        $data = array(
            'key' => 'xxxxxxxxxxxxxxxxxx',
            'secret' => 'xxxxxxxxxxxxxxx'
        );
        $payload = json_encode($data);
        $ch = curl_init('https://cgi.singmap.com/token?key='.$key.'&secret='.$secret.'');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/x-www-form-urlencoded',
            'Accept: application/json',
            'Content-Length: ' . strlen($payload))
        );

        // Submit the POST request
        $response = json_decode(curl_exec($ch), true);
        $trimmed = $response['datas'];
        $token = $trimmed['access_token'];
        curl_close($ch);
        $this->token = $token;
    }

该令牌仅可持续使用5分钟。但是在我这样使用令牌的其他方法中

 public function propertyUnitDetails(){

        $unitId = \DB::table('property_unit_list')
        ->select('projectId','unitId')
        ->get();

        foreach($unitId as $res){

        $this->getToken();
        $final_token = $this->token;

        // dd($final_token);

        $request_time = Carbon::now()->format('YmdHis');
        $sign = md5($final_token.$request_time);
        $pageNo = 1;
        $pageSize = 200;
        $url = 'https://cgi.singmap.com/unit/queryUnitDetail?request_time='.$request_time.
        '&token='.$final_token.'&sign='.$sign.'&projectId='.$res->projectId.'&unitId='.$res->unitId.'';

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $response = json_decode(curl_exec($ch), true);
        $trimmed = $response['datas'];

        if(empty($trimmed)){
            $this->getToken();
            $final_token = $this->token;
        }

        foreach ($trimmed as $data){
            $inserts[] = [
                'projectId' => $res->projectId,
                'stack' => $data['stack'],
                'floorPlanId' => $data['floorPlanId'],
                'soldBy' => $data['soldBy'],
                'transactionPrice' => $data['transactionPrice'],
                'type' => $data['type'],
                'unitId' => $data['unitId'],
                'floorPlanName' => $data['floorPlanName'],
                'price1' => $data['price1'],
                'price2' => $data['price2'],
                'price3' => $data['price3'],
                'price4' => $data['price4'],
                'custom1' => $data['custom1'],
                'custom2' => $data['custom2'],
                'custom3' => $data['custom3'],
                'custom4' => $data['custom4'],
                'direction' => $data['direction'],
                'area' => $data['area'],
                'buildName' => $data['buildName'],
                'unitName' => $data['unitName'],
                'buildId' => $data['buildId'],
                'bathrooms' => $data['bathrooms'],
                'transactionDate' => $data['transactionDate'],
                'bedrooms' => $data['bedrooms'],
                'purchaseStatus' => $data['purchaseStatus'],

                ];

            }
        }
        $chuncked = array_chunk($inserts, 10);
        foreach($chuncked as $inserts){
          \DB::table('property_project_details')->insert($inserts);
       }
      dd('record inserted'); 
    }

当该功能未完全执行或数据未完全插入时,可能是因为它具有大量数据。它引发datas找不到索引或curl响应中有错误的错误这是因为我只能datas基于手动获得或手动声明的令牌获得。我想要的是,如果令牌到期,它将运行该函数getToken()并将令牌传递给正在运行的函数,以避免中断它。

编辑:我添加了

 $this->getToken();
 $final_token = $this->token;

在我的foreach语句中,因为@ user001232说在unitId我得到的每个结果查询中,都会生成一个新令牌。但是我仍然每隔5分钟出现一个错误,这是因为即使我在其中添加该功能,我也无法获得新令牌。

查看更多

查看更多

提问者
Vince
被浏览
138
Jack 2020-02-03 11:31

在这里,这将起作用:

<?php 

class NameOfYourClass {
    public $token;

    public function refreshToken()
    {
        $key = 'xxxxxxxxxxxxxx';
        $secret = 'xxxxxxxxxxxxxxxxxx';
        $data = array(
            'key' => 'xxxxxxxxxxxxxxxxxx',
            'secret' => 'xxxxxxxxxxxxxxx'
        );
        $payload = json_encode($data);
        $ch = curl_init('https://cgi.singmap.com/token?key='.$key.'&secret='.$secret.'');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLINFO_HEADER_OUT, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/x-www-form-urlencoded',
                'Accept: application/json',
                'Content-Length: ' . strlen($payload))
        );

        $response = json_decode(curl_exec($ch), true);
        $trimmed = $response['datas'];
        $this->token = $trimmed['access_token'];
        curl_close($ch);
    }

    private function getUnitDetails($res, $attempts = 1)
    {
        // We only allow 5 attempts to avoid getting into infinite loops
        if ($attempts > 5) {
            throw new \Exception('Signmap API Issue');
        }

        $request_time = Carbon::now()->format('YmdHis');
        $sign = md5($this->token.$request_time);
        $pageNo = 1;
        $pageSize = 200;
        $url = 'https://cgi.singmap.com/unit/queryUnitDetail?request_time='.$request_time.
        '&token='.$this->token.'&sign='.$sign.'&projectId='.$res->projectId.'&unitId='.$res->unitId.'';

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $response = json_decode(curl_exec($ch), true);
        $trimmed = $response['datas'] ?? null;

        // If the response datas is empty, we're assuming it's because of a token error, so we retry
        if(empty($trimmed)){
            $attempts++;
            $this->refreshToken();
            return $this->getUnitDetails($res, $attempts);
        }

        return $trimmed;
    }

    public function propertyUnitDetails()
    {
        // Grab all of the units
        $unitItds = \DB::table('property_unit_list')->select('projectId','unitId')->get();

        foreach($unitId as $res) {
            $trimmed = $this->getUnitDetails($res);

            foreach ($trimmed as $data){
                $inserts[] = [
                    'projectId' => $res->projectId,
                    'stack' => $data['stack'],
                    'floorPlanId' => $data['floorPlanId'],
                    'soldBy' => $data['soldBy'],
                    'transactionPrice' => $data['transactionPrice'],
                    'type' => $data['type'],
                    'unitId' => $data['unitId'],
                    'floorPlanName' => $data['floorPlanName'],
                    'price1' => $data['price1'],
                    'price2' => $data['price2'],
                    'price3' => $data['price3'],
                    'price4' => $data['price4'],
                    'custom1' => $data['custom1'],
                    'custom2' => $data['custom2'],
                    'custom3' => $data['custom3'],
                    'custom4' => $data['custom4'],
                    'direction' => $data['direction'],
                    'area' => $data['area'],
                    'buildName' => $data['buildName'],
                    'unitName' => $data['unitName'],
                    'buildId' => $data['buildId'],
                    'bathrooms' => $data['bathrooms'],
                    'transactionDate' => $data['transactionDate'],
                    'bedrooms' => $data['bedrooms'],
                    'purchaseStatus' => $data['purchaseStatus'],
                ];
            }
        }
        $chuncked = array_chunk($inserts, 10);
        foreach($chuncked as $inserts){
            \DB::table('property_project_details')->insert($inserts);
        }
        dd('record inserted'); 
    }
}