Jump to content

Jacques1

Members
  • Posts

    4,207
  • Joined

  • Last visited

  • Days Won

    209

Everything posted by Jacques1

  1. Long-running or even unlimited sessions can be implemented with a “remember-me” feature (just like in this forum). This is done on top of the standard PHP sessions and involves the following steps: If your site doesn't use HTTPS yet, you need it now. The user should have to explicitly request a long-running session (e. g. with a checkbox), because this is only safe in a trusted environment. By default, you should issue a standard PHP session. You don't want to user to be logged in forever on some shared PC. Create a separate database table with the the following fields: A hashed identifier, the user ID, the time when the session was started and the time of the last update. If the user checks the “remember me” box in the log-in procedure, you create a secret remember-me identifier with a secure random number generator. For example: bin2hex(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)) will generate 16 hexadecimally encoded random bytes. This identifier is stored in a remember-me cookie with the HttpOnly and Secure flag set. You hash the identifier with something like SHA-256. Then you store the hashed identifier, the user ID and the current time in your database table. On every page that involves the session, you first check if a standard PHP session is present. If that's not the case, you check if the user has provided a valid remember-me ID (hash the ID and look it up in your database). If this is the case, you start a new PHP session as if the user had just logged in. So the remember-me cookie will constantly spawn short-lived standard sessions. To the user, this looks like a single long-running session. Be aware that a remember-me feature is relatively difficult to implement and inherently unsafe. Often times, there are better alternatives: If your users are simply too lazy to type in their password all the time, they should use a password manager with an auto-type feature (like KeePass). Of course it's also possible to store the password in the browser, but then they should set a master password. If you don't want your users to lose unsaved input, simply save the data every few seconds.
  2. Simply format the number in your application when you display it. Or if you insist on a doing this with MySQL, use FORMAT() in your query.
  3. What does the error log of your server say?
  4. Besides the obvious security vulnerabilities already mentioned, your uniqueness check doesn't work in a highly parallel environment like a web application. If two processes request an unused name at the same time, your SELECT query tells both of them that they can have the name. In the worst case, you end up with a duplicate name despite your check. Only the database system can enforce unique values: Set up a UNIQUE constraint on the username column and simply try to insert the row. If that fails due to a constraint violation, you know the name is already taken. See this example implementation. Since you specially asked about security-related problems, I strongly recommend you learn the basics before you jump to the code. Security is not a trial-and-error business.
  5. I have to disagree. The extract() function with the default flags is actually harmful, because it blindly overwrites any variable that happens to have the same name as one of the array keys. This is perfect for causing nasty bugs and infinite confusion, but you wouldn't want this in your application. When you apply extract() to any kind of user-controlled data, you even end up with a massive security vulnerability, because now it's possible to actively inject variables and manipulate the control flow of the program. See the discussion about the ancient “Register Globals” misfeature (in a sense, extract() is even worse than that). Don't randomly import variables into the symbol table. Just use $row_variable['fieldname']. Yes, that's a few character more than just $fieldname, but it's much safer. And if you don't like typing, use an IDE with autocomplete.
  6. You obviously have only one PHPMailer instance, and it sounds like you just keep overwriting the messages without ever sending them. That of course doesn't make sense. I suggest you create a fresh mailer instance in every iteration, assemble the message and then immediately send it.
  7. In any case: While you iterate over your rows, you need to compare $option->id with the previously submitted value, be it $_POST['project'] or $_GET['project']. If the current option ID matches the submitted value, you emit a selected attribute. Of course you also need to remove the dummy option in case there's a preselected option, so you have to iterate over the rows before you assemble the HTML markup for the select element.
  8. The code you've posted doesn't make sense in any PHP version, because you're defining a function with no effect whatsoever: function pparams($sort) {global $sponsor, $school, $student, $instrument, $room, $time;} And then you try to access the $sort parameter from outside of the function: if (!$sort) $sort = "time"; Obviously the closing brace of the function definition is misplaced. Whether that's a copy-and-paste error or your real code, I don't know. In any case: If you want us to help you, we need the concrete error symptoms, all PHP error messages and all relevant code. It's not enough to tell us what you think is wrong.
  9. You should consider using a template engine like Twig or Smarty. Those PHPHTML gymnastics are fine for very simple pages, but when you're dealing with more complex structures, it's time to get rid of the spaghetti code and use a more systematic approach. Template engines were made for exactly this purpose. You can easily insert one template into another (e. g. a menu into a page), and you can even retroactively inject new HTML snippets into an existing HTML structure.
  10. Since you want a JavaScript solution, I'll move this thread to the JavaScript forum. In any case, you have to do the check server-side as well, because otherwise people will just disable your JavaScript code and select as many checkboxes as they want.
  11. Why do you even need to mention the parent page in the URL? In other words, why can't you just say index.php?page=0102? Isn't the ID of the subpage already unique? By the way, you really need to choose better identifiers for your pages. It might also be a good idea to review the overall architecture of your site. When people start to use weird numbering schemes to organize their pages, that's usually a bad sign (unless this was just an example).
  12. How is this not PDO? All you've done is replace the named placeholders with positional placeholders. Did you read my comment regarding the misplaced single quotes in your previous query?
  13. Remove the single quotes surrounding the placeholders. You should also get rid of the useless transaction. A single UPDATE query either suceeds or fails, there's nothing in between. To check if the update actually changed the data, use PDOStatement::rowCount().
  14. I have absolutely no idea what you're talking about. What is a “signature for a server”? Where's the code? What is your problem?
  15. Yeah, but do you understand what “length” actually means in this context? It's irrelevant for you (if it was relevant, you'd know).
  16. Well, there's definitely no table named “task” in the database you've selected. So you need to double-check both your credentials and your database. We cannot do that for you.
  17. You're randomly mixing mysql_* functions with mysqli_* functions. You cannot do this. They belong to two entirely different PHP extensions which are not related to each other (besides the fact that they both deal with MySQL). Actually, the mysql_* functions are hopelessly outdated and will be removed with the release of PHP7. The “var” keyword you're using in your class is also obsolete. It dates back to PHP4 which died somewhere around 2008. So it looks like you really need to update your learning resources. Nowadays, we use access modifiers (private, protected, public) instead of just “var”. What's weird is that you already use those modifiers for your methods. So I guess the “var” stuff was copied and pasted? Your database code is also somewhat shaky (no security, no proper error handling). I don't know. Maybe you should write your first class for a problem that you really understand. This database wrapper stuff usually just ends in a truckload of SQL injection vulnerabilities.
  18. The Mozilla Developer Network has plenty of examples, but they won't necessarily address the particular problems of your own code.
  19. The short version: The display width is irrelevant except for very special cases (like when you use ZEROFILL to pad your numbers with leading zeros).
  20. Your code has several problems: It is vulnerable to cross-site scripting attacks, because you insert the user input straight into your HTML markup. Of course this is just a toy example, but when you write real applications, you need to be much, much more careful when using innerHTML. You've forgotten to URL-encode the content of str before using it for the name parameter. This will lead to a misinterpretation of the input if certain characters are present. For example, try entering “Paul&Mary” or “Joe#Blow”. You'll see that both are truncated, because “&” starts a new parameter, and “#” denotes a URL fragment. You need to run str through encodeURIComponent(). You have no error handling. If the HTTP response code is something other than 200, you don't do anything. You're using the ajax() function as an event handler before it's even defined. Your ajax() function has a parameter, but you never use it. The code you've wrapped in a try statement cannot possibly throw an exception, so the whole statement is useless. I guess what you actually meant to do is catch exceptions in the function. So put the try statement into the function. In general, people today rarely write low-level JavaScript code to make Ajax requests. This is certainly useful for learning, but in the long run, you should look into frameworks like jQuery. Then you don't have to write tons of boilerplate code for such a simple task.
  21. When you want to delete all descendants, then ON DELETE CASCADE is perfect. I see absolutely no reason why one would prefer to do this manually. This is especially true for complex relations that would require you to write some big recursive function to traverse the dependency tree. So, yes, I would use (and have used) ON DELETE CASCADE for this purpose.
  22. Did you read what cyberRobot told you? By the way, I strongly recommend you use a proper IDE (like PHPStorm or Netbeans) instead of a plain editor. This will immediately warn you when you make syntax errors so that you don't end up with a whole bunch of broken code.
  23. Hm, that sounds pretty annoying, especially when it's a dialog that forces the user to click some silly “OK” button for he can do anything else. If at all, I'd display a warning next to the checkboxes so that the user can decide for himself when to fix the problem.
  24. Unchecked boxes aren't submitted at all, so you just have to count the elements of $_POST['pr'] (if you're using the POST method): if (isset($_POST['pr']) && count($_POST['pr']) > 4) { echo 'You can select at most 4 options.'; }
  25. The question is: What do you want to achieve? You've stated a lot of technical rules about natural keys vs. surrogate keys, manual queries vs. application queries etc., but I'd concentrate more on the underlying goal. If you don't define any referential action, the default is RESTRICT, which means MySQL will reject the UPDATE or DELETE query altogether. This is useful if updating or deleting a parent record should be considered an error. For example, you might want to force the application user to manually delete the child records before deleting the parent (for whatever reason). Using ON UPDATE CASCADE generally makes a lot of sense, because it allows you to safely update a parent key. If you think that the key shouldn't be updated at all, you should prevent that rather than preventing the propagation of the change. In other words: Make sure an UPDATE isn't possible in the first place. The referential action of DELETE queries, again, depends on your goals: Are you afraid of losing records? Then you should probably prevent DELETE queries altogether and set a “deleted” flag instead. For extra safety, you might use an explicit(!) RESTRICT action. Do you want to keep the child records after the parent has been deleted? Then you'd use SET NULL (assuming this is possible for the child records). Or do you want to cleanly remove all data that depends on the parent record? Then use CASCADE. So it's not about the type of the key or the origin of the query. It's about the 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.