Laravel вызов метода и передачи значения при получении исключения - PullRequest
0 голосов
/ 31 января 2020

У меня есть метод получения токена доступа, и вот он

   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 минут, потому что я не могу получить новый токен, даже если я добавлю эту функцию туда.

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

Вот вам go, это будет работать:

<?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'); 
    }
}
0 голосов
/ 31 января 2020

Что если вы вызываете метод getToken() каждый раз, когда в вашем l oop появляется projectId. Это так

foreach($project_id as $res){
        $this->getToken();
        $final_token = $this->token;

        $request_time = Carbon::now()->format('YmdHis');
        $sign = md5($final_token.$request_time);

//and so on ....

Таким образом. он будет получать новый токен в каждом projectId. Единственный недостаток - он будет выполняться очень медленно.

И если ошибка все равно будет получена, замените ваш код следующим образом. Добавить условие, если пусто

public function propertyBuildings(){

        $project_id = \DB::table('project_list')
                        ->select('projectId')
                        ->get();

        foreach($project_id as $res){

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

            $request_time = Carbon::now()->format('YmdHis');
            $sign = md5($final_token.$request_time);
            $url = 'https://cgi.singmap.com/project/queryBuilding?request_time='.$request_time.
            '&token='.$token.'&sign='.$sign.'&projectId='.$res->projectId.'';
            $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;
           }

            // return $trimmed;
                foreach($trimmed as $data){
                    $inserts[] = [
                    'projectId' => $res->projectId,
                    'buildId' => $data['buildId'],
                    'buildName' => $data['buildName'],
                    ];
            }

         }
         \DB::table('property_building')->insert($inserts);
         dd('Data Inserted');

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...