Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vincentsanity's avatar

Laravel PDOStatement::execute(): MySQL server has gone away error when inserting data using curl request

I got a 3rd party api and I want to save data when I hit a request. It has a small data but there is one column that has lots of text in it. So I set the column of that object in the database to text. The problem is when I hit the api it got me this error of PDOStatement::execute(): MySQL server has gone away everytime i insert

Here is my code

public function propertySitePlans(){
        ini_set('max_execution_time', 600);
        ini_set('max_allowed_packet',500);
        ini_set('mysql.connect_timeout', 300);
        ini_set('default_socket_timeout', 300); 
        ini_set('mysqli.reconnect',true);
        ini_set('wait_timeout',36000);


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

        foreach($project_id as $res){
            $request_time = Carbon::now()->format('YmdHis');
            $token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; 
            $sign = md5($token.$request_time);
            $url = 'https://cgi.singmap.com/project/querySitePlans?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'];

            // dd($trimmed);

            foreach ($trimmed as $data){
                $inserts[] = [
                    'projectId' => $res->projectId,
                    'buildingId' => $data['buildingId'],
                    'showInterest' => $data['showInterest'],
                    'showIndex' => $data['showIndex'],
                    'sitePlanName' => $data['sitePlanName'],
                    'img' => $data['img'],
                    'showInMobile' => $data['showInMobile'],
                    'sitePlanId' => $data['sitePlanId'],
                    'type' => $data['type'],
                    'content' => $data['content'],

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

Im using mysql

Ver 15.1 Distrib 10.3.16-MariaDB, for Win64 (AMD64), source revision 0789a1a18f0e780c0412667e7b6e0a9970aa6905

0 likes
12 replies
prasadchinwal5's avatar

@vincentsanity Can you dump what $trimmed contains?

Or also try moving the DB::insert statement inside this loop

foreach ($trimmed as $data){
    $inserts[] = ...
    
\DB::table('property_site_plan')->insert($inserts);

}

vincentsanity's avatar

Here is the sample for sir @prasadchinwal5 . This is only for one record or project_id

array:6 [▼
  0 => array:9 [▼
    "showInterest" => "YES"
    "showIndex" => 2
    "sitePlanName" => "Elevation Chart"
    "img" => "https://img.singmap.com/upload/broke/2029c11d79004b5e915809fbd6e19f7b/0275d26811574de68834663514ee2878/siteplanImg/595a95e7f5e146abad580e6324ec90dd.jpg"
    "showInMobile" => "YES"
    "sitePlanId" => "26895ac8f1f042ed84595190bf249a2d"
    "type" => "allbuilding"
    "content" => "[{"width":"54","height":"23","left":"125","top":"148","name":"Rect0","fill":"rgba(220,20,60,0.4)","type":"rect","buildingID":"e3e778a61f544fcf953c11d09cb8fa47", ▶"
    "buildingId" => "9930b9c9d5124a87ab026c679de427ce"
  ]
  1 => array:9 [▶]
  2 => array:9 [▶]
  3 => array:9 [▶]
  4 => array:9 [▶]
  5 => array:9 [▶]
]
vincentsanity's avatar

I also tried chunking the data like this

   foreach ($trimmed as $data){
                $inserts[] = [
                    'projectId' => $res->projectId,
                    'buildingId' => $data['buildingId'],
                    'showInterest' => $data['showInterest'],
                    'showIndex' => $data['showIndex'],
                    'sitePlanName' => $data['sitePlanName'],
                    'img' => $data['img'],
                    'showInMobile' => $data['showInMobile'],
                    'sitePlanId' => $data['sitePlanId'],
                    'type' => $data['type'],
                    'content' => $data['content'],

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

Still not working. Same error will display

uksarkar's avatar
uksarkar
Best Answer
Level 2

@vincentsanity make sure that you have the right database configuration in .env file. If you sure that you have a proper connection but the problem is happening for another reason. Then try to raising max_allowed_packet in my.cnf (under [mysqld]) to 8 or 16M usually fixes it.

[mysqld]
max_allowed_packet=16M

NOTE: This can be set on your server as it's running. You need to restart the MySQL service once you are done.

After all of this if the error still happening or if you don't able to edit my.cnf then give a try this one.

foreach ($trimmed as $data){
                $inserts = [
                    'projectId' => $res->projectId,
                    'buildingId' => $data['buildingId'],
                    'showInterest' => $data['showInterest'],
                    'showIndex' => $data['showIndex'],
                    'sitePlanName' => $data['sitePlanName'],
                    'img' => $data['img'],
                    'showInMobile' => $data['showInMobile'],
                    'sitePlanId' => $data['sitePlanId'],
                    'type' => $data['type'],
                    'content' => $data['content'],

                    ];

        \DB::table('property_site_plan')->insert($inserts);
            }
        }
vincentsanity's avatar

@uksarkar it seems fine when i do edit the my.ini file. But I declared before my function here ini_set('max_allowed_packet',500); Also, i dont understand why i got to put my insert statement after the loop? Can you explain to me why it is put after the loop? I tried doing it the values is almost 30k but if i put the insert statement outside the second loop I only got 1k data. Which is the correct one?

uksarkar's avatar

@vincentsanity , According to your error, it's happening because of your mySql server couldn't handle of the amount of data that you are passing. If you edit the my.ini and increase themax_allowed_packet to 16M then it should fix the problem. But after increasing it if the error still happening then you have a very large amount of data so the server need a lot of thread to process this, then you should insert your data by chunking your data to small parts. In case If you put the insert statement inside the loop then the data will insert one by one, so that your server can handle this. If you think about performance then you should find out a better way to chunk your data to maximum capacity of your server.

Note: first you should increase the max_allowed_packet and check with your previous code, if it's not fixed then try to put the insert statement inside the loop like my code.

1 like
vincentsanity's avatar

yah its fine now @uksarkar . but i am getting a different number of data when i put my insert inside and outside the loop. im confused which is the correct code now

uksarkar's avatar

@vincentsanity , Defiantly putting insert statement inside the loop will give you the right data. But if you want to put the statement outside from the loop then first declare the $inserts variable to an empty array right before the foreach loop. A quick overview like this:

// Declaring empty array first
$inserts = [];

// The foreach loop to decorate data to currect formate
foreach ($trimmed as $data){
                $inserts[] = [
                    'projectId' => $res->projectId,
                    'buildingId' => $data['buildingId'],
                    'showInterest' => $data['showInterest'],
                    'showIndex' => $data['showIndex'],
                    'sitePlanName' => $data['sitePlanName'],
                    'img' => $data['img'],
                    'showInMobile' => $data['showInMobile'],
                    'sitePlanId' => $data['sitePlanId'],
                    'type' => $data['type'],
                    'content' => $data['content'],

                    ];
            }

// Now insert all data into the database with one statement (If the data is not overlap the server limit)
 \DB::table('property_site_plan')->insert($inserts);
1 like
vincentsanity's avatar

is it the same as this ? $inserts[] = [ @uksarkar . and i think if i put the insert statement after the loop i get duplicate data

uksarkar's avatar

@vincentsanity $inserts = [...] is defining a variable with an array. But $inserts[]=[...] pushing an array to an array. It may cause some problem if you have duplicate data (what you are facing now). Finally, please take your time to learn programming first (don't mind please).

optic4predator1's avatar

Hello @vincentsanity i had the same issue but i will ask you to check if the user of your database had all priveleges to create, update and delete. so for exmple in my case i went to phpmyadmin i was searching fro the user which i use in my .env file for example login :root passwod : root so the user in my case is root i went to phpmyadmin to the home then in the user acount server privileges make sure the user had the same config root localhost YES ALL PRIVILEGES YES

Please or to participate in this conversation.