Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
Database queries are interpreted similar to mathmatical expressions. Operations are interpreted from left to right by precedence! That means there is an order to which certain interpretations are made. In math multiplication/divisions are done before addition/subtraction. However, you can override that logic per your needs using parenthesis. Example: 5 + 2 * 10 = 5 + 20 (multiplication done first) = 25 (5 + 2) * 10 = 7 * 10 (addition done first) = 70 Two completely different results with the same numbers and operations because of the parenthesis. Database queries are the same. I forget all of the order of operations for query operations, but I do know that ANDs and ORs are of equal precedence. So, they are interpreted from left to right, so you need to ensure you parenthesis them as needed. As the query is interpreted from left to right the parser decides if the current comparison and all the preceeding are TRUE or FALSE before it moves to the next condition. For example, let's say you wanted to query for all the boys who play football or basketball. You might think this query would work: WHERE gender='male' AND sport='football' OR sport='basketball' But that would find all boys who play football and ALL poeple that play basketball. When an AND is encountered the previous result must be true and the current comparison must be true. When an OR is encounterd the previous must be true or the current comparisson must be true. So, if a record does not match the gender 'male' or the sport 'football' the OR makes all of that inconsequential if the record matches the sport 'basketball'. The correct query would look like WHERE gender='male' AND (sport='football' OR sport='basketball') So the record would have to be male AND the record would have to have one of the sports 'football' OR 'basketball'
-
Woops! I was going to add another example where using curly braces is useful for array variables in a string, but decided not to at the last minute. So, disregard the array value in my example above as it has no consequence on the rest of the code.
-
You might want to have a look at the PHP manual for strings: http://php.net/manual/en/language.types.string.php Basically, when you use double quotes (or the heredocs method) to define a string, the PHP parser will interpret variables within the string. Here are a couple of examples: $foo = 'bar'; //Double quotes echo "The value is $foo"; //Output: The value is bar //Single quotes echo 'The value is $foo'; //Output: The value is $foo See the difference? When using variables within quotes I always use the curly braces. The braces help to avoid problems where the variable may be misinterpreted within the string. Examples: $foo = 'bar'; $array['index'] = 'somevalue'; echo "Variable adjacent to other 'text': $foo_underscore"; //Ouptut: Variable adjacent to other 'text': //The PHP is trying to parse the variable $foo_underscore which doesn't exist echo "Variable adjacent to other 'text': {$foo}_underscore"; //Ouptut: Variable adjacent to other 'text': bar_underscore //The curly braces define where the variable begins and ends for the PHP parser
-
Why would you not want to use the ternary operator? It is the perfect solution when you need to set a variable to one of two values based upon a condition. Here is the same code with comments added //Array of values for the select list $optionList = array('apple', 'orange', 'banana', 'pear'); //Variable to hold the html for the options $fruitOptions = ''; //Assign the selected value (if it was set) $selectedValue = (isset($_POST['fruit'])) ? $_POST['fruit'] : false; //Iterrate through each option (uses the index key as the actual value) foreach($optionList as $value => $label) { //Set the $selected variabled based on whether the selcted option equals the current option $selected = ($value === $selectedValue) ? 'selected="selected"' : ''; //Add the html for the current option to the options variable $fruitOptions .= "<option value=\"{$value}\"{$selected}>{$label}</option>\n"; } EDIT: Made one change. Changed the double equal to a triple equal. The reason for doing so is that I set the $selectedValue to false if the POST value was not set. The problem was that if there is an option with a value of 0, then false would compare to 0 using double equal comparison. This isn't a problem with this particular example since 0 would be the first value. But, if there was a situation where 0 could be the 2nd or later option, then that value would be preselected even if the user did not submit a value. I think it was overkill in the sense that there was more going on than just preselecting a value. I suspect offset gap part of the code would cause more confusion than clarification.
-
That is way more complicated than it needs to be. The key is to have a defined "list" of values. This can be from a database query or from a hard-coded array. Here is a simple example: $optionList = array('apple', 'orange', 'banana', 'pear'); $fruitOptions = ''; $selectedValue = (isset($_POST['fruit'])) ? $_POST['fruit'] : false; foreach($optionList as $value => $label) { $selected = ($value == $selectedValue) ? 'selected="selected"' : ''; $fruitOptions .= "<option value=\"{$value}\"{$selected}>{$label}</option>\n"; } Then where you have the select list in the body of your page <select name="fruit"> <?php echo $fruitOptions; ?> </select>
-
So, are you asking for a workaround? Your last post was just a statement, so I'm not sure. Anyway, IE doesn't recognize the type property, plain and simple. So, there is no way to dynamically change the type of an input field in IE. The only solution, which is a messy one, is to use two sets of fields. One set is password fields and the other is text fields. Then hide one set while displaying the other. Of course you will need to ensure that the values remain the same between both sets as well. Here is a working solution. I did some testing and didn't find any problems. <html> <head> <script type="text/javascript"> function togglePass() { var dispTxt; var i = 1; while (document.getElementById('pass'+i) && document.getElementById('text'+i)) { var textObj = document.getElementById('text'+i); var passObj = document.getElementById('pass'+i); //Determine which field is displayed dispField = (textObj.style.display=='inline') ? 'text' : 'pass'; //Swap displayed/hidden fields textObj.style.display = (dispField=='text') ? 'none' : 'inline'; passObj.style.display = (dispField=='pass') ? 'none' : 'inline'; i++; } return; } function copyInput(fieldObj) { var fldID = fieldObj.id.substr(4); var src = (fieldObj.id.substr(0,4) == 'text') ? 'text' : 'pass'; var tgt = (src == 'text') ? 'pass' : 'text'; document.getElementById(tgt+fldID).value = document.getElementById(src+fldID).value; return; } </script> </head> <body> Field 1: <input type="text" value="123" id="text1" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass1" onchange="copyInput(this);" /><br /> Field 2: <input type="text" value="123" id="text2" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass2" onchange="copyInput(this);" /><br /> Field 3: <input type="text" value="123" id="text3" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass3" onchange="copyInput(this);" /><br /> Field 4: <input type="text" value="123" id="text4" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass4" onchange="copyInput(this);" /><br /> Field 5: <input type="text" value="123" id="text5" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass5" onchange="copyInput(this);" /><br /> Field 6: <input type="text" value="123" id="text6" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass6" onchange="copyInput(this);" /><br /> Field 7: <input type="text" value="123" id="text7" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass7" onchange="copyInput(this);" /><br /> Field 8: <input type="text" value="123" id="text8" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass8" onchange="copyInput(this);" /><br /> Field 9: <input type="text" value="123" id="text9" style="display:none;" onchange="copyInput(this);" /> <input type="password" value="123" class="text" id="pass9" onchange="copyInput(this);" /><br /> <button onclick="togglePass();">Toggle</button> </body> </html>
-
You're right, it is messy - but it doesn't work or else you would not be here. If you write your code in a logical format it will be less error prone and will be easier to read/review. All those nested if/else statements are a bear to understand. But, that is the current problem. You simply have an IF statement for when there is a username match. After that the code continues on just the same if there wasn't a match. Putting your validations in a more linear model makes more sense. Also, your code quits validating after the first error condition. While this makes sense if they have not entered all the information, why would you not alert the user to an invalid email address if the email is already in use (do you even see the illogical problem there?) Do all the easy validations first - leave database validations for the last part. And, keep it all in a logical sequence <?php if($_SERVER['REQUEST_METHOD'] == 'POST') { //Parse the input values $username = trim($_POST['username']); $password1 = trim($_POST['password1']); $password2 = trim($_POST['password2']); $email = trim($_POST['email']); $rights = trim($_POST['rights']); $ipaddress = trim($_POST['ipaddress']); $errors = array(); if(empty($username) || empty($password1) || empty($password2) || empty($email) || empty($rights) || empty($ipaddress)) { $errors[] = 'You left one or more fields blank.'; } else { if (preg_match('/[a-z0-9-\s]{3,13}/i', $username)==0)) { //Validate username format $errors[] = 'ERROR: Invalid username. Your username can only contain Numbers and Letters, and be 3-13 characters in length.'; } if($password1 != $password2) { //Validate passwords match $errors[] = 'ERROR: Passwords do not match.'; } else if(preg_match('/[a-z0-9]{3,13}/i', $password1)==0) { //Validate password format $errors[] = 'ERROR: Invalid password. Your password can only contain Numbers and Letters, and be 3-13 characters in length.'; } if(!is_numeric($_POST['rights'])) { //Validate rights $errors[] = '<p class="info" id="error"><span class="info_inner">ERROR: Undefined rights.</span>'; } if(count($errors)==0) { //Format validations passed validate unique username and email adress $query = "SELECT username, email FROM users WHERE username='".realEscape($username)."' OR email='".realEscape($email)."'"; $result = mysql_query($query); if(mysql_num_rows($result) > 0) { $found = mysql_fetch_assoc($result); if($found['username']==$username) { $errors[] = 'ERROR: The username is already in use!'; } if($found['email']==$email) { $errors[] = 'ERROR: The email is already in use!'; } } } } //Check if there were any validation errors if(count($errors)>0) { echo "<p class=\"info\" id=\"warning\"><span class=\"info_inner\">The following errors occured:<ul>\n" foreach ($errors as $error) { echo "<li>{$error}</li>"; } echo "</ul></span></p>\n"; } else { //No errors occured, insert record $query = "INSERT INTO users (username, password, rights, ipaddress, email, date) VALUES ('".realEscape($username)."', '".encrypt($password1)."', '".realEscape($rights)."', '".realEscape($ipaddress)."', '". realEscape($email)."', NOW())"; mysql_query($query); echo '<p class="info" id="info"><span class="info_inner">The account has been created.</p>'; } } ?>
-
No difference. I don't like the look of code that concatenates variables how you had it. Besides, when using double quotes, the PHP parser will interpret variables in the string. If you are going to exit out of the string to concatenate a variable, why use double quotes. You can just put the variable inside the double quotes, but enclosing them in curly braces helps alleviate certain problems - such as using arrays. The code I posted create a loop where YOU can insert the code for displaying the results. I don't know how you want to display them so I left it out. But, here is one example where each result is displayed on a separate line. I also added code to display the number of records returned. $query = "SELECT `search2`FROM `search` WHERE `search1`='%{$search}%'"; $result = mysql_query($query); if(mysql_num_rows($result)==0) { echo "There were no results."; } else { echo "There were " . mysql_num_rows($result) . " records found:<br />\n"; while($row = mysql_fetch_assoc($result)) { echo " - {$qry['search2']}<br />\n";; } }
-
The problem could be a couple of different places. Youshould validate the actual content in the database and the content in the HTML page. Just because you can't "see" the text in the web page doesn't mean it is not there. Check the HTML page source to see if the content is there. The problem might be with the content being interpreted as HTML code. If that is the case you will need to use something like htmlentities() to convert the HTML code characters to their character code equivalents.
-
Uh, not at all. You just need an appropriate query using the right JOIN/GROUP BY parameters. Really, we cannot answer this question for you. It all depends upon exactly what features your forum will contain. Also, don't forget the user table!
-
$query = "SELECT `search2`FROM `search` WHERE `search1`='%{$search}%'"; $result = mysql_query($query); while($row = mysql_fetch_assoc($result)) { //Include code to output results for each record }
-
This is a good example of where the ternary operator would be useful: function togglePass() { var i = 1; while (document.getElementById('pass'+i)) { var obj = document.getElementById('pass'+i); obj.type = (obj.type=='text') ? 'password' : 'text'; i++; } } NOTE: IE does not recognize the type property.
-
Um, which variable are you referring to? There are two variables in the code you posted: 'params' and 'id'. But, to elaborate on MrAdam's post, that line instanciates a new variable ('params') and set's it to a string value consisting of the string 'id=' and the value of the variable 'id'. SO, if the variable 'id' was set to the value '23', then the variable 'params' would contain the string 'id=23'
-
The second code is closer to what you want. Remember, that code would flag a post as a duplicate even if the first one was made years in the past. If you want to allow someone to post the same thing after a certain amount of time you would want to add an additional parameter to the WHERE clause to find matches that are "recent", i.e. posts that have been created in the last day, week, whatever.
-
So, again, my question is "which" category ID do you want used when the post is associated with multiple categories? It seems like you are trying to reverse engineer some 3rd party application. I will say it again - you do NOT need to pass the category ID on the query string. It is even more irrelevant when a post can be associated with multiple categories. On the page that displays the post you would just do a query to get the associated categories: include('leftbar.php');// Here comes the post data from above url of post id 5 //Run query to get the associated categories $query = "SELECT catid FROM `post_category` WHERE postid = '{$_GET['post']}'"; $result = mysql_query($query); $catIDs = array(); while($row = mysql_fetch_assoc($result)) { $catIDs[] = $row['catid']; } //You now have an array of all the associated category IDs. //You can then use those values in the rightbar.php page include('rightbar.php'); // in this page i hv code to use $_GET['cat'] to display related posts
-
Queries do not return true/false. (Well, the result is false if the query fails, but that is not what you would normally expect). Queries return record sets. The "sample" query above would return a record set of all the records that match the WHERE criteria. Namely, and posts that have the same user ID and the same post content. You would then check the result set to see if the count is >1 (the user has submitted posts with the exact same content) or 0 (the user has never submitted a post with that exact same content). So, you would need to check the count of the results and react accordingly.
-
Huh? I'm not following. If you are clicking a link to access a post, why do you need a category ID associated with that link? On the page that displays the post you can determine what category or categories the post is associated with and display related posts accordingly. There is no need to pass it on the query string to access the post. Besides, as I stated above, how would you determine what category ID to use on the query string when a post is associated with more than one category.
-
To prevent a user fromposting the exact same content just do a simple query such as SELECT id FROM posts WHERE userID = '$userID' AND posttext='$posttext' Of course a user may post the exact same content legitimately, such as a canned response for a common question. Another solution people use is to implement a wait period before a user can post another message. In that case you would just query for the timestamp of the most recent post by the user. If not enough time has elapsed don't add the post and give the user an appropriate message.
-
To get the product totals in order of amount (highest to lowest) you would do a query such as this: SELECT product_name, SUM(product_cost) as product_total FROM tableName GROUP BY product_cost ORDER BY product_total DESC Then when processing the record set you could add up the totals for the other items. Alternatively you could set a limit on that query to only get the top three products and do a second query to get the grand_total (either excluding the top three or subtracting the top three totals after you get the results). As for creating a pie chart, there are many solutions available. Just do a google search for "PHP Pie Chart".
-
Well, you can reference characters in a string the same way you reference elements in an array. So the simplest solution would be to simply define a string with all the characters $array = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; However, if you need to keep it as an array construct and/or need it to be done programatically, then this might be more efficient $array = array_merge(range(97, 122), range(65, 90)); $array = array_map("chr", $array); However, there are many different possible solutions and I can't say which would be more efficient without testing.
-
The simple answer is don't use a JOIN on the category table when doing a search. But, that seems problematic because of the dependency on the category ID you are using in the link. Why do you need the category ID included in the link? That really doesn't make sense to me. If it IS required then what logic are you going to use to determine which category ID to use for a post when it is associated to multiple categories? I think you should remove the dependency on including the category ID in the URL and remove the JOIN on the search query.
-
No, that is what you think you want. But, that is not how you are going to get records returned from the database. You just need to process the db results to display the records accordingly. So, let's assume you are getting the results for a single post and getting back three records because the post is associated with three categories as in the above example. Then let's assume you want to display the post something like this: My First Post This is a test post Categories: Gaming, Discussion, Community Then your PHP code for processing the db results might look something like this: //Run the query $query = "SELECT p.posttitle, p.postbody, c.catid, c.catname FROM `Post` as p JOIN `post_category` as pc ON p.id = pc.postid JOIN `Categories` as c ON c.id = pc.catid WHERE p.id = '$postID'"; $result = mysql_query($query) or die(mysql_error()); //Generate the output $output = ''; if(mysql_num_rows($result)<1) { $output .= "No post found with that ID."; } else { //Parse the db results $category_links = array(); while($row = mysql_fetch_assoc($result)) { $category_links[] = "<a href=\"showcategory.php?catid={$row['catid']}\">{$row['catname']}</a>"; } //Create the HTML output $output .= "<b>{$row['posttitle']}</b><br />\n"; $output .= "<p>{$row['postbody']}</p><br />\n"; $output .= "<p>Categories: </p>" . implode(', ', $category_links); } echo $output;
-
To get a post record alonw with the associated category names, your query would look something like this: SELECT p.posttitle, p.postbody, c.catname FROM `Post` as p JOIN `post_category` as pc ON p.id = pc.postid JOIN `Categories` as c ON c.id = pc.catid WHERE p.id = '$postID' When getting multiple associated records like this, you will need to process the results. If the post was associated with three categories, the result set will include three records with the post data repeated three times. Something like this: posttitle | postbody | catname ================================================ My First Post This is a test post | Gaming My First Post This is a test post | Discussion My First Post This is a test post | Community
-
If you don't know how to do that then you should read up on database queries. But for a generic answer you would need to do two queries to insert records and do a join when retrieving your records. Example script to add a new record. This assumes the form will have the following input fields: post_title, post_body and an array of checkboxes named "categories[]" where each checkbox has the id of the different categories (note I am not including any code to validate/cleanse teh input for brevity): //insert the post record $query = "INSERT INTO `Post` (`postbody`, `posttile') VALUES ($_POST['post_title'], $_POST['post_body'])"; mysql_query($query); //Get the inserted record id $postID = mysql_insert_id(); //Insert the array of categories as individual records $values = array(); foreach($_POST['categories'] as $catID) { $values[] = "($postID, $catID)"; } $query = "INSERT INTO `post_category` (`postid`, `catid`) VALUES " . implode(', ', $values[); mysql_query($query); Sample query to select all the posts associated with a particular category SELECT * FROM `Post` as p JOIN 'post_category` as pc ON p.id = pc.postid WHERE pc.catid = $searchCategoryId
-
If you want to assign multiple categories then you need to remove the 'catid' field from the Post table and instead use an intermediary table to associate posts to categories: Categories table: id, catname Post Table: id, postbody, posttile, date post_category table postid, catid You would have one record for each post to category assignment. For example a post that is associated with three categories would require three records in the post_category table.