concatenate string in php foreach - php

I should be able to figure this out, but I keep going in circles. I have a form with checkboxes. When the checkboxes are selected they tagged to be deleted.
I process those selected checkboxes with a foreach:
foreach (array_keys($_POST['checkboxselect']) as $k) {
$str .= $k.',';
}
This is my lame attempt to put the list of videos together. The sql delete I'm using is:
DELETE FROM `videos` WHERE `video_name` IN ($str)
So I'm missing lots of things here. The $str needs to have:
Only one checkbox is returned so return string with quotes (i.e. "myvideo.mp4")
Multiple checkboxes are selected so build a string with quotes and commas (i.e. "myvideo.mp4","myvideo2.mp4","myvideo3.mp4")
Thanks for the help.

Try using PHP's implode:
// Init links
$mysqliLink = mysqli_connect('host', 'user', 'password') or die('Could not connect: ' . mysqli_error());
$mysqlLink = mysql_connect('host', 'user', 'password') or die('Could not connect: ' . mysql_error());
//-----
// Prep values for query
//-----
// Only pick one of the following depending upon the mysql library you are using
// If using mysql, passing the 2nd argument is not necessary, but for
// clarity, adding it
$deleteNames = array_map('mysql_real_escape_string', array_keys($_POST['checkboxselect']), array_fill(0, count($_POST['checkboxselect']), $mysqlLink));
// If using mysqli
// This will ensure that $mysqliLink will be passed in as first arg for
// every iteration satisfying the function signature
$deleteNames = array_map('mysqli_real_escape_string', array_fill(0, count($_POST['checkboxselect']), $mysqliLink), array_keys($_POST['checkboxselect']));
//-----
// Because you are passing strings, we need to ensure each is wrapped in quotes
$deleteNames = "'" . implode("','", $deleteNames) . "'";
// Construct query using implode
$sql = sprintf('DELETE FROM `videos` WHERE `video_name` IN (%s)', $deleteNames);
-- Update --
Using Joomla APIs:
$db = &JFactory::getDBO();
// Localize and sanitize each individual value
foreach (array_keys($_POST['checkboxselect']) as $element) {
$deleteNames[] = $db->quote($element);
}
// Because you are passing strings, we need to ensure each is wrapped in quotes
// No longer true because $db->quote taking care of quoting out each name for us
$deleteNames = implode(',', $deleteNames);
// Construct query using implode
$sql = sprintf('DELETE FROM `videos` WHERE `video_name` IN (%s)', $deleteNames);

Use implode() like this:
$str = '"' . implode('","', array_keys($_POST['checkboxselect'])) . '"';
implode() will take an array and join each value in the array with the "glue" string. In this case the "glue" is "," and the array is composed of the keys in $_POST['checkboxselect']. Finally, the resulting string is wrapped in ".
This will result in your desired example string "myvideo.mp4","myvideo2.mp4","myvideo3.mp4".

Related

PHP SQL query returns 'unknown colum' when string data type

I'm having a problem querying a database. I have been provided the environment so I can not change. And it's a Joomla that I'm trying to adapt to be able to work with a database.
I created the query and I get the data to be inserted correctly when they are numbers, but if I enter a string it returns 'unknown column'.
It is probably a problem with single or double quoting and how the PHP code is being interpreted but I can not see it and I come to see if anyone could lend a hand.
Here is the PHP code I am adding. Supported by JDatabase expressions that joomla provide.
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Insert columns.
$columns = array("De", "Para");
// Insert values.
$data = $_POST['form'];
$de = $data[De];
$para = $data[Para];
$values = array($de, $para);
// Prepare the insert query.
$query
->insert($db->quoteName('referencias'))
->columns($db->quoteName($columns))
// ->values($de, $para);
->values(implode(',', $values));
// Set the query using our newly populated query object and execute it.
$db->setQuery($query);
$db->execute();
Im trying with 2 fields (columns) of the form as you see. If I type 'asfasd' in one of the fields and POST the form it returns:
Unknown column 'asfasd' in 'field list'
But if I type a number it just add the register to database.
Edit: Data type is 'varchar' in SQL Database.
Thanks in advance.
$values = array($de, $para);
Let's assume that De = 3 and Para = asd
$values_str = implode(',', $values);
$values_str will be 3','asd
$values_str = "'" . $values_str . "'"; \\<--This is missing step
Now, $values_str will be '3','asd'
.
.
.
->values($values_str);
I don't know why you want to make a string by imploding the values. But, if you want to, you have to append the quotes on both ends.

Looping an entire form into a MySQL db row?

