Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
Again, you still have not provided the needed information. Is the error being generated by the INSERT statement? $ins="INSERT INTO post(topicsID,post_content,post_by)VALUES('$hidden','$comment','$name')"; If so, then one of those fields is set as a primary key and must be unique. I suspect it is the "topicsID" field. So, if the intent is to allow multiple records associated with the same topic ID then that field should not be a primary or unique field.
-
Well, you haven't really provided any information. You need to state what is causing the error. What you have tried and what the results were. I *assume* your problem is due to the insert query. It looks like you have a form for updating records - which includes a hidden field for the primary key of the record. But, you are taking that information and trying to run an INSERT query instead of an UPDATE query. If you want to INSERT a new record then you should not provide the primary key value - that should be automatically done by the database if the field is an auto-increment field
-
Does blank space really matter in performance?
Psycho replied to Ivan Ivković's topic in PHP Coding Help
Although I have no definitive proof I would agree. The PHP engine would only parse the file once. So, if you have a loop in your code the spaces/comments in that loop are only interpreted once upon file load and would have no effect when the loop actually runs. Unless there is a ton of code that is being processed I don't think that extra white-space or comments would make any perceptible difference (for the most part). However, when you get into situations with sites with extremely high levels of usage (think facebook/google) then saving even a tenth or one hundredth of a second on a page load can have an impact on the number of servers you deploy. But, if you really want to check it out for your self - test it. If you find you want to go that route you still don't want to "build" your files without white-space and comments. Instead, you would find/build a utility to strip that content out for you. So, you would maintain the original code with the white-space/comments for development purposes. Then, you would run the files through the utility to remove that content before deploying it to your production environment. However, I suspect there are probably other inefficiencies in your code that would have a greater impact in performance than white-space and comments. That's not to knock your code - I'm sure that's the case in my own code even though I consider myself pretty vigilant to trying to make efficient code. -
When creating a process such as this it is typically a best practice to do one thing, check your results, then do the next thing. Since you already had per-existing code what I provided was pretty much a full solution except for the final output. You should add some debugging code at specific points to validate that the results up to that point are correct. The first thing I would do is echo out the query then run it in PHPMyAdmin to ensure the results are what I expect. Next, I would add an echo inside the while loop to output each record to verify that it matched the results I got in PHPMyAdmin Third, I would add a print_r() on the array before and after the code to shuffle() the array. Then, just find out where the debugging output does not match what you expect. Determine the cause and fix it. Here is the code with some debugging lines added <?php //Connect To Database $hostname=""; $username=""; $password=""; $dbname=""; $question_table="wp_mtouchquiz_question"; $answer_table="wp_mtouchquiz_answer"; $yourfield = "question"; $question = "question"; $answer = "answer"; $connection = mysql_connect($hostname, $username, $password); $lastQuestionID = -1; $str = ""; mysql_select_db($dbname, $connection); if(!$connection) { die('Unable to connect to database server.'); } if(!mysql_select_db($dbname, $connection)) { die('Unable to select database.'); } //Query for questions/answers $question_table="wp_mtouchquiz_question"; $answer_table="wp_mtouchquiz_answer"; $query = "SELECT q.id, q.question, a.answer FROM {$question_table} q JOIN {$answer_table} a ON q.ID = a.QUESTION_ID WHERE q.quiz_id = 1 ORDER BY question_id ASC, correct DESC"; $result = mysql_query($query); ## DEBUGGING LING ## echo "Query: {$query}<br> Num Records " . mysql_num_rows($result) . "<br><br>\n"; if(!$result) { //die ('Unable to get questions.'); //Comment out to debug die("Query: $query<br>Error: " . mysql_error()); } //Populate results into multi-dimensional array $questions = array(); while($row = mysql_fetch_assoc($result)) { ## DEBUGGING LING ## echo implode(" : ", $row) . "<br>\n"; if(!isset($questions[$row['question_id']])) { $questions[$row['question_id']] = array( 'question' => $row['question'], 'question_id' => $row['question_id'], 'answers' => array() ); } $questions[$row['question_id']]['answers'][] = $row['answer']; } ## DEBUGGING LING ## echo "Array before randomizing:<br><pre>" . print_r($questions, true) . "</pre><br>\n"; //Randomize the questions and answers shuffle($questions); foreach($questions as &$question) { unset($question['answers'][rand(1, 4)]); // <== This will remove one of the incorrect answers before randomizing shuffle($question['answers']); } ## DEBUGGING LING ## echo "Array after randomizing:<br><pre>" . print_r($questions, true) . "</pre><br>\n"; //NOW output the results //The following is just in plain HTML for testing, but you can change to JSON foreach($questions as $q) { echo "<b>{$q['question']} (ID:{$q['question_id']})</b><ul>"; foreach($q['answers'] as $a) { echo "<li>{$a}</li>\n"; } echo "</ul><br><br>\n"; } ?>
-
OK, if I understand you correctly, the player's picks only need to match the winning pic number - regardless of order. Also, you say you do want to give the players a smaller payout if they match two numbers. But, we are back at a problem. What if a user has 10 picks and 3 of those picks match 2 numbers? Shouldn't that user get the small payout multiplied by 3. The problem is you are trying to count the matches across ALL the picks. Instead you need to do the matches for each pick individually. I still believe you have not worked out all the logic of how you want this to operate and are trying to do it as you go. But, here is an example of a possible solution based upon some rules I will set. - Winning draw will consist of three random numbers - Users may purchase as many "picks" as they want (consisting of three different numbers) - Winning: - A match of any two numbers will win 5 units - A match of all three numbers will win 100 units Based upon those rules I would create a function to return the combined results of all the user submissions: how many matched 0, how many matched 1, etc. THEN create another process to determine the winnings. Building upon the code I previously posted here is an example script function getResults($draw_pick_str, $user_picks_str) { $resultsAry = array(0=>0, 1=>0, 2=>0, 3=>0); //Convert data into arrays and process $draw_pick_ary = explode('|', $draw_pick_str); $user_picks_ary = explode(',', $user_picks_str); foreach($user_picks_ary as $user_pick_str) { $user_pick_ary = explode('|', $user_pick_str); $matches = count(array_intersect($draw_pick_ary, $user_pick_ary)); $resultsAry[$matches]++; } return $resultsAry; } $winning_numbers = "2|18|3"; $numbers_chosen = "8|18|3,8|18|3,5|8|12,1|18|22"; $payouts = array(0, 0, 5, 100); $results = getResults($winning_numbers, $numbers_chosen); $total_winnings = 0; foreach($results as $matches => $count) { $winnings = $payouts[$matches] * $count; $total_winnings += $winnings; echo "You had {$count} picks that matched {$matches} numbers, winning {$winnings} gold.<br>\n"; } echo "<br>Your total winnings are {$total_winnings} gold.";
-
As I suspected as a possible cause, you query is failing. Could be a simple typ0 in a field name or something. You will need to check for the error and fix accordingly. Change the line that runs the query as follows to get some more info to debug the problem $result = mysql_query($query); if(!$result) { //die ('Unable to get questions.'); //Comment out to debug die("Query: $query<br>Error: " . mysql_error()); } As for the 4 questions vs. 5, MySQL is not very efficient at randomizing results. I would still follow the a similar process as before but when processing the array of results I would remove one of the incorrect answers. This would only require one additional line of code in what I provided previously //Randomize the questions and answers shuffle($questions); foreach($questions as &$question) { unset($question['answers'][rand(1, 4)]); // <== This will remove one of the incorrect answers before randomizing shuffle($question['answers']); }
-
The basic syntax of the control structures (if, while, etc.) is just a single line of code after the control structure with no braces. You only need the braces if you have multiple lines to be associated with the control structure. (see this reference: http://us3.php.net/manual/en/control-structures.while.php) I don't think the same applies for functions. But, I ALWAYS use the braces with indenting of code to make my scripts easy to read/analyze There is also a third option: http://us3.php.net/manual/en/control-structures.alternative-syntax.php
-
Start by forgetting about the JSON requirements. First build your script such that you know you have the right data THEN format the data accordingly. I see a lot of things in that code that could be improved/corrected. here are a few: - You have no error handling for the DB operations. Your query could be failing for all you know. - The query is ordering results based upon the correct question - why? For the purposes of generating the test you don't need to know which one is correct or not. That takes place when the answers are submitted. - Don't use '*' in your select statement, only query the fields you need. There is a pretty simple solution. Just populate the data into an array, then use shuffle() to randomize the questions/answers. Here is an example: //Connect To Database $hostname=""; $username=""; $password=""; $dbname=""; $connection = mysql_connect($hostname, $username, $password); if(!$connection) { die('Unable to connect to database server.'); } if(!mysql_select_db($dbname, $connection)) { die('Unable to select database.'); } //Query for questions/answers $question_table="wp_mtouchquiz_question"; $answer_table="wp_mtouchquiz_answer"; $query = "SELECT q.question_id, q.question, a.answer FROM {$question_table} q, JOIN {$answer_table} a ON q.ID = a.QUESTION_ID WHERE q.quiz_id = 1 ORDER BY question_id ASC, correct DESC"; $result = mysql_query($query) or die('Unable to get questions.'); //Populate results into multi-dimensional array $questions = array(); while($row = mysql_fetch_assay($result)) { if(!isset($questions[$row['question_id']])) { $questions[$row['question_id']] = array( 'question' => $row['question'], 'question_id' => $row['question_id'], 'answers' => array() ); } $questions[$row['question_id']]['answers'][] = $row['answer']; } //Randomize the questions and answers shuffle($questions); foreach($questions as &$question) { shuffle($question['answers']); } //NOW output the results //The following is just in plain HTML for testing, but you can change to JSON foreach($questions as $q) { echo "<b>{$q['question']} (ID: {$q['question_id']})</b><ul>\b"; foreach($q['answers'] as $a) { echo "<li>{$a}</li>\n"; } echo "</ul><br><br>\n"; }
-
You can't hurt a database with spaces. Furthermore, simply removing spaces is not going to prevent SQL injection. To do that, you need to use mysql_real_escape_string() which will escape harmful characters (like quotes) before they interact with the database. To add to that. As I stated above "trimming" spaces IS a standard practice. But, trimming (using the trim() command) only removes white-space characters before and after non-white-space characters. White-space characters are things such as spaces, tabs, line breaks etc. It is NOT standard practice to remove spaces within the value. Plus, the purpose of trimming has nothing to do with protecting the database. It is characters such as quote marks, '*' and some others that could cause a problem. but as scootstah stated using mysql_real_escape_string() will prevent any problems (or using prepared statements). When dealing with user input you need to know exactly why you are doing what you are doing. If you need to restrict certain input know what you are doing that and provide appropriate feedback to the user. It is a bad idea to automatically change the user input without the user knowing. There is no general reason to restrict input for normal "text" values (names, addresses, etc.). So, analyze what the input is for to determine if there is a need. For example, if the input should be numeric, then you obviously want to ensure it doesn't contain letters - same goes for dates. However, if you are allowing the user to enter text that would be displayed in a web-page then you also need to prevent problems if the data has HTML code. It is true that you could strip_tags() on the input before saving it - but that is again modifying the input without the user's knowledge. So, if you don't want to allow them you can validate for it first then not allow the input. Or, you can simply allow the input and instead transform the data so it will still display the original user input but not be interpreted as HTML code using htmlspecialchars().
-
The decision to use a 3rd party calendar or build your own should simply be based upon your requirements: 1. Need to create large number of calendars in a day 2. Need to be able to access/manage calendars internally (i.e. the rest of your site) 3. Need ability to sync with other calendars Requirement #3 is really met if you already meet requirement #2. But, it is worthwhile to know if a 3rd party calendar already has integration with the other calendars you need to sync with or if you will have to build your own integration code. If you can find a 3rd party script that meets requirements #1 & #2 that has all the features you want then that would save you a ton of time. Even if it doesn't integrate with the other calendars that is something you would have had to build on your own anyway.
-
You are doing a very poor job of explaining your needs and/or you really don't have a solid understanding of what you are exactly doing. Based upon your last comments a user's picks is only a jackpot winner if they have a pick that has the same numbers - in the same order. But, do you have other types of winners based upon some matching numbers and some matching positions? You really need to be comparing each user pick individually. But, if you only have one type of winner (jackpot) and you just want something to give the user some info regarding how close they were to winning, then what you are requesting kinda makes sense. I would probably create a function to return "true" if one of the picks was an exact match otherwise return a number of the pick with the most matches. But, I am reluctant to provide any more code without some better explanation of what you think you are doing.
-
Here is my take on a rewrite. I've added some comments to hopefully explain the logic flow <?php //Include this function on BOTH the registration and login scripts function saltedPassword($password, $salt) { return md5($password . $salt); } session_start(); //Check if user is already logged in if(isset($_SESSION['logged_in'])) { //Return control back to calling script return true; } else { $error_msg = ''; //Check if login form was submitted if (isset($_POST['username'])&& isset($_POST['password'])) { //Preprocess the input $username = trim($_POST['username']); $password = trim($_POST['username']); //Validate data $errors = array(); if(empty($username)) ( $errors[] = "Username is required."; ) if(empty($password)) { $errors[] = "Password is required."; } //If validations passed, attempt authentication if(!count($errors)) { $query = sprintf("SELECT salt, password FROM users WHERE username = '%s'", mysql_real_esacpe_string($username)); $result = mysql_query($query); if(mysql_num_rows($result)) { $user_data = mysql_fetch_assoc($result); if(saltedPassword($password, $user_data['salt']) == $user_data['password']) { //Authentication passed $_SESSION['logged_in'] = 1; return true; } } //Authentication did not pass $errors[] = "Password and/or Username are invalid!"; } } if(count($errors)) { $error_msg = "The following errors occured:<ul>\n"; foreach($errors as $err) { $error_msg .= "<li>{$err}</li>\n"; } $error_msg .= "</ul>\n"; } } ?> <html> <body> <?php echo $error_msg; ?> <form action="<?php echo $current_file; ?>" method="POST"> Username: <input type="text" name="username" /><br> Password: <input type="password" name="password" /> <input type="submit" value="Login" /> </form> </body> </html>
-
Here are my comments: if(!empty($_POST['username'])){ $T_user = strip_tags($_POST['username']); $user = str_replace(' ','',$T_user); }else{ $user = false; } You should always trim() user input before doing any empty() validations. Otherwise an entry of nothing but spaces would pass this validation but would result in empty strings being inserted for the value in the DB!!!. Also, I agree with the above statement. trim()ing a value is a standard practice, but if you are going to do more intensive manipulations (removing inner spaces, tags, or other data) then you need to generate an error and let the user fix the problems. You *could* just do the same manipulation when the user logs in, but that's really not a good solution. EDIT: A further note on manipulating input. Since this is the login form and not the page where the user "creates" there username/password you should do absolutely NO data manipulation [with the exception of trim()]. If you don't allow the character '@' (for example) in usernames then you would only have an error condition for that when the user tries to create their account. On the login page you don't need an error condition since there would be no valid username with '@'. The only person using it would be someone trying to gather information or trying to luck into a valid account./EDIT Also, there is absolutely NO reason to remove/change characters in a password. The value will be converted to a hash anyway. Let the user enter whatever they want. By removing characters you are only making the ultimate value less secure. For example, let's say a user creates their password using "<b>password</b>". Your code would strip out the tags and the user would be left with "password". //Generate SALT and encrypt// $salt = 'angelinajolie'; $pass = md5($T2_pass.$salt); }else{ $pass = false; } The salt should be something unique to the user that does not change. Otherwise if a malicious user was to get your hashing method above they would have to only generate one lookup table of hash values and they could use that on every user's hashed password. If you instead used a different salt for each user then a malicious user would have to generate an entirely different lookup table to try and backward engineer each password. You can use any existing data that will not change (user ID, date joined, etc) or generate an entirely new value for the salt and store it in the database for each user. Your successful login needs to do something more such as setting a session value to use on subsequent page loads so you know the user is logged in. Otherwise, the login accomplished nothing. Instead, you should create this script to first check if the user is logged in. If not, then display the form or authenticate. You could then call this script on every page load. If the user is logged in then the original page would display. If not, then the user will go to the login process. EDIT#2 Also, you should create a function for your salting process because you need to use it both on the account creation process and the login process. You don't want to have two sets of code for that as it would be too easy to accidentally make a small difference that could cause problems later.
-
This topic has been moved to Miscellaneous. http://www.phpfreaks.com/forums/index.php?topic=352526.0
-
What you are asking for makes absolutely no sense based upon the ultimate goal. You are allowing the user to submit multiple picks (3 numbers each) for a lottery draw. You wouldn't count how many matches there are across all the picks - you need to know how many matches there are in each single pick. Let's say the winning numbers are 3, 8, 18 If a user has two picks of 8, 18, 20 AND 5, 8, 18 there are four total matches. But, that really doesn't tell you if either pick was a winner or not. For example, what if the user's two picks are 3, 8, 18 AND 5, 8, 12. Again, there are four matches total for both picks. But, the first pick was an exact match. Plus, you have said nothing about whether the position of the numbers is relevant to a match or not. Besides you are making this way more difficult than it needs to be. The data should already be in arrays rather than a string. There are many array functions that can be used without having to loop through each individual record. The following will do EXACTLY as you requested - even though I don't think it is what you really want. It will return the number of matches across ALL the user picks (whether that is one pick or many) for a single winning draw. This code does NOT consider the positions of the numbers in the picks/draw for the purposes of a match. function getMatches($draw_pick_str, $user_picks_str) { $matches = 0; //Convert data into arrays and process $draw_pick_ary = explode('|', $draw_pick_str); $user_picks_ary = explode(',', $user_picks_str); foreach($user_picks_ary as $user_pick_str) { $user_pick_ary = explode('|', $user_pick_str); $matches += count(array_intersect($draw_pick_ary, $user_pick_ary)); } return $matches; } $winning_numbers = "2|18|3"; $numbers_chosen_str = "8|18|3,5|2|3"; echo getMatches($winning_numbers, $numbers_chosen_str); //Output: 4
-
You didn't answer my questions. An input field does not create '\r\n' tags. Again, are you saying the input contains actual line breaks are are you actually seeing the characters '\r\n'? And, what was that last block of code you posted? Was that a list of attempts to manipulate the input or is that code you have in place before you try and do the matching? You do realize that '\r\n' (in single quotes) is entirely different than "\r\n" (in double quotes), right? When you put those into single quotes it means the literal characters "\" "r" "\" "n". However, when you put those in double quotes it represents line break characters.
-
The code I provided worked based upon the EXACT data you supplied above. That is why I prefaced my response as I did. I suspect there is something else going on that you are not aware of and so the information you are providing is not accurate. Additionally the line that you say works might be a clue $user_description = str_replace(array("\r","\n",'\r','\n'),' ', $user_description); The escape characters in double quotes match the special line break characters which could be sent from a textarea input. But, the ones in the single-quotes are the literal text '\n' and '\r'. If your submitted descriptions have the literal characters '\r' and '\n' then something is wrong with your input. You shouldn't "see" those actual characters (unless you are actually entering them). So, you need to fix what is causing those to show up. What is that last block of code supposed to be? If that is your process of sanitizing the data you are definitely making it more complicated than it should be. But, I think your problem is this line $user_description = trim_chars('$user_description', '\r\n'); If that line is supposed to be replacing something with a line break it is actually replacing it with the literal characters '\r\n'.
-
How can I make this flow control statement more efficient?
Psycho replied to APD1993's topic in PHP Coding Help
To get the final sum this is all you need $first = 1; $last = 100; $sum = (($last - $first + 1) * ($first + $last)) /2; echo "Sum: {$sum}"; This adds all the consecutive numbers between the start number to the last number, i.e. 1 + 2 + 3 + . . . + 98 + 99 + 100 = 5050 -
How can I make this flow control statement more efficient?
Psycho replied to APD1993's topic in PHP Coding Help
The if() statement is unnecessary. The while() loop will ensure that $num will be >99 before it gets past the while. But, I don't think that loop is even necessary. Let me see if there is a math function to do that addition automatically. -
You are not still using the CAST() are you?
-
Sorry, but absolutely don't follow that advice. Security should never be achieved through obfuscation. And, cookies is a bad choice since they can be modified by the users. The solution is simple. Whenever someone logs in simply set a session variable. Then you would use that value for two things: 1. On the menus/links you display you would use that value to determine whether you will display the links to the download page 2. On accessing the download page you would check if the session value is set. If yes, show the download content. If no, then show the login page.
-
Um, yeah. That is why I asked back on my first post why you were using CAST() to cast fields into DATE types when they should already have been date types. That is most likely the cause of all your problems. If you want MySQL to do comparisons of data (for example checking if a date is greater or less than another date) then MySQL needs those objects to be dates. Instead MySQL is having to convert ALL those fields into types it can work with THEN do the comparison. In addition to changing your date fields to date types I hope you are using INT types for the ID fields.
-
Well, I'm making some assumptions because, without actually having the data in front of me, there may be some aspects that aren't apparent from your description. You state the values are as follows So, the value in the database is "Testing..." [space] "1" [space] "2" [space] "3" And, it appears the user is entering "Testing..." [linebreak][linebreak] "1" [linebreak][linebreak] "2" [linebreak][linebreak] "3" But, what is not clear is what ELSE would you allow the user to enter and still want to consider a match? Can the user put in tabs between words? How many linebreaks between words should you allow? What if the user enters multiple spaces, should they be collapsed to one space, etc. etc. . . . Plus, I don't know how all the other values in your database may be formatted such that different modifications may be necessary. Without knowing all those answers here is my guess at a solution. Replace all repetitions of line breaks (\n or \r) and spaces with a single space. So, if you have "1" [space][linebreak][linebreak][space] "2" make the result "1" [space] "2". $user_description = "Testing...\r\n\r\n1\r\n\r\n2\r\n\r\n3"; $sql_description = "Testing... 1 2 3"; //Parse input $user_description = preg_replace("#([\r|\n| ]+)#", ' ', $user_description); if($user_description == $sql_description){ echo 'Match'; // <== This will be the output for the above input values } else { echo "Don't match"; }
-
I don't know what editor you are using, but you need to find one that colorizes the code such as this forum does when using [ php ] tags. You will then get accustomed to seeing certain elements in certain colors. Just "looking" at the code you posted I was able to easily spot at least one error. Looking at the last echo() statement the command is in red fond whereas all the other functions are in green. That is because you forgot to close the last text string with double quotes. Also, you run the POST vars through a function to parse them and assign to new variables, but then you use the original POST vars when doing the validation. Lastly, the mistakes you are making are simple syntax errors. You obviously know that a string starting with a quote mark needs to have the ending quote mark because you did it correctly many other times. So, stop excusing yourself for being a beginner. Programming is a VERY unforgiving process. You need to dot ALL your I's and cross ALL your T's.
-
Adding fields via JavaScript is probably your issue. Instead of dynamically adding the fields, I would suggest just creating the three sets of fields by default and then hiding the last two sets until the user clicks the button. That way all three sets of fields are passed in the POST data (just ignore the empty ones) and you won't have nay problems with the JavaScript corrupting your form.