Sorry for my English but it is not my native language.
I have created a user interface to insert data to MySQL. Everything except one thing is ok but when I want to read data from multiple checkboxes and write them to SET type in MySQL it just doesn't work. I have tried to find the answer but after 4 hours I can't find it or I don't understand it.
http://jyxo.info/uploads/21/21b104df77f6ca723bb708d8d0549af5430e8e91.jpg
dobaVyskytu is SET type and there are in with month you can find mushroom(my tema is online atlas of mushrooms)
in user interfacei have 12 checkbox for 12 month.
http://jyxo.info/uploads/FD/fd548760b155307dfa677ada7c4be4996abf7b93.png
In dobavyskytu i need to have multiple select and that is reason why i use $doba +=
if(isset($_POST["Leden"]))
{
$doba += "Leden";
}
if(isset($_POST["Únor"]))
{
$doba += "Únor";
}
if(isset($_POST["Březen"]))
{
$doba += "Březen";
}
Db::query("INSERT INTO houby(nazev,dobaVyskytu,mistoVyskytu,popis,jedovatost,img)VALUES(?,?,?,?,?,?)",$nazev,$doba,$misto,$popis,$jedovatost,$foto);
Thank you all for reading and for help because it works now.
For strings in PHP, it uses . as concatanation not +, so
$doba .= "Leden";
Edit:
For a better way of doing this, you should try something like...
$options = [];
if(isset($_POST["Leden"]))
{
$options[] = "Leden";
}
if(isset($_POST["Únor"]))
{
$options[] = "Únor";
}
...
$doba = implode(',', $options);
As this will give you something like Leden,Únor
My hypotheses are:
$doba is the variable you want to insert in your SET type column (I translated and it seems the values you put as example in your question is Slovak for "January", "February", "March" -- I suppose there could be more).
I suppose that your SET type column is "dobaVyskytu" and that you created it correctly in MySQL by including all the possible values in the column definition.
(Your question update seem to confirm my hypotheses!)
First, when you want to insert multiple values in a SET type column in MySQL, the string value has to be separated with commas.
With the code I see, you can end up with that string "LedenÚnorBřezen" (I suppose you use += for string concatenation, but you should really use .= like Nigel Ren mentionned). You really want to end up with a string like "Leden,Únor,Březen" if all the 3 values you show are checked in your form.
See here for how to handle SET type in MySQL:
https://dev.mysql.com/doc/refman/5.7/en/set.html
Since you do not know if you will end up with 0 or multiple values for that column, I would suggest to make $doba an array.
$doba = array(); // depending on your PHP version, you can also write $doba = [];
After, you can add your values this way (the syntax $array[] = 'value' will apprend a value to the array):
$doba[] = "Leden";
$doba[] = "Únor";
$doba[] = "Březen";
Then, before inserting it, you can convert the array to a string with the values separated by commas that way:
$csvDoba = implode(',', $doba);
Then use $csvDoba instead of $doba in your Db::query() line.
After you get this working, here are more things you can look for to improve your code:
You can also take advantage PHP magic by naming your form checkbox with a special name to avoid repeating yourself.
For example, you can name all your checkboxes with the name "doba[]", and if (isset($_POST["doba"]), it will already be an array with all the checked values! But beware, if no value is checked, it won't be set. That way, you will avoid doing an if condition for each of your checkbox.
You can do something like this in your code to retrieve the value:
$doba = isset($_POST['doba']) ? (array) $_POST['doba'] : array();
What this do?
If any checkboxes named "doba[]" is checked, then you will retrieve them and make sure the value you retrieve is of type array, the "(array)" part for the value to be an array even if it was not (e.g., an error or someone trying to hack your form). Else you will return an empty array (as no choices has been put).
If you are not familar with this syntax, do a searcch for "ternary operator".
You will of course want to do some validation of your values if not already done
You might look to put the values in another table instead of using the "SET type", but that is up to you and at this stade you probably still have a couple stuff to learn, so I don't want to flood you with too much info. ;-)
Related
I have an ENUM stored in PHPMYADMIN which allows the numbers 1-10.
I'm trying to find out how that number can be converted to a string which the user can see, an example is;
1=London
2=Spain
3=France
4=Germany
etc...
The obvious way would be to do an if statement for each something like
if ENUM == 1 then STRING == "London"
if ENUM == 2 then STRING == "Spain"
but I was wondering if there was a similar way of doing this or if I just need to do 10 if statements. I've tried to look online but no helpful tutorials.
Thanks (Sorry i've had to submit the question as code, stackoverflow wouldnt allow me to post it otherwise for some reason)
Here is an efficient/clean/professional way of doing it:
$enum = 1; // The value fetched from the database
$cities = array(
'1'=>'London',
'2'=>'Spain',
'3'=>'France',
'4'=>'Germany'
); // Array of cities
// Make sure there is a city with the given key
if(isset($cities[$enum])){
echo $cities[$enum];
}
But it is also advisable to store the cities in another database table.
Answer found (syntax): The column name of my string had to be encased in backticks " ` " as they contained spaces. Note that this means that the majority of this post has no relevance to the issue. The code has been corrected in case someone wants to do something similar.
So, I am doing a foreach loop to assign a value (1/0) to non-static columns in my database (it needs to support addition/deletion/editing of columns). I am using $connectionvar->query($queryvar); to do my queries which worked fine up until now when I'm trying to use a custom built string as $queryvar in order to change the column name to a variable within the loop. I've been outputting this string through echo and it looks exactly like my functional queries but somehow doesn't run. I've attempted to use eval() to solve this but to no avail (I feel safe using eval() as the user input is radio buttons).
Here's the loop as well as my thought processes behind the code. If something seems incoherent or just plain stupid, refer to my username.
foreach($rdb as $x) { //$rdb is a variable retrieved from $_POST earlier in the code.
$pieces = explode("qqqppp", $x); //Splits the string in two (column name and value) (this is a workaround to radio buttons only sending 1 value)
$qualname = $pieces[0]; //Column name from exploded string
$qualbool = $pieces[1]; //desired row value from exploded string
$sql = 'UPDATE users SET '; //building the query string
$sql .= '`$qualname`';
$sql .= '=\'$qualbool\' WHERE username=\'$profilename\''; //$profilename is retrieved earlier to keep track of the profile I am editing.
eval("\$sql = \"$sql\";"); //This fills out the variables in the above string.
$conn->query($sql); //Runs the query (works)
echo ' '.$sql.' <br>'; //echoes the query strings on my page, they have the exact same output format as my regular queries have.
}
}}
Here's an example of what the echo of the string looks like:
UPDATE users SET Example Qualification 3='1' WHERE username='Admin2'
For comparison, echoing a similar (working) query variable outside of this loop (for static columns) looks like this:
UPDATE users SET profiletext='qqq' WHERE username='Admin2'
As you can see the string format is definitely as planned, yet somehow doesn't execute. What am I doing wrong?
PS. Yes I did research this to death before posting it, as I have hundreds of other issues since I started web developing a month ago. Somehow this one has left me stumped though, perhaps due to it being a god awful hack that nobody would even consider in the first place.
You need to use backticks when referring to column names which have spaces in them. So your first query from the loop is outputting as this:
UPDATE users SET Example Qualification 3='1' WHERE username='Admin2'
But it should be this:
UPDATE users SET `Example Qualification 3`='1' WHERE username='Admin2'
Change your PHP code to this:
$sql = 'UPDATE users SET `'; // I added an opening backtick around the column name
$sql .= '$qualname`'; // I added a closing backtick around the column name
$sql .= '=\'$qualbool\' WHERE username=\'$profilename\'';
Example Qualification 3 : Is that the name of your Mysql Column name ?
You shouldnt use spaces nor upper / lower case in your columnname.
Prefere : example_qualification_3
EDIT :
To get column name and Comment
SHOW FULL COLUMNS FROM users
i have a row in my database with name "active_sizes" and i want filter my website items by size, for this, i use LIKE Condition in php :
AND active_sizes LIKE '%" . $_GET['size'] . "%'
but by using this code i have problem
for example when $_GET['size']=7.0 this code shows items that active_sizes=17.0
my active_sizes value looks like 17.0,5.0,6.5,7.5,,
thanks
Using comma-separated values in a single field in a database is indicative of bad design. You should normalize things, and have a seperate "item_sizes" table. As it stands now, you need a VERY ugly where clause to handle such sub-string mismatches:
$s = (intval)$_GET['size'];
... WHERE (active_sizes = $s) // the only value in the field
OR (active_sizes LIKE '$s%,') // at the beginning of the field
OR (active_sizes LIKE '%,$s,%') // in the middle of the field
OR (active_sizes LIKE '%,$s') // at the end of the field
Or, if you normalized things properly and had these individual values in their own child table:
WHERE (active_sizes_child.size = $s)
I know which one I'd choose to go with...
You don't state which DB you're using, but if you're in MySQL, you can temporarily accomplish the same thing with
WHERE find_in_set($s, active_sizes)
at the cost of losing portability. Relevant docs here: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set
You Have % signs around your $_GET value. Combined with LIKE, this means that any string that simply contains your get value will be retuned. If you want an exact match, use the = operator instead, without the percentage signs.
This will solve your immediate issue:
AND active_sizes LIKE '" . mysql_real_escape_string($_GET['size']) . "%'
If you are using the database other than MySQL, use corresponding escape function. Never trust input data.
Besides, I'd suggest using numeric field (DECIMAL or NUMERIC) for active_sizes field. This will accelerate your queries, will let you consume less memory, create queries like active_sizes BETWEEN 16.5 AND 17.5, and generally this is more correct data type for a shoe size.
I've got a form with checkboxes set to bitwise values (CB1=1,CB2=2,CB3=4,CB4=8), and I want to store their sum in a single cell (to avoid having empty fields). The checkboxes have the same name but different values, and the data is sent to the processing php script as a serialised string, ie name=value&name=value2&name3=value3&name=&name=value5
Currently I can separate the string and get the values into the proper cells rather efficiently/easily. But, I'm wondering if there is a way to insert the first value into the cell then add subsequent values to the same cell. I imagine it would look something like this:
foreach ( $qaPairs as $pair ) {
list($question , $answer) = explode('=', $pair);
// ^ splits Q1=A1 into $question=Q1 and $answer=A1
// this mysql_query is a modified version of what I'm currently using
mysql_query("UPDATE $table SET `$question`=`$question`+'$answer' WHERE `key`='$key';") or die(mysql_error());
// $question is also the name of the column/field
} // end foreach
I dunno if it makes a difference, but: there are other datatypes (besides bitwise integers, such as text) and other form types (like textfields).
P.S. I would rather not have to somehow check if there are multiple instances of the same name and then do addition.
P.P.S. I got the UPDATE idea from this question: MySQL Batch increase value?, and I tried it out, but it didn't update null values (which I need it to do).
Thanks in advance!
Working on a pre-existing program that parses an html form that has a dynamically created number of fields, and in the interest of forward-compatibility, may not even know number of mysql columns...
I imagine that this requires creating two arrays, and comparing/re-ordering of some sort, but can't quite wrap my head around it...
Would this be something like:
A) Database Array -
1) get # of MySQL columns
2) loop through this number and get MySQL column names
B) Form Array -
1) get # of form fields
2) get form field names/values
C) Match Array -
match name.form_field[f] to name.mysql_column[c]
D) Execute Insert -
insert value of name.form_field[f] into name.mysql_column[c]
(INSERT INTO name.mysql_column[c], name.mysql_column[c+2], name.mysql_column[c+5], name.mysql_column[c+n] VALUES value(name.form_field[f]), value(name.form_field[f+9]), value(name.form_field[f+3]), value(name.form_field[f+x]))
I'm guessing the answer is something like the above, but can't quite picture the nested loops required to achieve the result...
Any possible solutions spring to mind out there?
All responses will be greatly appreciated!
Thanks,
Sean McKernan
McK66 Productions
This requires a longer answer, but I'll try a halfway decent introduction.
I suggest approaching the problem from the other direction. Ideally, the code would have it's own list of fields to insert and then go looking at the submitted data to construct the relevant rows. That also lets it have default values for 'missing' columns, so it can always generate row data with the correct number of fields.
There is a distressingly high amount of PHP which uses the submitted field names to build the SQL rather than starting with a known list of field names. In my experience, programmers do this because they are in control of the generated form, but forget that they aren't really in control of the submitted form. All it takes is a little editing in FireBug and you can knock the page for six, potentially corrupting your database.
I'm not sure if this fits your situation exactly, but we use something similar to the following for handling queries with data we aren't sure we have absolute control over. The form input names match the column names so if your's don't, you'll need to come up with the correct mapping.
This retrieves the column data from the table, and then builds the query from the form data using only the elements that match columns that exist in the table.
DB() is our wrapper around MDB2.
$db = new DB();
$sql = 'DESCRIBE `table`';
$result = $db->query($sql);
$row = array();
$query = array();
while ($row = $result->fetchRow())
{
if (array_key_exists($row['field'], $form_data))
if (is_null($form_data[$row['field']]))
$query[$row['field']] = 'NULL';
else
$query[$row['field']] = $db->quote($form_data[$row['field']]);
}
$keys = array_keys($query);
foreach ($keys as &$key)
$key = $db->quoteIdentifier($key);
unset($key);
$vals = array_values($query);
$sql = 'INSERT INTO `table` '
. '(' . implode(', ', $keys) . ') '
. 'VALUES(' . implode(', ', $vals) . ')';