Jump to content

Psycho

Moderators
  • Posts

    12,157
  • Joined

  • Last visited

  • Days Won

    129

Everything posted by Psycho

  1. I agree with that, I always like to be very explicit. In this case, you have three possible outcomes: A) no records were updated which means username/password do not match, B) Only one record matched and was updated (success scenario), or C) There were multiple records that matched the username and password. If you were to get option C there are some serious problems that need to be resolved independent of the pw update script.
  2. That was my initial thought as well. But, when I did a little more analysis I think you could so this with just ONE update query (no SELECT query) using the username/current PW in the WHERE clause. Then just do a check of affected rows. If the result is 0, then the username and/or current password are incorrect. If the result is 1, then username/current password were correct and the value was updated. It is only reducing the queries from 2 to 1, but I try to eliminate as much overhead on the db as possible. Sample code: //process the input into variables $username = strtolower(strip_tags(trim($_POST['username']))); $oldpass = strip_tags(trim($_POST['oldpass'])); $newpass1 = strip_tags(trim($_POST['newpass1'])); $newpass2 = strip_tags(trim($_POST['newpass2'])); //Validate input $error = false; if(empty($username) || empty($oldpass) || empty($newpass1) || empty($newpass2)) { $error = "All fields are required."; } elseif($newpass1 != $newpass2) { $error = "New passwords do not match."; } else { //No input errors, run query $username = mysql_real_escape_string($username); $oldpass = md5($oldpass); $newpass1 = md5($newpass1); $query = "UPDATE user SET password = '$newpass1' WHERE username = '$username' AND password = '$oldpass'"; $result = mysql_query($query) or die(mysql_error()); if(mysql_affected_rows()!==1) { $error = "Username and/or password are not correct". } } //Check if any errors occured if($error !== false) { echo "<span style=\"color:red\">The following error occured: {$error}</pan>\n"; } else { echo "Password updated successfully". }
  3. OK, I have been "assuming" that the array you are posting is not formatted as it REALLY is. You should do a print_r() and post the result of that. Here is what I assume is the true format of your array: Array ( [0] => array( [0] => 07/20/2011 [1] => 07/21/2011 ) [1] => Array ( [0] => 08/16/2011 [1] => 08/17/2011 ) ) Also, as my signature states I do not always test the code. If I am confident in the logic I leave it to the person I am providing the code for to do any debugging of syntax errors. In this case, the error did not produce a code failure. There was an errant semi-colon at the end of the IF statement. During my debugging I transformed the script into a function. The revised "tested" code is below. However, if the booked dates are coming from a database you should just do a single query against the database to see if there is a conflict rather than querying the database for all the records and then checking the requested dates. I would have to know the format of the data in the database to provide a query. Revised script //Returns true/false based upon whether the requested dates conflict //with the already booked dates in the $bookedDates array function datesAvailable($bookedDates, $start_date, $end_date) { $datesAvailable = true; foreach($bookedDates as $key => $dates) { //Create variables for rrecord start/end dates list($bookedStart, $bookedEnd) = $dates; if ($start_date < strtotime($bookedEnd) && $end_date > strtotime($bookedStart)) { return false; } } return true; } //Array of already booked dates $checkDates = array( array ('07/20/2011', '07/21/2011'), array ('08/16/2011', '08/17/2011') ); $available = datesAvailable($checkDates, 1312844400, 1312930800); //returns true $available = datesAvailable($checkDates, 1313362800, 1313622000; //returns false
  4. This forum is for people looking for help with code they have written. Your question has nothing to do with that. Even so, it is impossible to answer your question with anything substantive. You say you are an "intermediate" at PHP. I have no idea what that means to you and, more importantly, what your skill set is. I have to assume that since you are asking this question you don't possess the skills necessary to start. I don't know what skills, therefore, you are lacking. But, you would need "excellent" PHP skills as wells as good database skills. Not just accessing the database, but being able to design a database schematic based upon the needs and requirements of the application. There may be other skill sets needed based upon how complex you want the application to be: CSS, advanced HTML, JavaScript, etc. Assuming you have the requisite skills the first step is to define your requirements( e.g. users need to be able to register, users should be able to post "x" type of information, users need to be able to request friends, etc.). Then you need to convert those requirements into actual features to develop the user interface that you will build. There are many other facets to the process, but I'm not going to try to fit a books worth of information into a forum post. On second though, that is my answer, . . . get a book.
  5. Yeah, my copy/paste error. Use $pairs[$pairKey]++;
  6. I think I may know what is happening. But, before I explain that, I would say the first order of business is to do a print_r on the array $pairs and inspect it. Look at some of the results to see if they at least look valid. Then do some queries to verify they are correct. For example, if it shows a key of '16-32' with a value of 20, then do a query to validate: $query = "SELECT * FROM june122011 WHERE 16 IN (`A`,`B`,`C`,`D`,`E`,`F`,`G`,`H`,`I`,`J`,`K`,`L`,`M`,`N`,`O`,`P`,`Q`,`R`,`S`,`T`) AND 32 IN (`A`,`B`,`C`,`D`,`E`,`F`,`G`,`H`,`I`,`J`,`K`,`L`,`M`,`N`,`O`,`P`,`Q`,`R`,`S`,`T`)"; $result = mysql_query($query); echo mysql_num_rows($result); OK, so this is what I think the problem is. I made an assumption that you would be storing the numbers in a logical order of smallest to largest. That way, when you do the loops in the code you would always get something like "16-24" and never "24-16". Since the numbers are apparently in a random order between the draws you may have 35 & 77 as the REAL most common pair, but it is being processed as 20 occurrences of "35 & 77" and 11 occurrences of "77 & 35". To resolve this you need to put the number in order when creating the keys. Change this $pairKey = "$num1-$num2"; To this $pairKeyAry = array($num1, $num2); sort($pairKeyAry); $pairKey = implode('-', $pairKeyAry); Of course, that is just my guess based on the facts I have at hand. you need to do the test and validation.
  7. Are you looking for similar words OR words with repeated letters? When trying to filter user input you must be VERY specific as to your requirements.
  8. The problem is you have apparently copy/pasted the function many times. You only need to create the function ONCE, then call it as many times as you need it. Example: function truncateString($string, $length, $ellipse='...', $preserveLineBreaks=false) { if(!$preserveLineBreaks) { //Remove 1 or more line breaks with a single space $string = preg_replace("#(\r|\n)+#", " ", $string); } if (strlen($string) <= $length) { return $string; } return trim(array_shift(explode("\f", wordwrap($string, $length, "\f")))) . $ellipse; } $nocaptitle = truncateString($nocaptitle, 47); $somestring = truncateString($nocaptitle, 47); $anotherstring = truncateString($anotherstring, 47);
  9. The best approach I can think of would be to have a cron job run each day to process all the records from the previous day. The script should query all the draws for the previous day. Then process each draw to determine the double, triple and quadruple combinations (of course, you would have to determine how to handle if there are ties!). As I process each record, I would probably determine a combinations (e.g. 3 & and create an array entry for it using those values as the key - and set the value to 1. Then, as I process the rest of the records, if I run across 3 & 8 again, I would increment the value of that array key by 1. Once all the records are processed, I would just grab the key of the highest value in the array. Here is some code. However, I don't know how long this would take to run to process the trips and quads - so I commented that section out. I didn't test this, but the logic seems right to me. If you do get it to run for the pairs, go ahead and uncommen the trips section - then the quads. <?php $query = "SELECT `A`,`B`,`C`,`D`,`E`,`F`,`G`,`H`,`I`,`J`,`K`,`L`,`M`,`N`,`O`,`P`,`Q`,`R`,`S`,`T` FROM draws WHERE draw_date = '$yesterday'"; $result = mysql_query($query); //Arrays to hold values $pairs = array(); $trips = array(); $quads = array(); $while($draw = mysql_fetch_assoc($result)) { foreach($draw as $num1) { foreach($draw as $num2) { //identify all pair combninations if($num1==$num2) { continue; } $pairKey = "$num1-$num2"; if(!isset($pairs[$pairKey])) { //Create the pair record if not exist $pairs[$pairKey] = 0; } //Increment pair record by 1 $pairs[$pairKey] = 0; /* //Identify all trip combinations foreach($draw as $num3) { //identify all pair combninations if($num1==$num2 || $num1==$num3 || $num2==$num3) { continue; } $tripKey = "$num1-$num2=$num3"; if(!isset($trips[$tripKey])) { //Create the pair record if not exist $trips[$tripKey] = 0; } //Increment pair record by 1 $trips[$tripKey] = 0; //Identify all quad combinations foreach($draw as $num4) { //identify all pair combninations if($num1==$num2 || $num1==$num3 || $num1==$num4 || $num2==$num3 || $num2==$num4 || $num3==$num4) { continue; } $quadKey = "$num1-$num2=$num3"; if(!isset($quads[$quadKey])) { //Create the pair record if not exist $quads[$quadKey] = 0; } //Increment pair record by 1 $quads[$quadKey] = 0; } #END Quad Check }#END Trip check */ }#END pair check } } //Sort arrays highest to lowest arsort($pairs); arsort($trips); arsort($quads); //Get most common $mostCommonPair = key($pairs); //E.g. 15-37 $mostCommonTrip = key($trips); //E.g. 8-14-35 $mostCommonQuad = key($quads); //E.g. 16-32-40-52 ?>
  10. If my math is correct there are 3,160 different pair combinations. With trips and quads the number will be exponential! I really don't see an easy way to do this without processing every record. You definitely don't want to do this with the database. So, you would have to query all the records and have a loop in PHP to process all the records to find the most common pair.
  11. That is an option, but may not be the best option. There are different approaches and you need to decide what makes the most sense for you. Just using rand() has the potential of creating duplicates, but the risk is probably small enough that it is worth it. I think it would be highly unlikely that two photos would be submitted with the exact same name at the exact same time. So, you could just append the timestamp of when the photo was submitted. In fact, I wouldn't even do a check if the file already exists before doing so, I'd just append the timestamp to every photo submitted.
  12. You know I just thought of a WAY better solution. Change the values of your select list as follows: <option value="0">Once</option> <option value="+1 Weeks">Weekly</option> <option value="+2 Weeks">Bi-Weekly</option> <option value="+1 Months">Monthly</option> <option value="+2 Months">Bi-Monthly</option> <option value="+1 Year">Yearly</option> Then use this replacement function: function nextDate($date, $occur, $end_date) { switch($occur) { case '+1 Year': case '+2 Months': case '+1 Months': case '+2 Weeks': case '+1 Weeks': $date = strtotime(date('Y-m-d', $date) . " $occur"); break; default: //return false if no occurances return false; } //return false if no more valid occurances if($date > $end_date) { return false; } return $date; }
  13. If you want to format the numbers in a consistent manner, you should FIRST use The Little Guy's code to strip out ALL characters that are not numbers. THEN you can apply the formatting. But there is a decision to be made on how to format it if there are not 10 characters. If the input is not 10 digits you can either leave it unformatted, return false (and not allow it), or determine some other way to format it. function getFormattedFax($inputFax) { //Strip out all non-numeric characters $faxNum = preg_replace("/[^\d]/", "", $inputFax); //If10 characters, apply formatting $formattedFax = (strlen($faxNum)==10) ? preg_replace('/(\d{3})(\d{3})(\d{4})/', '$1-$2-$3', $faxNum) : $faxNum; return $formattedFax; } echo getFormattedFax('123-456-7890'); //123-456-7890 echo getFormattedFax('(123) 456-7890'); //123-456-7890 echo getFormattedFax('123.456.7890'); //123-456-7890 echo getFormattedFax('123-4567'); //1234567 echo getFormattedFax('123456'); //123456 echo getFormattedFax('1234567890 FAX'); //123-456-7890 echo getFormattedFax('FAX: 1234567890');//123-456-7890 echo getFormattedFax('FAX 1234567'); //1234567
  14. I'm not going to fix your code when I already have a function that does what you need. The following function will return a string up-to the number of characters specified. If that will cause the string to break a word (i.e. not on a space) then it truncates the string to the first space before the requested number of characters. It does not truncate on dashes. function truncateString($string, $length, $ellipse='...', $preserveLineBreaks=false) { if(!$preserveLineBreaks) { //Remove 1 or more line breaks with a single space $string = preg_replace("#(\r|\n)+#", " ", $string); } if (strlen($string) <= $length) { return $string; } return trim(array_shift(explode("\f", wordwrap($string, $length, "\f")))) . $ellipse; } $nocaptitle = truncateString($nocaptitle, 47); The $ellipse parameter is optional (default is '...') and will be concatenated to the string - if it is truncated. If you don't want it pass an empty string as the 3rd parameter. The 4th parameter is to specify whether line breaks in the input should be preserved. The defaul tis false. SO, if a multi-line string is passed to the function, the line breaks will be replaces with spaces. Then the truncation is applied.
  15. The logic of the code I provided is valid. But, I think I misunderstood which dates were which. If the dates in the $checkDates array are the already booked dates and the $start_date & $end_date are the proposed dates for a new booking, then you just need to reverse the logic in the code. $dateUnavailable = false; foreach($checkDates as $key => $dates) { //Create variables for rrecord start/end dates list($bookedStart, $bookedEnd) = $dates; if ($start_date < strtotime($bookedEnd) && $end_date > strtotime($bookedStart)); { $dateUnavailable = true; break; } } If you still get invalid results provide the start/end dates and the $checkDates array. As a visual example, below are the various combinations of how a booked date range and various requested date ranges. If you look at all the "invalid" date ranges (the requested start date is before the booked end date) AND (the requested end date is before the booked start date) 3-----6 <== Booked Date Range ---------------- <== Valid Request date ranges 1-2 1---3 6---8 7-8 ---------------- <== Invalid Request date ranges 2---4 3-4 4-5 5-6 5---7 2---------7
  16. Yes, I know that was what you asked for, but what I was proposing is that it might not be the best approach. It is a fairly straightforward process to either create all the instances up front (as you asked) or to determine them dynamically at run-time. redixx and I were suggesting the latter. But, I really am ambivalent on which would be the better approach as it really depends on many variables on how it will be used. So, I'll provide some mock code to create all the records to insert (as you requested). You do NOT need a cron job, you can do it when the user submits the form. I left a lot of necessary validation logic out of this code (ensuring dates are actual dates, escaping for DB input, etc.) but this code has the logic for creating all the records based upon the occurrence selection. //Test input $_POST['date'] = '2011-3-15'; $_POST['time'] = '12:30 PM'; $_POST['desc'] = 'Meeting'; $_POST['occur'] = 'Weekly'; $_POST['end_date'] = '2011-5-15'; $date = strtotime($_POST['date']); $time = $_POST['time']; $desc = $_POST['desc']; $occur = $_POST['occur']; $end_date = ($occur!='Once') ? strtotime($_POST['end_date']) : $date; function nextDate($date, $occur, $end_date) { switch($occur) { case 'Yearly': $date = strtotime(date('Y-m-d', $date) . " +1 Year"); break; case 'Bi-Monthly': $date = strtotime(date('Y-m-d', $date) . " +1 Months"); break; case 'Monthly': $date = strtotime(date('Y-m-d', $date) . " +1 Month"); break; case 'Bi-Weekly': $date = strtotime(date('Y-m-d', $date) . " +2 Weeks"); break; case 'Weekly': $date = strtotime(date('Y-m-d', $date) . " +1 Week"); break; case 'Once': default: //return false if no occurances return false; } //return false if no more valid occurances if($date > $end_date) { return false; } return $date; } $values = array(); while($date!==false) { //Create insert values for current date $date_str = date('Y-m-d', $date); $values[] = "('$date_str', '$time', '$desc', '$occur')"; //Get next date based upon occurance $date = nextDate($date, $occur, $end_date); } $query = "INSERT INTO schedule (`date`, `time`, `desc_type`, `occur`) VALUES " . implode(", \n", $values); $result = mysql_query($query) or die(mysql_error()) With the test values in the code above, the following would be the resulting query: INSERT INTO schedule (`date`, `time`, `desc_type`, `occur`) VALUES ('2011-03-15', '12:30 PM', 'Meeting', 'Weekly'), ('2011-03-22', '12:30 PM', 'Meeting', 'Weekly'), ('2011-03-29', '12:30 PM', 'Meeting', 'Weekly'), ('2011-04-05', '12:30 PM', 'Meeting', 'Weekly'), ('2011-04-12', '12:30 PM', 'Meeting', 'Weekly'), ('2011-04-19', '12:30 PM', 'Meeting', 'Weekly'), ('2011-04-26', '12:30 PM', 'Meeting', 'Weekly'), ('2011-05-03', '12:30 PM', 'Meeting', 'Weekly'), ('2011-05-10', '12:30 PM', 'Meeting', 'Weekly')
  17. @sunfighter I see what you are saying. But, I have learned to "read between the lines" of what people post here. Sometimes they are asking the opposite of what they really mean. I took the OPs post as needing to make his code more efficient. To me that just doesn't mean execution time but also the basic complexity of the code. As to your statement: I have to disagree for several reasons. A function to get a list of users is very common. There is a high probability that an application will have many pages that need to get a list of users: a page of registered users, populate a select list to assign something to a user, etc. Typically I would have a function like that with an optional WHERE clause to give it more flexibility, e.g. I could use the same function to get a list of admins, disabled users, whatever. That way I only need ONE function to perform multiple tasks. In fact, I typically create a class to handle all the data abstraction within my applications. I may have several functions that are used throughout the application (such as getting a list of users) but I may also have functions that are only used by a single page. By separating the data abstraction you gain great flexibility in maintainability and portability of your application. If you need to change to a different database model, want to change table/database names, etc. You only have to go find the functions used for accessing data and make the changes there instead of finding each and every script that touches the database. If the OP is planning on duplicating that function in multiple pages where he needs to get a list of users, yes, that is a poor implementation. If, however, he is going to put that function in a common include file or a class, then it is a good implementation - even if he only calls the function on one page. But, creating functions for data abstraction is not the only reason you may write a function for something you only use one. The standards of structured programming and OOP both support the modularization of code.
  18. OK, to use just a single record for each series, I would suggest having an "endOccurence" field int he table. If the user selects anything other than "Once" for the occur value you should store a value for the endOccurence. This should be a date or NULL if it does not have an end date. Then you can use the following query to get all the schedules that fall between a start and end date. SELECT * FROM schedule WHERE date <= $endDate AND ( date >= $startDate OR (occur <> 'Once' AND (endOccurence = NULL OR endOccurence >= $startDate) ) ) The next step would be to process the records returned to determine the actual dates of the schedules that fall within the time period.
  19. Hmm . . . I've never thought about a scenario such as this. My first instinct would be to just create one record and save the occurrence as a parameter. Then just determine the the dates at run-time. But, that may be less efficient than creating multiple records. But, you have the problem that you could only create the multiple instances for a specific time period. If the user creates a meeting to occur each week with no end date, you can't create an infinite amount or records - which is why I assume you asked how to do this for one year. But, if that is the case the "yearly" occurrence has no purpose. So, let's assume you do create individual records for some period into the future. You probably still want some way to tie all of the occurrences together. When I delete a recurring meeting in Outlook it gives me the option of deleting that occurrence or all occurrences. Here is my suggestion: 1. When saving the records for a schedule that has multiple occurrences, have an additional field to store an occurrence ID. You could just use a unique random number (for example a timestamp of the submission and the user ID concatenated should do). Then, when the request is submitted and you see there is an occurrence selected, you could use PHP to generate the records needed programmatically and then do a single INSERT of all the records. I'll slap some sample code together and post it here shortly. EDIT: After further thought, I'm going to go back to my original idea of having only one record for the series. I need to look at how I would query and determine the dates for a given period, but it shouldn't be too difficult. But, if you want to delete certain occurrences within a schedule you would probably have to maintain an exception table.
  20. I see a couple of problems. First, since you have a multidimensional array, in your foreach() loop the '$date' value is an array. So, you are trying to compare an array against the start/end dates. You need to compare the two date value in the '$date' array against the start/end dates. Second, your logic of comparing the dates will not work. You can't compare the two dates individually against both the start and end dates. The logic you have will always show that there is a conflict unless the dates of the record exactly equal the start/end target dates. And, I think that should be considered a conflict as well. Think about it for a moment. If you have a start/end dates of Feb 1 to Feb 28. If you have a record for Jan1 to Jan 31, both the dates are less than the end target date, which would not be a conflict, but the logic above would make it seem so. This should be what you want. It may seem counter intuitive since you are comparing the record start date with the target end date and the record end date against the target start date. But, trust me it is correct. It will validate that the record time period does not overlap the time period of the target. $dateUnavailable = false; foreach( $checkDates as $key => $dates) { //Create variables for rrecord start/end dates list($recStart, $recEnd) = $dates; if (strtotime($recStart) < $end_date && strtotime($recEnd) < $start_date); { $dateUnavailable = true; break; } }
  21. PHP is run at the server. What it outputs goes to your browser and that is what creates bandwidth. You can run a thousand line PHP script but if it only output a single line of HTML it really don't use much bandwidth. Running MYSQL queries will not mess up your bandwidth. Consolidating them in functions will not help nor hinder the BW. Functions for queries are unnecessary if you get all the info you need with a single query instead of two or three; it makes your code more efficient and uses less server time. @sunfighter: You are referring to "bandwidth" in only one sense - internet upload/download bandwidth. But, just about any aspect of computing has "bandwidth". There is bandwidth specific to hardware: CPU, Memory and hard Drive. There is also bandwidth specific to software: Database and Web Server would apply here. All of these (and others) will have an impact on the performance of a web based application. For an example of how server-side bandwidth can affect the client browser you only need to have a script that runs queries in a loop. As the number of loops increases the time for the page to display will become longer and longer until the request will time out. There may be only a few bytes of actual data being transmitted between the server and client, but it is due to "bandwidth" issues on the server that affect the client side performance.
  22. Really, then tell me what my password was in the example I provided - I provided way more info than a user with access to the DB would have. You can't brute force it because you have no idea how the salt was applied. And, as I have already stated a multitude of times previously an attacker with access to the DB would have no clue how the salt was applied or, just as important, what the salt is. That is why it doesn't matter if you use a random value or some other value unique to the user for the salt. Both are just as valid.
  23. No, it does not remove anything. If anything it will "escape" characters (by putting a forward slash in front of them) that could cause the value to be interpreted as MySQL code. The actual stored value would be exactly the same as the user entered (except anything you may have trimmed). You need to take an analytical approach to each field you are storing to determine what are the appropriate values. When you say "...how do i cleanse the data of other dangerous characters such as... []{}-_:;,.<>$" Who says they are dangerous? they are not dangerous for storing in the database and they won't cause any harm if you "tried" to use them to send an email (it would just fail). But, if you want to validate whether the user entered email is a properly formatted email address, that needs to be done before you even think about storing it. As mikesta707 stated previously this was typically done using a regular expression to validate that the email only used certain characters and were formatted in a certain way. However, as of PHP5.2 there is a built in validation function called filter_var() that can validate many types of values - the first example shown is for email addresses http://www.php.net/manual/en/function.filter-var.php
  24. That is because your function only runs the query. It doesn't DO anything with the results and it doesn't return the results to wherever you called the function. First of all, give your functions useful names. A name like query(0 doesn't tell you anything about WHAT it is querying. Here is an example of a revision and how it would be used: function getUserData() { $sql = mysql_query("SELECT * FROM users"); $result = mysql_fetch_assoc($sql); $users = array() //Dump results into an array while($row = mysql_fetch_assoc($result)) { $users[] = $row; } return $users; } //In another section/script you need to display a list of users. //You would do the following $userList = getUserData(); foreach($userList as $userRecord) { echo "Username: {$userRecord['username']}<br>\n"; }
  25. I'm not really sure what you are asking. Your title states you want to create a drop-down list, but then in your description you state which would seem to indicate you want the ability to have separate pages (i.e. not a select list for the user to choose). Both are possible. In either case the solution is similar. You just need to provide the value for the team criteria to the query. However, to make this easier you should not be storing the team name in the players table. Instead you should have a teams table that has a team id and and a team name. Then the players table should use the team id. You can use the team name, but it requires more validation and manipulation of the value. If you want separate pages for each team, just create one page and pass an additional parameter to the page. E.g. <a href="showteam.php?teamid=1">Manchester United</a> This assumes that Manchester United has the ID of 1 in the database. If you didn't use IDs (and instead just use the team name, then you would need to urlencode() the names for the query string). Then in your page you would generate your query like so $teamID = (int) $_GET['teamid'] $query = "SELECT name FROM players WHERE teamid = $teamID"; Or, if you use a select list, you would just set up the name/value same as the link shown above. Then you would capture the team id via POST data instead of GET data.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.