I have a form where I am trying to implement a tag system.
It is just an:
<input type="text"/>
with values separated by commas.
e.g. "John,Mary,Ben,Steven,George"
(The list can be as long as the user wants it to be.)
I want to take that list and insert it into my database as an array (where users can add more tags later if they want). I suppose it doesn't have to be an array, that is just what seems will work best.
So, my question is how to take that list, turn it into an array, echo the array (values separated by commas), add more values later, and make the array searchable for other users. I know this question seems elementary, but no matter how much reading I do, I just can't seem to wrap my brain around how it all works. Once I think I have it figured out, something goes wrong. A simple example would be really appreciated. Thanks!
Here's what I got so far:
$DBCONNECT
$artisttags = $info['artisttags'];
$full_name = $info['full_name'];
$tel = $info['tel'];
$mainint = $info['maininst'];
if(isset($_POST['submit'])) {
$tags = $_POST['tags'];
if($artisttags == NULL) {
$artisttagsarray = array($full_name, $tel, $maininst);
array_push($artisttagsarray,$tags);
mysql_query("UPDATE users SET artisttags='$artisttagsarray' WHERE id='$id'");
print_r($artisttagsarray); //to see if I did it right
die();
} else {
array_push($artisttags,$tags);
mysql_query("UPDATE users SET artisttags='$artisttags' WHERE id='$id'");
echo $tags;
echo " <br/>";
echo $artisttags;
die();
}
}
Create a new table, let's call it "tags":
tags
- userid
- artisttag
Each user may have multiple rows in this table (with one different tag on each row). When querying you use a JOIN operation to combine the two tables. For example:
SELECT username, artisttag
FROM users, tags
WHERE users.userid = tags.userid
AND users.userid = 4711
This will give you all information about the user with id 4711.
Relational database systems are built for this type of work so it will not waste space and performance. In fact, this is the optimal way of doing it if you want to be able to search the tags.
Related
I know I'm probably doing this in a round about fashion but I don't understand why it wont work or a better way to just retrieve ONLY THE STRING VALUES in an array so that I can move them to a different table. I thought I could iterate through the array list and output only the strings in the array but it is not working :(
//database config and wpdb access code...
<?php
$cbposttitles = $wpdb->get_col('SELECT post_title FROM wp_posts' );
$countofposttitles = count($cbposttitles);
echo "count of post tiles . $countofposttitles"; //counts correctly
?>
<br>
<?php
for ($x = 0; $x < $countofposttitles; $x++) {
$individualpost = $wpdb->get_var('SELECT post_content FROM wp_posts WHERE ID =
[$x]');
echo $individualpost; // does't work
}
?>
$countofposttitles contains nothing but the number of posts/titles. This you have no use for in your piece code. You probably try to select some kind of ids from your first query and look for each of these in your second. However, this is very inefficient since you're making a lot of unnecessary database requests.
Which strings and/or values to you actually want and what is the purpose? You're using two queries for the same table, either you want both fields or just one? If you want both fields then just select both in one query:
SELECT post_title, post_content FROM wp_posts
I have been trying to get data from exploded values, but I am failing miserably and I am completely clueless despite all the researching I've been doing.
This is how the code looks like:
$array = explode(",", $hos['prop_owner']);
list($a) = $array;
$gu = $db->prepare("SELECT * FROM users WHERE user_id = :id");
$gu->execute(array(':id' => $a));
$dau = $gu->fetch();
echo $hos['prop_name']."<br><small>";
if(end($array)){
echo "<a href='/user/view/".$dau['user_id']."' style='color:#".$dau['user_colour']."'>".$dau['user_name']."</a></small><br>";
} else {
echo "<a href='/user/view/".$dau['user_id']."' style='color:#".$dau['user_colour']."'>".$dau['user_name']."</a>,";
}
Currently, the database field $hos['prop_owner'] contains the values "2,20" which are IDs of users (this field can potentially contain more IDs in the future). What I want to do is get all the user data from the exploded values, in this case 2 and 20, and then echo the information out in order as well.
Re-explanation:
I have a field in my database called prop_owner which is supposed to contain an unlimited number of user IDs, seperated by comma. Format: 1,2,3,4.
I want to take the value from this field, then somehow separate the user IDs and separately retrieve the usernames and echo them out.
Example result: Darren, Eva, Miles, Lisbeth
I hope I explained myself good enough to understand where I am trying to go with this.
Thanks in advance!
First of all the query will be like
SELECT * FROM users WHERE user_id in (2,20)
You need the data of both the users so the query will return all the data of all the ids that are being passed here..
You can directly pass here but you need to take care of security... or may be you can check how to pass values securely in such queries ...
I'm using WordPress, but this question is more pertaining to the SQL involved. I'll gladly move it if I need to.
I'm working on http://www.libertyguide.com/jobs and I'm trying to alter the filtering mechanics. Currently it's a global OR query.
Anyways, I have three filtering lists, and I'm storing what's selected into three strings (interests, type, experience) in the following way:
"( $wpdb->terms.slug = 'webdevelopment' OR $wpdb->terms.slug = 'journalism' OR ... ) AND"
It's populated by whatever is selected in my filtering lists.
When it comes down to it, I have this as a basic query (I'm leaving out the LEFT JOINS):
Before:
SELECT * FROM $wpdb->posts WHERE ($wpdb->terms.slug = 'fromlist1'
OR $wpdb->terms.slug = 'fromlist2' OR $wpdb->terms.slug = 'fromlist3')
AND $wpdb->term_taxonomy.taxonomy = 'jobtype'...
After:
SELECT * FROM $wpdb->posts WHERE
($wpdb->terms.slug = 'fromlist1' OR $wpdb->terms.slug = 'fromlist1again')
AND ($wpdb->terms.slug = 'fromlist2' OR $wpdb->terms.slug = 'fromlist2again')
AND ($wpdb->terms.slug = 'fromlist3' OR $wpdb->terms.slug = 'fromlist3again')
AND $wpdb->term_taxonomy.taxonomy = 'jobtype'...
So essentially I want to go from an
OR filter
to
an AND filter with OR filtering inbetween.
My new filtering only works when one item overall is selected, but returns nothing when I select more than one thing (that I know would match up with a few posts).
I've thought through the logic and I don't see anything wrong with it. I know nothing is wrong with anything else, so it has to be the query itself.
Any step in the right direction would be greatly appreciated. Thanks!
UPDATE
From the confusion, basically I have this:
"SELECT ...... WHERE $terms ..."
but I WANT
"SELECT ....... WHERE $interests AND $type AND $experience"
I don't want to have it filter $interest[1] OR $interest[2] OR $type[1] OR $experience[1], but instead want it to filter ($interest[1] OR $interest[2]) AND ($type[1]) AND ($experience[1])
I hope this makes more sense
*UPDATE 2*
Here's and example:
In my interests list, I select for example three things: WebDevelopment, Academia, Journalism.
In my type list, I choose two things: Fulltime, Parttime
In my experience list, I choose three things: Earlycareer, Midcareer, Latecareer.
When I run my query, I want to make sure that each record has AT LEAST one of each of the three lists. Possible Results: (WebDevelopment, Parttime, Midcareer), (Academia, Fulltime, Earlycareer, Midcareer).
NOT A RESULT: (Journalism, Earlycareer) - missing fulltime or parttime
I really hope this clears it up more. I'm willing to give compensation if I can get this working correctly.
Okay, I'll take a shot at this:
SELECT * FROM $wpdb->posts WHERE
(
$wpdb->terms.slug IN ('$interest1', '$interest2') AND
$wpdb->terms.slug IN ('$type1', '$type2') AND
$wpdb->terms.slug IN ('$exp1', '$exp2')
)
AND $wpdb->term_taxonomy.taxonomy = 'jobtype'
The IN keyword will return true if any member of the set matches.
I think you're looking for a WHERE category IN (comma, seperated, list, of, values) that you can generate dynamically from the form. If you combine it with the other categories, you can require them to select something from each with...
WHERE category1 IN (a, comma, seperated, list, of, values)
AND category2 IN (another, list, of, values)
AND ...
Which will only return a value if there is something selected from each category and will return nothing if any of the selection lists are empty; actually it may well kick out an error, so I would also generate the query dynamically if there is any content whatsoever for a given category.
if (!empty($arrayOfCategory1)) {
//sanitize input logic here
$Category[1] = 'category1 IN ('. implode(', ', $arrayOfCategory1) .')';
} else {
$Category[1] = '';
}
You concatenate the resultant string together and build the query with that. The WHERE 1=1 trick is problematic because if nothing is chosen, everything in the database will match, so I strongly recommend going through the process of adding the AND operators properly.
EDIT: it occurs to me that if you build the conditional statements as an array, you can implode those with ' AND ' and get the query in a fairly small number of lines of code.
Sort of confused a bit by what you are saying but if I wanted to build a filter I would be dynamically generating the SQL query based on the submitted filter values. Something like:
$sql = "SELECT * FROM $wpdb->posts WHERE 1=1";
if ( !empty($interest) ) { // they ticked the interested in ??? checkbox
$sql .= " AND $wpdb->terms.slug = $interest"
}
Obviously you will need to filter and escape any values that have been submitted.
I have 4 tables named wheels, tires, oil_change, other_servicing.
Now, I have an order form for the person that comes for a car checkup. I want to have all of these 4 options in a form. So say someone comes for new wheels but not for tires, oil change, and other servicing and they will leave the other fields blank. And then you might have a scenario where all four fields are filled up. So how do i submit each to their respective tables from that one form?
The form will submit to a single php script. In the php you must do 4 separate queries to put the data into the correct tables. For example if you have this in php:
$wheels = $_REQUEST['wheels'];
$tires = $_REQUEST['tires'];
$oil_ch = $_REQUEST['oil_change'];
$other = $_REQUEST['other_servicing'];
mysql_query("INSERT INTO wheels (wheels) VALUES $wheels");
mysql_query("INSERT INTO tires (tires) VALUES $tires");
mysql_query("INSERT INTO oil_change (oil_change) VALUES $oil_ch");
mysql_query("INSERT INTO other_servicing (other_servicing) VALUES $other");
Of course I don't know the schemas of your tables but this is just an example of how you have to split it into 4 queries.
However, I would suggest to you that rather than have 4 tables for this, just have one table and make each of these a column instead. There may be other details I don't know about which would necessitate separate tables but with the info you have given seems like it would be simpler.
This shouldn't present any problem. The PHP page that receives the form data can run as many queries as you want. The skeleton for the code would be something like:
if($_POST['wheels']) { //if they filled in the field for wheels...
mysql_query("insert into wheels...");
}
if($_POST['tires']) { //if they filled in the field for tires...
mysql_query("insert into tires...");
}
if($_POST['oil_change']) { //if they filled in the field for oil_change...
mysql_query("insert into oil_change...");
}
... etc
for each form you would have something like this:
if($_POST['wheels']){mysql_query("INSERT INTO wheel_table (column1) VALUES (" . 'mysql_real_escape_string($_POST['wheels']) . "')")
this checks if the form element has been set, or has a value, and if it does, it creates a new row in the corresponding table.
if the form element's name is not 'wheels', you'll have the change $_POST['wheels'] to $_POST['form_element_name'] and if the table's name is not wheel_table, you'll have to change that and same with the column name.
this all has to be wrapped in a
In the form action you will specify the php file that will process the form.
In the php script file you will make tests of what parts of the forms are used and inserted in the respective table.
Try to separate the tests and the inserts of each table, to be easier for you.
This could be useful
if(isset($_POST['submit'])) // assuming you have submit button with name 'submit'
{
$fields['wheels'] = isset($_POST['wheels']) ? $_POST['wheels'] : null;
$fields['tires'] = isset($_POST['tires']) ? $_POST['tires'] : null;
$fields['oil_change'] = isset($_POST['oil_change']) ? $_POST['oil_change'] : null;
$fields['other_servicing'] = isset($_POST['other_servicing']) ? $_POST['other_servicing'] : null;
$q="";
foreach($fieldsas $key=>$val)
{
if($val!==null)
{
$q="insert into ".$key." values('".mysql_real_escape_string($val)."')";
mysql_query($q);
}
}
if($q==="") echo " Please fill up at least one field !";
}
This is just the core idea, using this you can execute multiple queries if user submits more than one fields at once and you may have to add other values (i.e. user_id).
I have a table in MySQL with "text", "date_posted", and "user". I currently query all text from user=Andy, and call those questions. All of the other text fields from other users are answers to the most recent question.
What I want is to associate those answers with the most recent question, with a loop similar to "for each text where user=Andy, find the text where user!=Andy until date>the next user=Andy (question)"
This seems awfully contrived, and I'm wondering if it can be done roughly as I've outlined, or if I can save myself some trouble in how I'm storing the data or something.
Thanks for any advice.
EDIT: I've added in the insert queries I've been using.
$url = "http://search.twitter.com/search.json?q=&ands=&phrase=&ors=¬s=RT%2C+%40&tag=andyasks&lang=all&from=amcafee&to=&ref=&near=&within=1000&units=mi&since=&until=&tude%5B%5D=%3F&rpp=50)";
$contents = file_get_contents($url);
$decode = json_decode($contents, true);
foreach($decode['results'] as $current) {
$query = "INSERT IGNORE INTO andyasks (questions, date, user) VALUES ('$current[text]','$current[created_at]','Andy')";
mysql_query($query);
}
$url2 = "http://search.twitter.com/search.json?q=&ands=&phrase=&ors=¬s=RT&tag=andyasks&lang=all&from=&to=amcafee&ref=&near=&within=15&units=mi&since=&until=&rpp=50";
$contents2 = file_get_contents($url2);
$decode2 = json_decode($contents2, true);
foreach($decode2['results'] as $current2) {
$query2 = "INSERT IGNORE INTO andyasks (questions, date, user) VALUES ('$current2[text]','$current2[created_at]','$current2[from_user]')";
mysql_query($query2);
}
And then on the SELECT side, this is where I am currently:
$results = mysql_query("SELECT * FROM andyasks");
$answers = mysql_query("SELECT * FROM andyasks WHERE 'user' != 'Andy'");
while($row = mysql_fetch_array($results))
{
if ($row['user'] == 'Andy') {
print(preg_replace($pattern, $replace, "<p>".$row["questions"]."</p>"));
}
}
while($row = mysql_fetch_array($answers))
{
print(preg_replace('/#amcafee/', '', "<p>".$row["questions"]."</p>"));
}
What you have in mind could, I believe, be done with subtle use of JOIN or nested SELECT, ORDER BY, LIMIT, etc, but, as you surmise, it would be "awfully contrived" and likely pretty slow.
As you suspect, you would save yourself a lot of trouble at SELECT time if you added a column to the table, which, for answers, has the primary key of the question they're answering (that could be easily obtained at INSERT time, since it's the latest entry with user equal Alex). Then the retrieval would be easier!
If you can alter your schema this way, but need help with the SQL, pls comment or edit your answer to indicate that and I'll be happy to follow up (similarly, I'd be happy to follow up if you're stuck with this schema and need the "awfully contrived" SQL -- I just don't know which of the two possibilities applies!-).
Edit: since the schema's changed, the INSERT could be (using form :name to indicate parameters you should bind):
INSERT IGNORE INTO andyasks
(questions, date, user, answering)
SELECT :text, :created_at, :from_user,
IF(:from_user='Andy', NULL, aa.id)
FROM andyasks AS aa
WHERE user='Andy'
ORDER BY date DESC
LIMIT 1
i.e.: use INSERT INTO ... SELECT' to do a query-within-insertion, which picks the latest post by Andy. I'm assuming you do also have a primary keyid` that's auto-increment, which is the normal arrangement of things.
Later to get all answers to a given question, you only need to select rows whose answering attribute equals that question's id.
If I understand you correctly you want something like:
$myArr = array("bob","joe","jennifer","mary");
while ($something = next($myArr)) {
if ($nextone = next($myArr)) {
//do Something
prev($myArr)
}
}
see http://jp2.php.net/next as well as the sections on prev, reset and current