From PHP to MySQL bind_param() bool error - php

I cannot fint the error nor could find ideas from the internet.
The database has key, userIP, and date.
the code segment is:
$last = $conn->query("SELECT LAST_INSERT_ID();");
if (strcmp($last, "<empty string>") == 0) {
$index = 0;
} else {
$index = $last + 1;
}
$stmt = $conn->prepare("INSERT INTO Users (key, userIP, date) VALUES (?, ?, ?)");
$stmt->bind_param("iss", $key, $ip, $date);
$key = $index;
$ip = $_SERVER['REMOTE_ADDR'];
$date = date('Y-m-d H:i:s');
The idea is that I save the last "key" and add 1 to it. Tho it doesn't seems to work if the db is empty. I was looking over it for hours so I have ran out on ideas.

You need to fetch the results of the query.
$result = $conn->query("SELECT LAST_INSERT_ID();");
$row = $result->fetch_row();
$last = $row[0];
if ($last == "") {
$index = 0;
} else {
$index = $last + 1;
}
But you don't need to perform a query for this, there's a built-in function for it:
$last = $conn->insert_id;
Another problem is that key is a reserved word, so you need to quote it with backticks.
$stmt = $conn->prepare("INSERT INTO Users (`key`, userIP, date) VALUES (?, ?, ?)");

Related

PHP Insert into PostgreSQL

