Stored ENUM is displayed as a string - php

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.

Related

Creating a SQL query with OR statements based on whether or not checkboxes have been ticked

I am building a search engine for a school project, meant to allow users to look through a large database of schools, and I have set it up so that on one page, the user would be able to tick certain checkboxes, and that after hitting submit, the user would be returned with a list of schools which correspond to what was ticked.
The user is allowed to search schools nationwide along a number of parameters:
School type (high school, middle school, trade school, university, etc...)
School status (private or public)
City
State
etc.
For my question, I'll only focus on the part related to school types, as I can later apply the logic with the other form elements which function similarly.
For school types, along with a number of other form elements, I have decided to use checkboxes, so that for instance, if a user wants the search to return both middle schools and high schools, he would only need to tick both the "middle school" and "high school" checkboxes.
So, this implies using OR statements in my search, so that I would, for instance, have a SQL query like this:
SELECT schools.schoolId, schools.schoolName, villages.villageName FROM schools, villages
WHERE schools.villageId = villages.villageId
And here is where I would set up the condition that only the information pertaining to middle schools, high schools, and trade schools be returned by the query:
AND (schools.schoolType = "MiddleSchool" OR schools.schoolType = "HighSchool" OR schools.schoolType = "TradeSchool")
It is the construction of this statement that I am having trouble with.
As it is, because the school types can vary as the database evolves, I cannot hard code my query construction, nor do I wish to.
I use PHP to generate my query based on the form results.
To generate a list of all available school types, I read all the existing school types from the database (MySQL) using a DISTINCT query. I use this to build a list of all the available school types, which I use to generate the search form.
As such, I have to use a similar method to compare the form results with the database, meaning that, on my results page, to see which checkboxes have been ticked, I need to see what checkboxes could have existed at the moment the form was sent, so I once again read all of the available types from the database: (some code cut off, this is just the query I use which I know works, but this is just for context)
try
{
$pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$req_sql_type_school = "SELECT DISTINCT schoolType AS types FROM schools";
$res_type_schools = $pdo->query($req_sql_type_school);
$res_type_schools->setFetchMode(PDO::FETCH_ASSOC);
} catch (PDOException $e)
{
die("Could not connect to the database $dbname :" . $e->getMessage());
}
After that, I iterate over the query results to create an array of the school types: (I know this works too, but again, it's just for context)
$arrayTypes = array();
while ($row = $res_type_schools->fetch())
{
$arrayTypes[]=$row['types'];
}
Then, this is where I struggle. It is at this point that I must create the "AND..." statement to the start of the query which I mentioned above, which was:
SELECT schools.schoolId, schools.schoolName, villages.villageName FROM schools, villages
WHERE schools.villageId = villages.villageId
To see whether or not something was ticked by the user, I iterate over the array to check whether or not the corresponding checkbox was ticked. To do this, here is the code I wrote. Note: basictext() just formats the string to the format I used for my checkbox values, which is lowercase-only strings with no spaces and no accents):
foreach($arrayTypes as $arr)
{
if(isSet($_GET[basictext($arr)]))
{
echo "[x] Type ".$arr." <br/>";
}
else
{
echo "[ ] Type ".$arr." <br/>";
}
}
This allows me to check which types were checked by the user on the search form.
However, I don't know how to translate this to the AND statement I wanted, which was this one:
AND (schools.schoolType = "MiddleSchool" OR schools.schoolType = "HighSchool" OR schools.schoolType = "TradeSchool")
I had thought of placing each type inside parentheses and separating each type with an OR, and only writing inside the parentheses if the type was indeed checked.
This resulted in something like this:
AND ((schools.schoolType = 'MiddleSchool') OR () OR () OR (schools.schoolType = 'HighSchool') OR () OR () OR ())
Needless to say, it was very ugly, and it also didn't work, so I canned it. The problem is that I don't know how many "checked types" there can be, so, it's a little difficult to build a proper query.
One solution I've thought of while writing this is to place each "valid" type inside an array, and then use that array, whose length I would then know. Then I would be able to create the expected AND statement, because I would then have a definite amount of checked checkboxes, and it would also allow me to completely ignore the non-ticked values. Do you think that would work?
If your schools.schoolType column is an arbitrary VARCHAR data type, there needs to be some relationship between the data the user submits and the data used in the query, unless you predefine a list of possible values beforehand.
It looks like you have some relationship between the arrayTypes array of yours and the $_GET value. So assuming the query wants HighSchool, this can be detected if the user submits highschool using your basictext() function.
From there I would do something like this:
$selectedTypes = array();
foreach($arrayTypes as $arr)
{
if(isSet($_GET[basictext($arr)]))
{
echo "[x] Type ".$arr." <br/>";
$selectedTypes[] = $arr;
}
else
{
echo "[ ] Type ".$arr." <br/>";
}
}
This would populate the selectedTypes array with the matching types of what the user submits.
Using this it sounds like you want to add an IN clause to your final query.
$placeholders = implode(',', array_fill(0, count($selectedTypes), '?'));
$template = "SELECT schools.schoolId,
schools.schoolName,
villages.villageName
FROM schools,
villages
WHERE schools.villageId = villages.villageId
AND schools.schoolType IN ($placeholders)";
$stmt = $pdo->prepare($template);
$stmt->execute($selectedTypes);
$result = $stmt->fetchAll();
$stmt = null;
If selectedTypes contains ["HighSchool", "MiddleSchool", "TradeSchool"] then $placeholders will contain [?, ?, ?]. This is used to construct an SQL template for a prepared statement query using the selectedTypes array as the input data.
$result ought to have the data you're after.
So if I'm understanding you right, you simply need to write something to concatenate fragments of an OR statement based on a bit array. Instead of adding an OR for every entry regardless of if it is checked or not, do something like
first = true
string orClause = ""
array schoolTypes
array checkedSchoolTypes
for(i = 0; i < checkedSchoolTypes.length; i++)
if(first && checkedSchoolTypes[i])
orClause += "schools.schoolType = " + schoolTypes[i]
first = false
else if(checkedSchoolTypes[i])
orClause += "OR schools.schoolType = " + schoolTypes[i]
query = "This is your query" + orClause + "rest of your query"
*Note this is a solution for a school project not a production environment. If you were do this in a production environment in that case you would want to pass information through a paramaterized stored procedure and generate your statement in the sql based off of the information passed in from the form.
Instead of doing the or as you are suggesting you could do and IN statement as others are suggesting the code would basically be the same with a different format. Let me know if you need any clarifications.

