Jump to content

Psycho

Moderators
  • Posts

    12,157
  • Joined

  • Last visited

  • Days Won

    129

Everything posted by Psycho

  1. You can put a unique constraint on a combination between multiple fields. So, you would not be able to enter two records which have the same value for sender and the same value for recipient. But, there is no way I know of through the DB schema to prevent two records where the values are swapped between the fields in the two records (e.g. same as the second record in your example). Why not do a simple SELECT before inserting the reocrd? No need for a bunch of if()'s in your code. I can think of some more complicated solutions, such as creating a trigger that creates a unique value based upon the two IDs and sets that value in a third field with a unique constraint. But, really that is overkill.
  2. return ($count > 0) ? true : false; Pro tip:if you are using a condition and want a Boolean as the result, there is no need to actually create a TRUE and FALSE for the result because the condition itself will be a Boolean. That is basically the same as saying If true, return true, else return false. This will work just the same to return a Boolean: return ($count > 0);
  3. What do you mean by "alter" the table? Are you wanting to modify records already in the table, are you wanting to modify the table schema to prevent those conditions (don't think it's possible) or are you wanting to create code to prevent those "error" conditions. Both are very easy.
  4. mac_gyver is right. If code is not producing the results you expect, do not jump to the conclusion that you need to completely change the logic. Besides, there shouldn't be anything wrong with that code (I provided it ). You just need to learn how to DEBUG. Debugging is not a hard concept and it amazes me how many people can't do simple validations. But, a couple of things you should always think of doing in these types of situations: 1) Verify what values contain. Don't assume a variable in your script contains what you *think* it does. Use an echo or var_dump() to help. 2. Verify that your if/else conditions are doing what you think they are. I like to output the values used in the condition before the condition is executed and then put an echo within the condition block to verify if the condition was true. There are plenty of techniques to use. Just determine the most logical point of failure and add some code to check what really is happening. Then based upon those results you may need to test something else. But, eventually you will narrow down the problem. In this case you have four points of possible failure. You could add a few echo statements to see which one is "failing" and then you can work on determining why it is failing. Look at the four points of failure where I've put an echo statement. You will now get a message on screen as to why the function is returning false. Note, I put an exit() after each echo to stop the script from doing the redirect. You should remove or comment out those lines after you resolve the problem. There are much better techniques than this, but this will get you started. <?php function login($email, $password, $mysqli) { $stmt = $mysqli->prepare("SELECT id, username, password, salt FROM users WHERE email = ? LIMIT 1") //Check if prepared query was succesful if (!$stmt) { echo "Failed trying to prepare query"; exit(); return false; } //Execute the query $stmt->bind_param('s', $email); $stmt->execute(); $stmt->store_result(); //Check if any matching records found if($stmt->num_rows != 1) { echo "No matching records on email '{$email}'"; exit(); return false; } $stmt->bind_result($user_id, $username, $db_password, $salt); $stmt->fetch(); //Check if too many attempts if(checkbrute($user_id, $mysqli) == true) { echo "The user is locked."; exit(); return false; } $passwordCheck = hash('sha512', $password.$salt); //Check if password matches if($db_password != $passwordCheck) { echo "The passwords do not match."; exit(); $now = time(); $mysqli->query("INSERT INTO login_attempts (user_id, time) VALUES ('$user_id', '$now')"); return false; } //Everythign checks out. Complete login $user_browser = $_SERVER['HTTP_USER_AGENT']; $user_id = preg_replace("/[^0-9]+/", "", $user_id); $_SESSION['user_id'] = $user_id; $username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username); $_SESSION['username'] = $username; $_SESSION['login_string'] = hash('sha512', $password.$user_browser); return true; } ?>
  5. If you see something you don't understand, take the time to figure out what it is doing instead of using it "quite a lot". However, I personally don't like using "@" to suppress errors and instead to handle them gracefully. In this case you could use empty() which works very similar to just using the variable as the condition - but empty() won't generate an error if the variable doesn't exist. Here is the list of things that will cause empty() to return true I believe most/all of those would generate the same result as how you are using it now - not 100% sure on the last two or the "0" as a string. But, those would probably not be applicable in 99% of scenarios.
  6. Psycho

    vbscript

    OK, so on the Second Computer (The PC where the user is viewing the web page) you want to initiate the execution of the VBScript on the first computer (where the VBScript exists). Is the first computer also the one where the web server is running? If yes, you can have a PHP script that uses exec() to run the VBScript file. The manual for that function has some examples. If the first PC is not where the Web server is running it would get trickier. You would have to create some kind of service that runs on that PC waiting for a request to run the file. That service would need to monitor a certain port for a request. You could then create a PHP script that generates the request to that machine to run the file. It not impossible, but it beyond what I could help with.
  7. I was going to post a quick question such as yours but decided to write a quick example. <html> <head> <script type="text/javascript"> function validNumber(numberStr) { var validNumTest = /^\d{10,14}$/ return validNumTest.test(numberStr); } function testNumber(numberStr) { if(validNumber(numberStr)) { alert('Valid number.'); } else { alert('Not a valid number.'); } } </script> </head> <body> Test Number: <input type="text" id="number1"><br> <button onclick="testNumber(document.getElementById('number1').value);">Check Number</button> </body> </html>
  8. Psycho

    vbscript

    What, exactly, are you trying to accomplish? I "believe" you can execute VBScript code that is included in the web pages the same as JavaScript - but it will ONLY work on IE. At least it used to. But, allowing that is a HUGE security risk, so it would be a safe bet that it might not work in current versions of IE. Or, are you trying to execute a vbs file that exists on the user's PC? Either way, you are going to have some challenges to overcome. The only solution might be to have a Java Plug-In (not JavaScript) created to perform the actions you want performed. but, that would require the user to actually install the Plug-In.
  9. Psycho

    rowCount

    Per the manual: http://php.net/manual/en/pdostatement.rowcount.php
  10. I have no idea why you would generate a random number from 1 to 100 and then check for the value >50. Why not just do a random number of 1 or 2. Anyway, you could do for any number of options in this manner $test = rand(1, 4); //Where 4 is the max number of options switch($test) { case 1: header("Location: http://www.example1.com"); break; case 2: header("Location: http://www.example2.com"); break; case 3: header("Location: http://www.example3.com"); break; case 4: header("Location: http://www.example4.com"); break; }
  11. On the very last line of the function login(), where everything succeeded, put return true;
  12. You don't care? You have to write code to programatically understand how to interpret the user input. As humans we can read an address, for example, and intuitively know the street, city, country, etc. A computer would just see a string of random characters. We have to write logic to break apart a string and determine what values are what. If the values are separated by a dash, then we can explode on the dash. If not, then we have to come up with some other rule or rules on how the string will be broken apart. As for your error, you are exploding a line of text based upon the dash and then taking ONE value at a time and trying to insert a record which requires eight values. If you are going to receive multiple lines, then follow the logic from the other post linked above to process the results into a single line. THEN use explode on each line to break it into the eight different values and use ALL EIGHT of those values in the insert query.
  13. I think this may be your problem: if ($stmt = $mysqli->prepare("SELECT id, username, password, salt FROM users WHERE email = ? LIMIT 1")) { On that very first line, if the $mysqli->prepare returns a false, the entire rest of the function is skipped and the function returns nothing - which may be interpreted as true. Perhaps your connection to the database does not exist. But, overall, I don't like the logic anyway. For example, why do you attempt to fetch the results BEFORE you check the num_rows returned? Also, it makes it hard to read the code when you check for a success condition and put the error condition way down at the end in else statements. Lastly, I see you are apparently setting a unit timestamp in the "time" field. That is a bad idea. Use a MySQL timestamp field and you can create the field such that it is automatically set when a new record is created (or edited) without having to set it within your code or the query. And, regardin gthe "login_attempts" table. I don't see anything in your code that would 'clear' that table if a user has a successful login. I would do something like this: function login($email, $password, $mysqli) { $stmt = $mysqli->prepare("SELECT id, username, password, salt FROM users WHERE email = ? LIMIT 1") //Check if prepared query was succesful if (!$stmt) { return false; } //Execute the query $stmt->bind_param('s', $email); $stmt->execute(); $stmt->store_result(); //Check if any matching records found if($stmt->num_rows != 1) { return false; } $stmt->bind_result($user_id, $username, $db_password, $salt); $stmt->fetch(); //Check if too many attempts if(checkbrute($user_id, $mysqli) == true) { return false; } $passwordCheck = hash('sha512', $password.$salt); //Check if password matches if($db_password != $passwordCheck) { $now = time(); $mysqli->query("INSERT INTO login_attempts (user_id, time) VALUES ('$user_id', '$now')"); return false; } //Everythign checks out. Complete login $user_browser = $_SERVER['HTTP_USER_AGENT']; $user_id = preg_replace("/[^0-9]+/", "", $user_id); $_SESSION['user_id'] = $user_id; $username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username); $_SESSION['username'] = $username; $_SESSION['login_string'] = hash('sha512', $password.$user_browser); } EDIT: ON second thought, there's no reason to create a separate function to check for too many invalid logins. Just JOIN the login_attempts table on the users table in your initial select query and you can check the login attempts based upon the initial result. Personally, I would just have a login_attempts FIELD in the user table and increment the value by 1 for every invalid login attempt (and, of course, set to 0 after a successful attempt)
  14. OK, so you are running the site on your local machine. Is that machine connected to a network such as a router in your home? Can you connect your mobile device to that router via Wi-Fi? If so, then both devices will be on the same network and you can access the web pages from the PC on your mobile device by entering a URL that points to your PC. So, instead of using the URL http://localhost/mypage.php you would just replace the 'localhost' with the ip or computer name of the PC.
  15. Yeah, you are going to have a real problem with that input. You can easily explode() the text into individual lines. But then, I see no easy way to differentiate the data on a single line into the different sets of data. Well, not without more information. You first state the information will be in this format Date - Local Team - Away Team - RatioLocal - Draw - RatioAway - SportID - League Then you show an example of this 2013/04/03 21:00 Bolivar The Strongest 2.20 3.20 2.88 1 LFP 2013/04/03 21:00 La Paz Oriente Petrolero 4.33 3.50 1.73 1 LFP 2013/04/03 21:00 Wilstermann Universitario 1.91 3.40 3.60 1 LFP Those are not in the same format. If there are dashes between the different pieces of data, you can simply explode() the line using that character. But, your sample data example does not show dashes. But, it does show four spaces between each piece of data - except the last one. I don't know if that is correct or just how you decided to post the data. You need to determine a rule or rules(s) that you can rely upon to programmatically differentiate the different pieces of data. Also, you shouldn't just explode the data and assume that the right number of fields are present. You need to verify each record before you execute the query. Lastly, your error is due to this: $a=explode(' ',$text); foreach($a as $res){ You explode the string based upon spaces and then execute a loop for each "word". Then in that loop you try to run a query $res=mysql_real_escape_string($_POST['res']); $sql="INSERT INTO events (hometeam, awayteam, ratiohome, ratioaway, ratiox, sportid, starttime, liga) VALUES ('$res')"; That query is trying to insert a record for 8 different fields, but you are only supplying ONE value.
  16. There are mobile emulators, but I've never used them. But, you would have to have the site hosted somewhere, even if it is on your local environment, in order to use a simulator. You could just as easily open the site on an actual device in that environment. In other words, if you are hosting the web site on a local install (e.g. XAMPP) and you have a mobile device that is on the same network, you could simply point the browser on your device to that machine, either by IP or computer name. E.g. http://192.168.1.125/mypage.php
  17. Or it isn't returning false when the login check fails. Post the code for the function login()
  18. I mean that your corrections were not quite right. Yes, there were errors in the code I provided, but as I clearly state in my signature I don't always test the code I provide here. It is meant to be a framework for the person asking for help and to do the final implementation. I provided this: //Trim all the values $textLines = array_map('trim', $textLines); //Remove empty line $textLines = array_filter('trim', $textLines); //Escape input for query $textLines = array_filter('mysql_real_escape_string', $textLines); And you stated that the parameters for the array_filter() calls should be flipped. array_filter() removes items from an array based upon the "value". The line after the comment "//Remove empty line" is meant to remove empty values from the array. I incorrectly copied/pasted the array_map() line above and changed the function name but forgot to remove the parameter for the trim function. If the second, optional parameter is not provided then array_filter() will remove any values that are "interpreted" as false (such as an empty string). If you flip the parameters then that line will not do anything since trim() would not return false - which is required for array_filter() to remove values as it is intended. So that line should be //Remove empty lines $textLines = array_filter($textLines); - which will remove empty lines/values from the array For the last line, which the comment states is for the purpose of escaping values, I again did a copy/paste and changed the callback function to use, but did not change the function, which should be array_map(). Again, using array_filter() with 'mysql_real_escape_string' would have absolutely no affect since mysql_real_escape_string() would not return false for any of the input. Even worse, that line would not perform the intended function of escaping the values, leaving the script open to SQL Injection attacks. That line should use array_map() with 'mysql_real_escape_string' as the second parameter. That last part should be //Escape input for query $textLines = array_map('mysql_real_escape_string', $textLines); - which will escape the values in the array and make then safe for use in a database query Yes, I goofed on the code on those two lines, but I did provide clear comments on what the intent of those lines was. So, just making the comment to flip the parameters without understanding what that would do or not do was just as bad, if not worse.
  19. Then you need to change that field to be a timestamp or a datetime field type. varchar is for text data. It would update based upon the time that the MySQL server is running on. Is the MySQL server not in Malaysia? If so, (assuming you don't have rights to change the default settings of the server) you have several options: 1) You can set the time as per the server's timezone and then change the value when you retrieve the value 2) You can set the timezone for the MySQL connection on each session 3) To make your application "global" you can do both of the above. Set the timezone of the MySQL connection to UTC and then output the values based upon the user's timezone. For now, I would suggest just doing #1. You can set the timezone for the session with MySQL using something like this: SET time_zone = 'America/Los_Angeles'; I assume you would want to execute that right after you make a connection to the MySQL server in your scripts. But, I've never used it before. EDIT: Look here for how the timezone can be specified http://stackoverflow.com/questions/9808160/mysql-time-zones
  20. Hmm, that code is not valid - there is no closing curly brace to match the opening curly brace after the if() condition. I assume there is more code since the line before the alert is simply an assignment and doesn't do anything. So, you must have other code that uses that value which is not working as you expect. Assuming the format errors above are just due to a lack of the entire code the only thing that comes to mind is that some of the code is dependent upon some other process completing first and the alert allows that to complete before you click "OK". It could even be an issue with field focus. Once the alert pops up and you click OK your focus may change allowing the process to complete successfully. Basically, you haven't shared enough of the code to really understand the problem.
  21. To expand on Requinix's post. It *most* circumstances you should store data in its "original" format. In other words, do not transform the data based upon how you think you will be outputting it. So, you should do things such as: Use trim() to remove uneeded spaces Provide error handling for invalid content (It is a bad idea to just remove invalid data without the user knowing it) Escape data to make it safe for use in a query or other means of handling (this all depends on how you will use it. If storing in a DB then use mysqli_real_escape_string(), prepared statements, etc. If storing in a comma separated file, then you need to properly escape for commas as part of the date, etc.) You should NOT modify the data before you store it based upon an intended output. So, if you plan to display the data on a web page you should normally not use htmlentites() or any other process to make the data safe for that output method before you store it. Instead, do that transition after you retrieve it and before creating the output. The reason for this is that you lose the ability to re-purpose the data for another need. For example, if you need to send the data as part of a JSON request, put into a plain-text email, etc. It would become "corrupt" for those uses. So, if you do not use htmlentities() or nl2br() before storing the data (which you shouldn't), then they would not affect any string length checks you perform on the data when it is submitted.
  22. Line 257 in your code above is this { Which is between the two lines that reference $File. Are you sure the error is not on the first instance? Try putting in some echo statements to verify echo "Before the if()<br>\n"; if ($File) { echo "After the if()<br>\n"; copy ($File, "$File_name"); echo "After the copy()<br>\n";
  23. Not quite. The first instance should be array_filter with only the array and no second parameter (which will remove empty values). The second instance should have been array_map() //Remove empty line $textLines = array_filter($textLines); //Escape input for query $textLines = array_map('mysql_real_escape_string', $textLines);
×
×
  • 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.