So it's probably a really stupid/basic question, but i have this simple PHP function (which works) and inserts data into a PostgreSQL DB.
My issue is when it encounters specific data;
function insertData($pg, $csvfile)
{
$x = 0;
foreach ($csvfile as $data)
{
$email = $csvfile[$x]['email'];
$name = $csvfile[$x]['name'];
$surname = $csvfile[$x]['surname'];
$query = "INSERT INTO users (email, name, surname) VALUES ('$email', '$name', '$surname')";
$result = pg_query($pg, $query);
$x++;
}
}
And while this works, it falls over with a surname such as:
O'hare
And obviously this occurs because then the PHP code comes out as:
...VALUES ('john#example.com', 'John', 'O'hare')";
but im not sure of how i should be structuring the PHP to allow for this.
Try this:
function insertData($pg, $csvfile) {
$nbr = count(file($csvfile));
for($i=0; $i<$nbr; $i++) {
$email = pg_escape_string( $csvfile[$i]['email'] );
$name = pg_escape_string( $csvfile[$i]['name'] );
$surname = pg_escape_string( $csvfile[$i]['surname'] );
$query = "INSERT INTO users (email, name, surname) VALUES ('$email', '$name', '$surname')";
$result = pg_query($pg, $query);
if (!$result) {
echo "Error while executing the query: " . $query;
exit;
}
}
}
You need to escape the string parameters. And it is much better if you can use PDO extension, because prepared statements can take care of escaping for you and also helps with preventing SQL injection and some other security concerns.
function insertData(PDO $dbh, $csvfile) {
$x = 0;
foreach ($csvfile as $data)
{
$query = "INSERT INTO users (email, name, surname) VALUES (?, ?, ?)";
$params = [
$csvfile[$x]['email'],
$csvfile[$x]['name'],
$csvfile[$x]['surname']
];
$statement = $pdo->prepare($query);
$statement->execute();
$x++;
}
}
PDO::prepare
PDOStatement::execute
Solution using prepared query
function insertData($dbname, $tbname, $csvfile)
{
$result = [];
// Connect to a database named "mary"
$dbconn = pg_connect("dbname=$dbname");
// Prepare a query for execution
$result = pg_prepare($dbconn, "my_query", 'INSERT INTO $1 (email, name, surname) VALUES ($2, $3, $4)');
// Execute the prepared query. Note that it is not necessary to escape
foreach ($csvfile as $data)
{
$email = $data['email'];
$name = $data['name'];
$surname = $data['surname'];
$query = "";
$result[] = pg_execute($dbconn, "my_query", array($tbname, $email, $name, $surname));
}
if (in_array(false, $result) )
return false;
else
return true;
}
$dbname = "your dbname";
$tbname = "name of table";
$csvFile = [];
if (insertData($dbname, $tbname, $csvFile))
echo "Data inserted";
else
echo "Data not inserted";
So i took note of the suggestions from #Karsten Koop and #TOH19, and came up with this code which is working;
function insertData($pg, $csvfile)
{
$x = 0;
foreach ($csvfile as $data)
{
$email = pg_escape_string($csvfile[$x]['email']);
$name = pg_escape_string($csvfile[$x]['name']);
$surname = pg_escape_string($csvfile[$x]['surname']);
$query = "INSERT INTO users (email, name, surname) VALUES ('".$email."', '".$name."', '".$surname."')";
$result = pg_query($pg, $query);
$x++;
}
}

files included creates Call to a member function fetch_assoc() on a non-object

Trying to integrate a new script with my existing homepage I am required to include 2 new php files in my index.php. I love playing with web development but sadly my coding knowlage is very limited. (CMS and GUI make human stupid)
if ($page == 'Premium') {
include('affiliates/controller/affiliate-tracking.php');
if (isset($_GET['payment']) && $_GET['payment'] == 'created') {
$sale_amount = '5.00';
$product = 'Premium';
include('affiliates/controller/record-sale.php');
}
}
If I do this I get the fatal error: Call to a member function fetch_assoc() on a non-object in affiliates/controller/record-sale.php on line 61.
Code in line 61 is this:
$stmt->execute();
Can someone Point me in the right direction here? I am not really sure what the error means. There don't seem to be any database errors and all the other functions work the way they are supposed to.
Thanks to any samaritan who answers.
Using mysqli
complete code for record-sale.php is this:
application/x-httpd-php record-sale.php ( PHP script text )
<?php
$path = dirname(__FILE__);
$path = substr($path, 0, -10);
include($path.'/auth/db-connect.php');
$ap_tracking = 'ap_ref_tracking';
$datetime = date("Y-m-d H:i:s");
//IF AFFILIATE ID IS PRESENT
if(isset($_COOKIE[$ap_tracking])){
session_start();
//GET COMMISSION LEVEL
$get_dc = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT default_commission FROM ap_settings WHERE id=1"));
$default_commission = $get_dc['default_commission'];
//IS SALE VOLUME COMMISSIONS ON
$get_sv = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT sv_on FROM ap_other_commissions WHERE id=1"));
$sv_on = $get_sv['sv_on'];
if($sv_on=='1'){
$get_cl = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT percentage FROM ap_commission_settings WHERE $sale_amount BETWEEN sales_from AND sales_to"));
$comission = $get_cl['percentage'];
}
//COMMISSION OVERRIDE
$comission = $commission;
//SET DEFAULT COMMISSION IF NO OTHER VALUE HAS BEEN SET
if($comission==''){$comission = $default_commission;}
//RECURRING COMMISSIONS
if(isset($recurring)){
$recurring_period = strtolower($recurring);
$recurring_amount = $recurring_fee;
if($recurring_period==''){$recurring_period='monthly';}
if($recurring_fee==''){$recurring_fee = $default_commission;}
}else{
$recurring_period = 'Non-recurring';
$recurring_fee = '0';
}
//RECORD SALE
$affiliate_id = $_COOKIE[$ap_tracking];
$percentage = $comission / 100;
$net_earnings = $sale_amount * $percentage;
$datetime = date("Y-m-d H:i:s");
//CHECK FOR VALID AFFILIATE
$get_affiliate = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT balance FROM ap_members WHERE id=$affiliate_id"));
$affiliate_balance = $get_affiliate['balance'];
if(isset($affiliate_balance)){
//PREVENT DUPLICATE SALES
if($_SESSION['ap_sale_hit']=='1' && $affiliate_id == $_SESSION['saved_affiliate'] && $net_earnings == $_SESSION['saved_net']){}else{
$stmt = $mysqli->prepare("INSERT INTO ap_earnings (affiliate_id, product, comission, sale_amount, net_earnings, recurring, recurring_fee, datetime) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param('ssssssss', $affiliate_id, $product, $comission, $sale_amount, $net_earnings, $recurring_period, $recurring_fee, $datetime);
$stmt->execute();
$transaction_id = $stmt->insert_id;
$stmt->close();
//UPDATE AFFILIATE BALANCE
$updated_balance = $affiliate_balance + $net_earnings;
$update_one = $mysqli->prepare("UPDATE ap_members SET balance = ? WHERE id=$affiliate_id");
$update_one->bind_param('s', $updated_balance);
$update_one->execute();
$update_one->close();
}
}
//MULT-TIER COMMISSIONS
$get_mt = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT mt_on FROM ap_other_commissions WHERE id=1"));
$mt_on = $get_mt['mt_on'];
if($mt_on=='1'){
$levels = 10;
//FOR EACH LEVEL RUN
$get_sponsor = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT sponsor FROM ap_members WHERE id=$affiliate_id"));
$sponsor = $get_sponsor['sponsor'];
for ($loop = 2 ; $loop < $levels; $loop++){
//CHECK FOR AVAILABLE SPONSOR
if($sponsor!='0'){
//GET LEVEL PERCENTAGE
$gp = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM ap_other_commissions WHERE id=1"));
$p = $gp['tier'.$loop.''];
$sc = $p / 100;
$se = $sale_amount * $sc;
//GET SPONSOR BALANCE
$gb = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT balance FROM ap_members WHERE id=$sponsor"));
$ob = $gb['balance'];
$nb = $ob + $se;
$update_one = $mysqli->prepare("UPDATE ap_members SET balance = ? WHERE id=$sponsor");
$update_one->bind_param('s', $nb);
$update_one->execute();
$update_one->close();
//INSERT TRANSACTION HISTORY
$stmt = $mysqli->prepare("INSERT INTO ap_multi_tier_transactions (affiliate_id, transaction_id, tier, commission, mt_earnings, datetime) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param('ssssss', $sponsor, $transaction_id, $loop, $p, $se, $datetime);
$stmt->execute();
$stmt->close();
}else{
break 1;
}
//GET NEXT SPONSOR FOR NEXT LOOP
$gs = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT sponsor FROM ap_members WHERE id=$sponsor"));
$sponsor = $gs['sponsor'];
}
}
$_SESSION['ap_sale_hit'] = '1';
$_SESSION['saved_affiliate'] = $affiliate_id;
$_SESSION['saved_net'] = $net_earnings;
}
if(isset($_POST['reset'])){
unset($_SESSION['ap_sale_hit']);
unset($_SESSION['saved_affiliate']);
unset($_SESSION['saved_net']);
//header("Refresh:0");
}
?>

PHP MySqli Inserting

I have this script:
<?php
ini_set('max_execution_time', 0);
ini_set('display_errors','1');
ini_set('default_charset','utf-8');
include("includes/mysqli.php");
$con->set_charset("utf8");
$sql = "INSERT INTO clans(id, clanid, name, badge, status, playercount, score, requiredtrophies, warswon, warslost, warstied, location,warfrequency, exp, level, description, playerjson, lastupdate)
VALUES ('', ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?, ?, ?, ?, now())";
$stmt = $con->prepare($sql); //prepare update statement
$stmt->bind_param('ssisiiiiiissiiss',$clanid,$name,$badge,$status,$playercount,$score,$requiredtrophies,$warswon,$warslost,$warstied,$location,$warfrequency,$exp,$level,$description,$playerarray);
$stmts = $con->prepare("SELECT * FROM activeclans WHERE id > 137439657919 ORDER BY id ASC"); //Prepare select statement
$stmts->execute(); //execute select statement
$result = $stmts->get_result(); //get select statement results
while ($row = $result->fetch_assoc()) {
$clanid = $row['id'];
$clanurl = "http://185.112.249.77:9999/Api/clan?clan=$clanid";
$jsondata = file_get_contents($clanurl);
$data = json_decode($jsondata,true);
if($data['name'] != null){
$name = $data['name'];
}else{
$name = "";
}
$badge = $data['badge'];
if($data['status'] != null){
$status = $data['status'];
}else{
$status = "";
}
$playercount = $data['playerCount'];
$score = $data['score'];
$requiredtrophies = $data['requiredTrophies'];
$warswon = $data['warsWon'];
$warslost = $data['warsLost'];
$warstied = $data['warsTied'];
if($data['clanLocation'] != null){
$location = $data['clanLocation'];
}else{
$location = "";
}
if($data['warFrequency'] != null){
$warfrequency = $data['warFrequency'];
}else{
$warfrequency = "";
}
$exp = $data['exp'];
$level = $data['level'];
$description = $data['description'];
$playerarray = json_encode($data['players']);
/* Execute update statement */
$stmt->execute();
}
echo $stmt->affected_rows;
$stmt->close();
$stmts->close();
$con->close();
?>
And it is basically inserting around 157K (157 THOUSAND) rows of data. And the data is quite big as well! You can't check the file_get_contents URL out because the port is open only to localhost.
What is the quickest way to insert all this data? It has been running for almost 24 hours now and done 65K. I did try and use transactions but that didn't work well. It gave my 502 Bad Gateway and therefore I lost a lot of time on the script because it rolled back after adding 3 thousand rows (which was however quite quick!)
Also it is possible that the script may at some point fail and leave some of the varchar fields as null hence I have made it so that they end up as an empty string so that there aren't any mySql errors (I got those exceptions thrown when using transactions)
This is the code I used with the transaction stuff. I'm pretty new to prepared statements. I converted this code from standard queries to prepared today and then tried transactions.
<?php
ini_set('max_execution_time', 0);
ini_set('display_errors','1');
ini_set('default_charset','utf-8');
include("includes/mysqli.php");
$con->set_charset("utf8");
$sql = "INSERT INTO clans(id, clanid, name, badge, status, playercount, score, requiredtrophies, warswon, warslost, warstied, location,warfrequency, exp, level, description, playerjson, lastupdate)
VALUES ('', ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?, ?, ?, ?, now())";
$stmt = $con->prepare($sql); //prepare update statement
$stmt->bind_param('ssisiiiiiissiiss',$clanid,$name,$badge,$status,$playercount,$score,$requiredtrophies,$warswon,$warslost,$warstied,$location,$warfrequency,$exp,$level,$description,$playerarray);
$stmts = $con->prepare("SELECT * FROM activeclans WHERE id > 137439657919 ORDER BY id ASC"); //Prepare select statement
$stmts->execute(); //execute select statement
$result = $stmts->get_result(); //get select statement results
try{
$con->autocommit(FALSE);
while ($row = $result->fetch_assoc()) {
$clanid = $row['id'];
$clanurl = "http://185.112.249.77:9999/Api/clan?clan=$clanid";
$jsondata = file_get_contents($clanurl);
$data = json_decode($jsondata,true);
if($data['name'] != null){
$name = $data['name'];
}else{
$name = "";
}
$badge = $data['badge'];
if($data['status'] != null){
$status = $data['status'];
}else{
$status = "";
}
$playercount = $data['playerCount'];
$score = $data['score'];
$requiredtrophies = $data['requiredTrophies'];
$warswon = $data['warsWon'];
$warslost = $data['warsLost'];
$warstied = $data['warsTied'];
if($data['clanLocation'] != null){
$location = $data['clanLocation'];
}else{
$location = "";
}
if($data['warFrequency'] != null){
$warfrequency = $data['warFrequency'];
}else{
$warfrequency = "";
}
$exp = $data['exp'];
$level = $data['level'];
$description = $data['description'];
$playerarray = json_encode($data['players']);
/* Execute update statement */
if(!$stmt->execute()){
throw new Exception("Cannot insert record. Reason :".$stmt->error);
}
}
$con->commit();
}catch (Exception $e) {
echo 'Transaction failed: ' . $e->getMessage();
$con->rollback();
}
echo $stmt->affected_rows;
$stmt->close();
$stmts->close();
$con->close();
?>
Thanks :)
$sql="
INSERT INTO
ue_game_alliance_rank_rights
(
rank
, `right`
)
VALUES
";
$insertQuery = array();
$insertData = array();
foreach ($rights_status['add'] AS $row ) {
$insertQuery[] = '(?,?)';
$insertData[] = $rank;
$insertData[] = $row['id'];
}
if (!empty($insertQuery)) {
$sql .= implode(', ', $insertQuery);
$stmt = $this->db->prepare($sql);
$stmt->execute($insertData);
}
}
That's an example of the basic technique, you would need to swap the functions for their equivalent mysqli_* functions. For each field having data inserted into it, you need:
$insertData[] = $row['id'];
$row needs to match whatever you've used in your foreach loop and ['id'] needs to be whatever the name of the field is that you're inserting into.
$insertQuery[] = '(?,?)';
You need as many placeholders as fields that you'll be inserting into.
Overall it creates a bulk insert, so you need to have the data to be inserted in an array. Given the amount of data that you're inserting, use transactions, you'll probably need to experiment to see how many rows you can bulk insert at a time before the server complains

Multiple MySQL rows with one form

I have a form that I would like to create up to 9 different MySQL rows with one process. The code I have as of right now doesn't throw any errors, but also does not insert any information into the database.
$id = '';
$rid = $_POST['rid'];
$desc = $_POST['desc'];
$ename = $_POST['ename'];
if ($stmt = $mysqli->prepare("INSERT INTO event(id, rid, desc, ename) VALUES (?, ?, ?, ?)")) {
$stmt->bind_param("isss", $id, $rid, $desc, $ename);
for ($i = 1; $i < 10; $i++) {
$rid = $_POST['rid' . $i];
$desc = $_POST['desc' . $i];
$ename = $_POST['ename' . $i];
$stmt->execute();
}
include ("./html/schedule2.htm");
} else {
printf("Errormessage: %s\n", $mysqli->error);
}
I have edited the code to follow the comment instructions but still get an error that is very vague. Not sure what is going on...
The comments have pointed out that you should prepare/execute this. This is what it should look like.
$id = '';
$rid = $_POST['rid1'];
$desc = $_POST['desc1'];
$ename = $_POST['ename1'];
$stmt = $mysqli->prepare("INSERT INTO `event`(`id`, `rid`, `desc`, `ename`) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $id, $rid, $desc, $ename);
$stmt->execute();
for ($i = 2; $i < 10; $i++) {
$rid = $_POST['rid' . $i];
$desc = $_POST['desc' . $i];
$ename = $_POST['ename' . $i];
$stmt->execute();
}
Also, I'd recommend using an array for your form elements. Like:
<input type="text" name="desc[]">

Inserting values of array into MYSQL

I have a text file, who's value i have put into arrays,
this is the php code:
<?php
$homepage = file_get_contents('hourlydump.txt');
$x = explode('|', $homepage);
$desc = array();
$cat = array();
$link = array();
$m = 1;
$n = 2;
$p = 3;
for ($i = 1; $i <= count($x) / 4; $i++) {
$m = $m + 4;
$desc[] = $x[$m];
$n = $n + 4;
$cat[] = $x[$n];
$p = $p + 4;
if ($x[$p])
$link[] = $x[$p];
}
echo "<pre>";
print_r($desc);
print_r($cat);
print_r($link);
?>
output is like:
Array
(
[0] => Kamal Heer - Facebook Official Video 720p Dual Audio [Hindi + Punjabi]76 mb by rANA.mkv
[1] => 50 HD Game Wallpapers Pack- 1
)
Array
(
[0] => Movies
[1] => Other
)
Array
(
[0] => http://kickass.to/kamal-heer-facebook-official-video-720p-dual-audio-hindi-punjabi-76-mb-by-rana-mkv-t7613070.html
[1] => http://kickass.to/50-hd-game-wallpapers-pack-1-t7613071.html
)
//
//
//
anyone please help me i dont know how to insert the values of these three arrays $desc, $cat and $link
into mysql table, columns named description, category, link
i know simple insert queries but dont how to deal with these arrays.
I will give you an example of how basic database connection is made and the insert is completed, this is for illustrative purpose only. You should reorganize this code inside a class so that every insert statement doesn't create a PDO object but re-use the object created before.
function insertItem($desc, $cat, $link) {
$dbh = new PDO("mysql:host=host;dbname=db", $user, $pass);
$sql = "INSERT INTO table (description, category, link) VALUES (:desc, :cat, :link)";
$sth = $dbh->prepare($sql);
$sth->bindValue(":desc", $desc);
$sth->bindValue(":cat", $cat);
$sth->bindValue(":link", $link);
$sth->execute();
}
You can use a for statement.
for($x =0, $num = count($desc); $x < $num; $x++){
// build you query
$sql = "INSERT into your_table (description, category, link) values ".
"(".$db->quote($desc[$x]).",".$db->quote($cat[$x]).",".
$db->quote($link[$x].")";
$db->query($sql);
}
Of course you will have to use the sanitation/quoting methods appropriate for your chosen database api.
Here is a simple sample to read your file as is from the website you retrieve it as well as inserting it to the database sanitizing the data:
<?php
// fill with your data
$db_host = 'localhost';
$db_user = '';
$db_pass = '';
$db_name = '';
$db_table = 'myTable';
$file = "hourlydump.txt.gz";
if($filehandle = gzopen($file, "r"))
{
$content = gzread($filehandle, filesize($file));
gzclose($file);
}
else
die('Could not read the file: ' . $file);
$con = mysqli_connect($db_host,$db_user,$db_pass,$db_name);
if($con->connect_error)
die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error());
$sql = "INSERT INTO $db_table (description, category, link) VALUES (?, ?, ?)";
if (!$insert = $con->prepare($sql))
die('Query failed: (' . $con->errno . ') ' . $con->error);
foreach (explode("\n", $content) as $line)
{
list($md5hash,$desc,$cat,$link,$torrent) = explode("|", $line);
if (!$insert->bind_param('sss',$desc,$cat,$link))
echo 'Binding parameters failed: (', $insert->errno, ') ', $insert->error;
if (!$insert->execute())
echo 'Insert Error ', $insert->error;
}
$insert->close();
$con->close();
NOTE: you may want to check if the file was loaded with success, if the fields from the explode exist or not to prevent further problems but in general this should work just fine.
Also you may want to change the $sql to reflect your MySQL table aswell as the $db_table at the top.
UPDATE: to insert all values change this:
$sql = "INSERT INTO $db_table (description, category, link) VALUES (?, ?, ?)";
To:
$sql = "INSERT INTO $db_table (md5, description, category, link, torrent) VALUES (?, ?, ?, ? ,?)";
And this:
if (!$insert->bind_param('sss',$desc,$cat,$link))
To:
if (!$insert->bind_param('sssss',$md5hash,$desc,$cat,$link,$torrent))
Note above the s for each item you need a s you have 5 items so 5 s's the S means string, D double, I integer, B blob you can read more at about it here.
Also note the $sql for each item we will use on the bind_param we have a ?.
Try this. I am assuming that only these much of values are there for insertion
for($i = 0;$i<2;$++) {
mysqli_query("INSER INTO tablename values(description,category,link) VALUES('$desc[$i]'
,'$cat[$i]','$link[$i]')");
}
You can build your query while you're doing you calculations:
$query = "INSERT INTO `table` (`description`, `category`, `link`) VALUES ";
for ($i = 1; $i <= count($x) / 4; $i++) {
$m = $m + 4;
$query .= "('".$x[$m];
$n = $n + 4;
$query .= "','".$x[$n];
$p = $p + 4;
if ($x[$p]) $query .= "','".$x[$p]."'),";
else $query .= "',NULL),";
}
$query = substr($query, 0, -1);//get rid of last comma
mysqli_query($query);
You can also build the arrays along with the query if you need to:
$query = "INSERT INTO `table` (`description`, `category`, `link`) VALUES ";
for ($i = 1; $i <= count($x) / 4; $i++) {
$m = $m + 4;
$desc[] = $x[$m];
$query .= "('".$x[$m];
$n = $n + 4;
$cat[] = $x[$n];
$query .= "','".$x[$n];
$p = $p + 4;
if ($x[$p]){
$link[] = $x[$n];
$query .= "','".$x[$p]."'),";
} else {
$link[] = $x[$n];
else $query .= "',NULL),";
}
$query = substr($query, 0, -1);//get rid of last comma
mysqli_query($query);
make the array to a string
$description = json_encode($desc);
$category = json_encode($cat);
$link = json_encode($link);
then insert these values to database
At the time of fetching
Use json_decode to get the array again from the string

Categories