I'm hoping someone can give me a suggestion on a challenge I am facing. I am not sure that I'm able to do this the way I envision, so looking for advice from those more experienced.
I have a database table with around 20 columns. It's a lot of columns and unfortunately I cannot change that. The goal is to take a form submission and insert it into this table. So what I have is, the field names are identical to the column names in the database.
To try and keep the code cleaner, I would like to just pull the entire form (key and value) in, instead of doing the traditional $varWhatever = $_POST['whatever']; 20 times. Using something like this: foreach ($_POST as $key => $value)
Now my question is, if at all possible, how can I run that foreach loop in a way that will let me put the keys and values into a single SQL statement?
"INSERT INTO table_name (Loop all keys here) VALUES (Loop related values here)"
Is this even possible, or should I just go back to the more traditional way I mentioned above?
One way I am thinking is, before starting the loop, I could create the empty row and grab it's ID, then within the loop, I could run an update query on the row matching the ID. Sounds sloppy though.
Here is a solution I came up with. You first have to define an array of field names that acts as a whitelist of expected inputs. Then you just loop through that array to build a parameters array to bind the submitted values. And implode the array with a comma when building the query.
$fields = array('field1','field2','field3');
$binds = array();
foreach ($fields as $field) {
$binds[":$field"] = $_POST[$field];
}
$sql = "INSERT INTO table_name (" . implode(',',$fields) . ") VALUES (" . implode(',',array_keys($binds)) . ")";
$db->prepare($sql);
$db->execute($binds);
This assumes you are using PDO.
Yes, you can loop for all keys (eg. do an array_keys), but I don't recommend blindly taking any submission parameter and putting it into a SQL query.
Instead, I would keep a list of all valid columns of the form and work with that, remembering that each value needs sanitization, too.
For example:
<?php
$columns = array('column1', 'column2', 'column3', …);
foreach ($columns as $column) {
if (!isset($_POST[$column])) {
die("No data for column $column\n");
}
}
if (!check_csrf($_POST['csrt_token'])) { … }
# (setup database connection)
$SQL = "INSERT INTO table_name (" . implode(", ", $columns) . ") VALUES (";
foreach ($column as $column) {
$SQL .= "'" . $mysqli->real_escape_string($_POST[$column]) . "',";
}
$SQL[strlen($SQL)-1] = ')';
$mysqli->query($SQL);

How to Use foreach with 2 array variable in php

i have codes like this
<?php
include "assets/config/connect.php";
foreach( $_POST['nim'] as $nim ){
$kode_mk= $_POST['kode_mk'] ;
$nilai= $_POST['nilai'] ;
$tahun_akademik= $_POST['tahun_akademik'] ;
$sql = " INSERT INTO nilai (nim, kode_mk, nilai, tahun_akademik, id_nilai) VALUES ('$nim', '$kode_mk', '$nilai', '$tahun_akademik', NULL) ";
if (!mysql_query($sql)){
die('Error: ' . mysql_error());
}
}
?>
but the result is not same with my expectation
this is the result
please help me
$kode_mk = $_POST['kode_mk'];
$nilai = $_POST['nilai'];
$tahun_akademik = $_POST['tahun_akademik'];
all variables are arrays, not strings as you expect, you should
var_dump($_POST);
to see the entire structure of POST array
The Error
So assuming kode_mk, nilai, tahun_akademik are all arrays in $_POST you are trying to insert the object of an array as a string. First convert the array to a string using a function like implode().
Solution: Using PHP Implode()
$array = array('hi', 'my', 'name', 'is');
$string = implode(',', $array); // string = 'hi,my,name,is'
Implode works like this implode(glue, array) the glue is a string that is inserted between each element of the array to separate them in a string. You can use explode(delimiter, string) to then reverse the string to an array!
Example Using your code
<?php
include "assets/config/connect.php";
foreach( $_POST['nim'] as $nim ){
$kode_mk= implode(', ', $_POST['kode_mk']);
$nilai= implode(', ', $_POST['nilai']);
$tahun_akademik= implode(', ', $_POST['tahun_akademik']);
$sql = " INSERT INTO nilai (nim, kode_mk, nilai, tahun_akademik, id_nilai) VALUES ('$nim', '$kode_mk', '$nilai', '$tahun_akademik', NULL) ";
if (!mysql_query($sql)){
die('Error: ' . mysql_error());
}
}
?>
Notes:
Try Using mysqli not the mysql extension for security reasons mentioned by: #messy
Looks like you are looping over $_POST['nim'], but then pulling the same $_POST values for the columns of the database.
We could really use the format and syntax of the $_POST variable
You have to show us what your input data looks like. You can do that with print_r() or var_dump():
print_r($_POST);
From the looks of it, your form inputs are arrays (checkboxes?) and you need to either pull them together into a single string or use each one separately.
Also, there is no reason to continue to gather your POST values inside the loop if there is no change in their values. Pull them up outside the loop.
Finally, the mysql_ extension is deprecated and highly discouraged - you shouldn't be using it to write new code. You also need to validate and sanitize your data before doing any inserts. Easiest way to do the latter is parameterized queries.

