Warm tip: This article is reproduced from stackoverflow.com, please click
curl function laravel php conditional-statements

Laravel call method and pass value when got an exception

发布于 2020-03-27 15:40:17

I got method in getting the access token and here it is

   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;
    }

The token only lasts for 5 minutes to use. But in my other method like this which uses token

 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'); 
    }

When the function is not completely excecuted or the data is not fully inserted, maybe because it has a large amount of data. It throws an error of datas index is not found or something from the curl response. It is because I can only get the datas based on the token i get manually or declared manually. What I want is that if the token expires, it will run the function getToken() and pass the token to the running function in order to avoid interrupting it.

EDIT: I added

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

in my foreach statement because @user001232 said that in every unitId result query I got, a new token would be generated. But I still got an error every 5 mins that is because i cant get a new token even if i add that function in there.

Questioner
Vince
Viewed
87
Jack 2020-02-03 11:31

Here you go, this will work:

<?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'); 
    }
}