Mysql INSERT SET type

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. ;-)

PHP: If statements unintentionally causing multiple MySQL columns to update?

I have a form on a page containing:
a text entry box named teachername
a text entry box named day (in the format YYYY-MM-DD)
a selection box named "resource" with the options [Library 1 or Library 2]
a selection box with the values [1,2,3 and 4] named block.
My mysql database has the fields:
- Teacher
Library1block1
Library1block2
Library1block3
etc.
The data from the html page is passed onto a php page meant to match the resource and block with the correct mysql field, and update the field so that the data from the text entry box "teachername" is inserted into it.
if ($_POST['resource']="Library 1" and $_POST['block']="1")
{mysql_query(
"UPDATE Resources
SET Teacher='yes', Library1block1='$_POST[teachername]'
WHERE Date='$_POST[day]'");}
if ($_POST['resource']="Library 1" and $_POST['block']="2")
{mysql_query(
"UPDATE Resources
SET Teacher='yes', Library1block2='$_POST[teachername]'
WHERE Date='$_POST[day]'");}
Expected:
- Enter "Mr. Smith" into teachername text entry field, select "Library 1" and "1" within the selection menu, and enter "2012-03-16" in the text entry field named day
Data is stored and passed along to the php script
an if statement updates the database record containing the field matched by the "resource"
field and "block" field (library1b1, library1b2, etc) for the date entered in the day text field
the field is updated, and the subsequent if statements check to match up the entered data with the correct mysql field
Result:
All fields (not just the specified field) are updated according to the first if statement.
EX: Entering in "Mr. Smith" for teachername, selecting "Library 1", selecting "1" for the block, and entering "2012-03-16" for the date does not update only the Library1block1 field, but it also updates the Library1block2 and library2block1 fields.
The mysql statement, when entered directly into a mysql terminal, updates the singular field correctly, but the usage of this php code results in multiple updated rows.
Help please?
You are making a common mistake of using the assignment operator (=) rather than the equality operator (==). On lines that look like this:
if($_POST['resource']="Library 1")
Change them to use the comparison operator:
if($_POST['resource'] == "Library 1")
The folks who have given answers have done a good job, but I would like to add one little trick that I like to use sometimes (depending on the language, etc.)
Usually you will write an if statement as something like
if ( $var == 1 ) { do_stuff( $var ) }; //or whatever
This following simple little trick has made this potential mistake almost impossible for me to make (esp. with php).
Just switch the two around.
So instead of the usual:
if ( $var == 1 ) { do_stuff( $var ) }; //or whatever
Try this instead whenever you can:
if ( 1 == $var ) { do_stuff( $var ) }; //or whatever
I'm pretty sure php 5.2+ hasn't changed to the point that it no longer works, but even if you make the mortal mistake of using a single equals sign it should still work because you can't assign a value to a constant (numbers are constant values, right?).
I believe this relies on php's behavior of always processing code from left to right:
if ( 1 = $var ) { do_stuff( $var ) }; //or whatever
And you're golden! Since I started doing this over 5 years ago I have never run into this problem again. 1 is always 1, no matter what you do. This is a good way of thinking through your conditionals, loops, etc. in php.
The beauty of this is in its mind smacking simplicity. "$var" can be lots of things, but the number 1 is always the number 1. I'm sure this doesn't work for all languages, but for php, it's one I use a lot, and it's apparently a good habit anyway to structure your code this way.
You should use two equal signs like this in you if statements to compare values:
$_POST['resource']=="Library 1"
This will check if $_POST['resource'] equals (==) Library 1
A single equal sign assigns Library 1 to $_POST['resource']
You may check Comparison Operators on php.net for more information:
http://php.net/manual/en/language.operators.comparison.php
Edit:
You should also use mysql_real_escape_string() for user input value such as $_POST:
if ($_POST['resource'] == "Library 1" and $_POST['block'] == "2")
{
mysql_query(
"UPDATE Resources
SET
Teacher='yes',
Library1block1='".mysql_real_escape_string($_POST['teachername'])."'
WHERE
Date='".mysql_real_escape_string($_POST['day'])."'"
);
}

how to implement the an effective search algorithm when using php and a mysql database?

I'm new to web design, especially backend design so I have a few questions about implementing a search function in PHP. I already set up a MySQL connection but I don't know how to access specific rows in the MySQL table. Also is the similar text function implemented correctly considering I want to return results that are nearly the same as the search term? Right now, I can only return results that are the exact same or it gives "no result." For example, if I search "tex" it would return results containing "text"? I realize that there are a lot of mistakes in my coding and logic, so please help if possible. Event is the name of the row I am trying to access.
$input = $_POST["searchevent"];
while ($events = mysql_fetch_row($Event)) {
$eventname = $events[1];
$eventid = $events[0];
$diff = similar_text($input, $event, $hold)
if ($hold == '100') {
echo $eventname;
break;
else
echo "no result";
}
Thank you.
I've noticed some of the comments mentioned more efficient ways of performing the search than with the "similar text" function, if I were to use the LIKE function, how would it be implemented?
A couple of different ways of doing this:
The faster one (performance wise) is:
select * FROM Table where keyword LIKE '%value%'
The trick in this one is the placement of the % which is a wildcard, saying either search everything that ends or begins with this value.
A more flexible but (slightly) slower one could be the REGEXP function:
Select * FROM Table WHERE keyword REGEXP 'value'
This is using the power of regular expressions, so you could get as elaborate as you wanted with it. However, leaving as above gives you a "poor man's Google" of sorts, allowing the search to be bits and pieces of overall fields.
The sticky part comes in if you're trying to search names. For example, either would find the name "smith" if you searched SMI. However, neither would find "Jon Smith" if there was a first and last name field separated. So, you'd have to do some concatenation for the search to find either Jon OR Smith OR Jon Smith OR Smith, Jon. It can really snowball from there.
Of course, if you're doing some sort of advanced search, you'll have to condition your query accordingly. So, for instance, if you wanted to search first, last, address, then your query would have to test for each:
SELECT * FROM table WHERE first LIKE '%value%' OR last LIKE '%value%' OR address LIKE '%value'
Look at below example :
$word2compare = "stupid";
$words = array(
'stupid',
'stu and pid',
'hello',
'foobar',
'stpid',
'upid',
'stuuupid',
'sstuuupiiid',
);
while(list($id, $str) = each($words)){
similar_text($str, $word2compare, $percent);
if($percent > 90) // Change percentage value to 80,70,60 and see changes
print "Comparing '$word2compare' with '$str': ";
}
You can check with $percent parameter for how strong match you want to apply.

PHP Form Posting Values To Database

Basically, i have a working form where the user inputs details about their laptop to sell to my shop.
I give them a quote once they have submitted the Specs of the laptop.
At the moment i have got option boxes and checkboxes which each have a value-- for example these. ---
<label for="state">State</label><br>
<select name="state">
<option value="10">Excellent</option>
<option value="5">Good</option>
<option value="0">Poor</option>
</select><br>
The Values of the options they have selected get added up at the end and that gives them the quote - in the above example - "10" means £10 extra for a excellent condition laptop etc.
I use $_POST[state] to get the value of it to add onto the other options for the quote.
But my problem lies when i POST them to a database (so we can check when they come in).
When they get added to the database, obviously it just comes out as the values not the actually name of it like "excellent" or "good". just says "10" or "5".
Is there anyway to put the name of the option into the database instead of the value?
sure... just make sure that's what you want to do. It's usually not considered a good database practice to create denormalized tables like that, but you could do it. When you collect your post data, simply create another variable and assign a value to it based off the state value like so:
$stateText = '';
switch ($state){
case 10:
$stateText = 'Excellent';
break;
case 5:
$stateText = 'Good';
break;
case 0:
$stateText = 'Poor';
break;
default:
// bad value
$stateText = '';
}
...then store this to the database in a new column.
This is just one of many ways to do this.
You can only do it if you have a lookup, be it an array or in another table that stores the keys and values.
You should be carefuly not to store the post data directly into your database without sanitizing it, otherwise you might become subject to sql injection.
Is there anyway to put the name of the option into the database instead of the value?
There is, but it involves doing it explicitly (converting "10" into "Excellent" before inserting the value) rather than just basically tossing $_POST into the database as-is. You can make this very simple if you are building the <option>s with an array in the first place by reading the the array again and swapping the values with the keys.
$values = array(
10 => 'Excellent',
5 => 'Good',
0 => 'Poor',
);
$post_value = $_POST['state'];
$db_value = $values[$post_value];
// further validation: make sure the array key exists or use a default value
// further usage: build your HTML <options> with this array
However:
If you're going to do that, you're much better off storing the values as numbers and converting them to words when you display them (assuming the numbers do have some meaning). This also allows you to localize by providing translations.
Response to comments:
I would recommend a rating system, like 1 through 5, and calculate your price modifications internally - not directly from the user input or from a hardcoded value (in the database). This allows you to tweak the price changes from within your app, rather than from database values that were created at an earlier time, like if you decide an "Excellent" condition warrants an increase of 11 rather than 10 - unless you specifically want the prices "locked in" permanently at the time the product was posted.
Whatever you do, make sure to validate the input - I can't think of any good reason to use direct user input to calculate prices - it should be done internally based on product ids, and any other conditions. HTML source can be modified on-the-fly to post values you didn't expect from the dropdown.
You can't get it via the HTML form. But you can still do a server side that would map the values to the appropriate condition.
You can use a switch statement or an if statement to map them.
if(value == 10){
$condition = 'Excellent';
} else {//....}

Categories