Fastest way to check array items existence in mySQL table

User writes a series of tags (, separated) and posts the form.
I build an array containing the tags and delete dupes with array_unique() php function.
I'm thinking of doing:
go through the array with foreach($newarray as $item) { ... }
check each $item for existence in the tags mySQL table
if item does not exists, insert into tags table
Is there a FASTER or MORE OPTIMUM way for doing this?
I'm hoping that people can comment on this method. Intuition tells me its probably not the best way to go about things, but what do you all think?
Instead of making an extra call to the DB to find duplicates, just add a unique constraint in the DB so that tags cannot be inserted twice. Then use INSERT IGNORE... when you add new tags. This method will ignore the errors caused by duplications while at the same time inserting the new items.
You can call implode( ',' $array ) then use the IN SQL construct to check if there are existing rows in the db.
Example:
<?php
$arr = ...
$sql = 'SELECT COUNT(*) FROM table WHERE field IN ( ' . implode( ',', $arr ) . ' );';
$result = $db->query( $sql );
?>
$tags = array('foo', 'bar');
// Escape each tag string
$tags = array_map('mysql_real_escape_string', $tags, array($sqlCon));
$tagList = '"' . implode('", "', $tags) . '"';
$qs = 'SELECT id FROM tag_list WHERE tag_name IN (' . $tagList . ')';
I don´t know if it's faster, but you can use mysql's IN. I guess you'd have to try.
You could build up a big query and do it in one shot, instead of many little queries:
SELECT DISTINCT tag
FROM my_tags
WHERE tag in ( INPUT_TAGS )
Just build up INPUT_TAGS as a comma-separated list, and make sure you properly escape each element to prevent SQL injection attacks.

Php Multi-Dimensional Array / MySql problem

I am trying to write a php script that take a text file break down its contents and and insert it into a MySql database, the code is as follows:
$file = "my_file.txt";
$db = "db_name";
$link = mysql_connect("localhost","root");
if(!$link) die("Connection Failed");
mysql_select_db($db) or die("Could not open $db: ".mysql_error()."<br />");
$fp = fopen($file, 'r') or die("Could not open file");
$my_filesize = filesize($file);
while(!feof($fp)) {
$prod_doc.=fread($fp, $my_filesize); // store the file in a variable
}
$prod_array = explode("~",$prod_doc); // create a array with the explode function
for($i=0; $i<count($prod_array); $i++){
$prod_items[$i] = explode(',', $prod_array[$i]); // create a malti-dimensional array
}
$query = "INSERT INTO my_table(feild1, feild two, feild three)
VALUES ('$prod_items[$i][0]','$prod_items[$i][1]','$prod_items[$i][2]')
";
$result = mysql_query($query);
if(!$result) die(mysql_error());
$result = mysql_affected_rows($result);
echo $result;
mysql_close($link); `
My problem is this: Array[0], Array[1], Array[3] is what is entered into the database instead of my data. Thanks in advance, cheers.
To access array variable element values used inside a double-quote string need braces delimiters:
"'{$prod_items[$i][0]}','{$prod_items[$i][1]}','{$prod_items[$i][2]}') ";
Another way to code this is by concatenation (in which case you don't need the extra delimiters):
"'" . $prod_items[$i][0] . "','" . $prod_items[$i][1] . "','" . $prod_items[$i][2] . "') ";
Don't forget, if the input data is unpredictable, you need to filter out characters that can break your sequel or compromise security principles. SEE How can I prevent SQL injection in PHP?
Also, junmats's comment is correct, you are only running the query outside the for loop which doesn't make sense.
You have to iterate over your $prod_items array as well, then concate the values
$insert = array();
for($i=0; $i<count($prod_array); $i++){
$prod_items[$i] = explode(',', $prod_array[$i]); // create a malti-dimensional array
$insert[] = '( ' .$prod_items[$i][0]. ', '.$prod_items[$i][1]. ', '. $prod_items[$i][3] .')';
}
$insert_string = implode(', ', $insert);
$query = "INSERT INTO my_table(feild1, feild two, feild three)
VALUES" . $insert_string;
And you should use foreach insted of for.
Seems like you've skipped some code.
After explode you'll have array of strings, not 2d array.
Also it's better to update the code a bit.
$query = "INSERT INTO my_table(feild1, feild_two, feild_three) VALUES ('".$prod_items[$i][0]."','".$prod_items[$i][1]."','".$prod_items[$i][2]."') ";
You should use the standard concatenation(.) technique for this.
PHP can only evaluate simple variables inside a string:
"$var" --> var is evaluated
"$var->var" --> is not evaluated
"$var[0]" --> is not evaluated
$query = "INSERT INTO my_table(feild1, feild two, feild three)
VALUES ('".$prod_items[$i][0]."','".$prod_items[$i][1]."','".$prod_items[$i][2]".')
";

Categories