-
Posts
4,207 -
Joined
-
Last visited
-
Days Won
209
Everything posted by Jacques1
-
The last database error can be fetched with errorInfo(). In fact, if you use the default PDO settings, then you must check every single statement for errors. Otherwise, the code will happily keep running, and you never know what happened (as you can see). A much better solution is to turn on exceptions so that PDO automatically throws errors instead of waiting for you to manually check the return values. For example, a proper configuration might look like this: $database = new PDO('mysql:host=localhost;dbname=YOUR_DB;charset=utf8', 'YOUR_USER', 'YOUR_PASSWORD', array( PDO::ATTR_EMULATE_PREPARES => false, // use actual prepared statements instead of client-side escaping PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // turn on exceptions PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // fetch associative arrays by default (optional) )); Note that your upload logic has several other issues: Users may willingly or unwillingly overwrite existing files. The problem is that there's a gap between checking if the file exists and allowing the script to use the filename. What if another request has already used the same filename in the meantime? Let's say two requests both want to upload a file named “kitten.jpg”. If the file doesn't exist yet, they're both allowed to use that name. However, now one of the requests will overwrite the file of the other request. Enforcing unique filenames also creates a denial-of-service vulnerability: What if a malicious user floods the upload folder with common filenames so that legitimate users can no longer take them? You allow the user to have double extensions like “.php.jpg”. This is a serious security issue and can lead to execution of arbitrary scripts depending on your webserver configuration. The solution is to not let the user choose the filename or the extension. Of course you can store this information in your database and display it to the user. But you must choose the actual filename and make sure it's unique. There are basically two ways to get unique names: You can either use the value from an AUTO_INCREMENT column. This leaks detailed information about the uploads of other users, which may or may not be a problem. Another option is to generate a sufficiently long random number: function generate_random_bytes($length) { $random_bytes = null; if (function_exists('mcrypt_create_iv')) { $random_bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); } elseif (function_exists('openssl_random_pseudo_bytes')) { $random_bytes = openssl_random_pseudo_bytes($length); } else { // Suppress warnings, because /dev/urandom is an OS-specific device $random_bytes = @file_get_contents('/dev/urandom', false, null, -1, $length); } if ($random_bytes) { return $random_bytes; } else { trigger_error('Failed to generate random bytes.', E_USER_WARNING); return false; } } A good filename would be bin2hex(generate_random_bytes(16)). That's 16 random bytes encoded as a hexadecimal string. Then attach a single permitted extension.
-
Please help me out on my PhP ECommerce Website
Jacques1 replied to studio23salons's topic in PHP Coding Help
I don't think you understood his reply. Nobody will debug your entire application for free. We can help you with concrete questions, but you can't just drop 1,000 lines of code and expect people to fix them. Would you do that for somebody else? Either narrow down the problem or hire someone to do your job. // I see you've cross-posted the same question in dozens of other forums. If your plan is to not get help from anyone in the future, you're on the right way. -
PHP spl_autoload_register, spl_autoload and __autoload functions
Jacques1 replied to Ansego's topic in PHP Coding Help
Registering an autoload function with spl_autoload_register() works just like registering it with __autoload(). The main difference is that spl_autoload_register() can be used to register multiple functions.- 6 replies
-
- spl_autoload_register
- spl_autoload
-
(and 1 more)
Tagged with:
-
How do i use a variable from a different php file
Jacques1 replied to korzxd's topic in PHP Coding Help
Do you realize that you've just allowed the whole world to place and run arbitrary PHP scripts on your server? Since you happily drop the user-provided file name into your generated PHP script, anybody can inject any PHP code they want. And then you run it. This is pretty much the worst-case scenario. This is what every server administrator is afraid of. I understand that you're new to PHP, but one thing you need to learn as early as possible is that you must not trust the user input. The Internet is full of script kiddies and actual criminals who would love to take over your server. Your webhoster will hopefully jump in if your machine goes berzerk and starts to flood innocent e-mail accounts with spam. But at that point, you've already caused damage, and they won't be happy about it. So if you write code and plan to actually upload it, please think about the consequences. It's also not be the best idea to download and run random PHP scripts without understanding what they do. What if they're harmlful? I mean, you wouldn't run unknown “.exe” files, right? My suggestion would be that you take a week or so and actually learn how file uploads work and how to get them secure. Then write your own code. Copy and paste sucks, and most people who upload their stuff to those code-for-free websites have no idea what they're doing. -
HTML natively provides validation attributes: <input type="email" name="email" required> And, unlike jQuery validation, this doesn't require JavaScript. The only reason for using jQuery would be if your users primarily run around with old versions of Internet Explorer. I also don't see how client-side validation solves your original problem. But if you're happy, I guess we can leave it at that.
-
The code is indeed a bit weird. A PHP script which writes a PHP script which sets a variable? Seriously? However, I do think it's valid to check the request method. The point is that the client made a POST request to add or alter data. How they made the request is irrelevant. Maybe they've clicked a submit button, maybe they've hit Enter, maybe the data was submitted with Ajax, maybe they've assembled a raw HTTP message. I don't care. Yes, you can have multiple submit buttons, but that's really a bad idea. If the user just hits Enter, the browser cannot tell which submit button they meant and seems to simply submit the first one. That's hardly acceptable. Of course you could try to block the Enter button with JavaScript, but this forces the user to turn JavaScript on and breaks standard UI behavior. The real solution is to not use multiple submit buttons in the first place. Just make multiple forms. Another problem is that the “value” of a submit button is actually the fancy label on top of it. I find it odd to base my application logic on a string like, say, “Upload your cute kitten videos NOW!”. And what if I want to change that label? Isn't the whole idea of modern programming to separate the logic from the presentation? Sure, you can “solve” this problem by using a button instead of an input element. But then again: Why care about the submit button in the first place? Long story short: It does make sense to check the request method rather than the submit button. Setting the error configuration at runtime is also problematic, because the error can happen before the script runs (a parse error, for example). This should be done in the php.ini or an application-specific .htaccess file or whatever. Also note that E_ALL includes E_NOTICE. And adding E_STRICT is only required in legacy PHP versions before 5.4.
-
So what are we supposed to do now? We can't see your screen from here. If you want us to help you, then you need to post the code and describe the problem. No, “doesn't work” is not a valid problem description. In fact, we knew that already, because otherwise you probably wouldn't be here. So what's the problem? Does the INSERT query succeed at all? What's the return value of lastInsertId()? And why do you even want the last insertion ID? Don't you set it manually with $abc['member_id']?
-
It does check for digits only. And since a comma isn't a digit, it will not accept “1,5”.
-
Who said it is? Did you try ctype_digit()? Or do you just assume it's not what you need?
-
This indeed makes no sense. First of all: Never trust $_SERVER['HTTP_HOST']. This variable is defined by the client and can contain any garbage they want. If you carelessly insert the raw value into your HTML markup or queries, it can even be used for a code injection attack. Secondly, you already have a variable with the host name: $_SERVER['HTTP_HOST']. Your $url variable is just useless. I'm not sure why PHP programmers have this strange idea that values are only “real” if you put them into a custom variable. The proper solution is to actually define a variable or constant with the host name and then include this in every script. Script inclusion is a natural part of programming, and you will need this either way as soon as your application becomes non-trivial. Trying to avoid it is rather silly.
-
When you can no longer find you own variables, it's definitely time to refactor. Wow. You really looove repetition, don't you? This looks more like a typing exercise than programming. And at least half of your code doesn't do anything, because you just keep overwriting the same variables. I think you should scrap the code and start over, this time with PDO and a more intelligent approach. I know, it's painful to throw away code, but this is just unmaintainable. Take it as a lesson: If the only keys you press are Ctrl and V, you're doing it wrong. Do you know what a loop is?
-
Says who? The problem with abusing strings as pseudo-booleans is that it creates ambiguity and can easily end in total chaos. It's simply bad design. If this is a VARCHAR field, then your database system will accept any string. Could be “yes” or “YES!” or “true” or “iliketurtles”. Sure, “this shouldn't happen”™. But depending on who enters the data and how the rest of your application looks like, it can happen. And then good luck cleaning up the mess. This “yes”/“no” thing may be OK for an Excel spreadsheet. But when you're dealing with a real database system, you should use real data types and not rely on magic strings. It also seems you're confusing two different things: How you store the data has nothing to do with how you display it. Of course you can display the answers as “yes”/“no” on your page. But you store them as booleans.
-
You're confused. The values are not different: Both arrays contain the strings “yes” and “no”, and that's exactly what array_intersect() tells you. The only thing that's different are the associations between the keys and the values. If you care about the associations and not just the values, then you need the already mentioned array_intersect_assoc(). Actually, the correct solution would be to use a query and not fumble with those arrays in the first place. This “yes”/“no” stuff is also more than questionable. We have booleans for this.
-
The problem is that you drop the user input right into the query string without escaping it. That's what needs to be fixed. Any PHP value you want to insert into the query must be esccaped and quoted: $sql_query = " SELECT leerlingnummer2 FROM nene WHERE leerlingnummer2= '".mysql_real_escape_string($_POST['leerlingnummer2'])."' "; See the mysql_real_escape_string()? This prevents the user from breaking out of the string expression. So no matter what they send you, it will all just be interpreted as the content of this string and never as an actual SQL query. Now you can add your validation on top of it if you want to. But the point is that all input must be escaped and quoted. Note that the mysql_* functions you're using are obsolete since almost 10 years and will be removed in one of the next releases. Haven't you seen the big red warning signs? Nowadays, we use PDO or MySQLi. Those also support much better security mechanisms, namely parameterized statements: Instead of throwing your SQL and the user input into one big query string, you strictly separate the two. You first send a “query template” with placeholders to the database system. This template is parsed just like a normal query. And then you assign your data to the placeholders. Since the data is now strictly separated from the actual query, there's no risk of SQL injections. It's simply not possible to manipulate the query through the data. So I strongly recommend you give up the old MySQL extension and switch to PDO. If that's not an option, you need mysql_real_escape_string().
-
All right, now we got total confusion. First of all, data validation is not a security feature. This is especially true for client-side validation like the type attribute, because this can easily be circumvented by anybody. All the user has to do is remove the attribute in their browser or not use a browser in the first place. I think you should forget about the number stuff for now and concentrate on the real problem. You said that people may be able to destroy data if they give you the “wrong” input. Then there's definitely something wrong with your query or your application logic. Can you show us the query and explain what exactly you mean by “destroying data”?
-
Social Network Relational Database Problem
Jacques1 replied to ljfreelancer88's topic in PHP Coding Help
There seems to be a lot of confusion regarding the basic logic. Friendship is obviously a relationship between two entities: Person x is a friend of person y. So where does the second person come into play in your function? I only see a single parameter for a single user ID. I would expect something like this: function isFriendOf($possibleFriendID, $userID) { } And now you simply check if there's any row with $userID as the my_id and $possibleFriendID as the friend_id. However, I think the whole concept needs some clarification. If person A is a friend of person B, does that automatically make B a friend of A as well? Then how do you prevent people from inviting themselves? Do you require confirmation from the other user? It might be a good idea to choose a different term which makes it clear that one direction doesn't necessarily imply the other direction. Something like “has_invited”.- 6 replies
-
- relational database
- php
-
(and 1 more)
Tagged with:
-
Fatal error: Call to undefined method Mail::AddAttachment() in
Jacques1 replied to vbcoach's topic in Third Party Scripts
Well, as you can see, there is no AddAttachment() method in the class. And there's nothing you can do about it except programming it yourself. But this code is ancient and pretty bad, anyway. The var keyword tells me it was probably written for PHP 4 somewhere around the year 2000. Let it rest in peace and use a proper mailer library. -
The best method is to RTFM.
-
Or just use a for or while loop: <?php $start = '2014-05-01'; $end = '2014-07-01'; $current_date = new DateTime($start); $end_date = new DateTime($end); while ($current_date <= $end_date) { echo $current_date->format('Y-m-d'), '<br>'; $current_date->modify('+2 weeks'); }
-
You didn't read the manual. The function utf8_encode() transcodes a string from ISO 8859-1 to UTF-8. Since your input clearly isn't ISO 8859-1, this function doesn't help you at all. I guess what you actually want is declare the character encoding of the HTML document as UTF-8 so that browsers display it correctly. Put this somewhere on top of your script: header('Content-Type: text/html;charset=utf-8'); In addition to this, you also have to set the encoding of the database connection to UTF-8: // If you're using PDO, set the character encoding in the DSN string. $database = new PDO('mysql:host=localhost;dbname=YOURDB;charset=utf8', 'YOURUSER', 'YOURPASSWORD', $options); // If you're using MySQLi, set the encoding right after the connection $database->set_charset('utf8'); // If you're still using the old MySQL extension ... mysql_set_charset('utf8'); Do not use a SET NAMES query. This silently changes the connection encoding without notifying PHP about it. As a result, all escaping functions will continue to use the old encoding and may stop working entirely.
-
This makes absolutely no sense to me. What exactly is the whole point of your “public ID”? I mean, what's the goal you're trying to achieve with this?
-
Trying to figure out the image type server-side doesn't help either, because a perfectly valid image can still contain malicious HTML (in a comment section, for example). Even worse, older versions of Internet Explorer will interpret the image as HTML, no matter what file extension and content type you serve. Long story short: File uploads are a security nightmare. This isn't a quick job you can do in 10 minutes with a few lines of PHP code. If you absolutely must have this feature, take at least a week of your time to understand the risks and how to deal with them. A rough overview: Store the files outside of your document root. This makes sure your webserver will never execute them as code, even if you screw up the file extension (which you did). The file name must be a random number to prevent people from overwriting existing files (accidentally or on purpose). Store the original file name in the database. There doesn't have to be a file extension, just store the type information in the database. If you do want an extension, then you must set it to one of the allowed values. Never accept the file extension from the user. Set the file permissions to the absolute minimum (e. g., 0600). Write an access script which takes an image ID, reads that image, looks up the type information in the database and then serves the image with the right type. Place the access script under a separate domain. This gives you basic security, but it does not cover bad browsers turning your images into HTML. For that, you must prevent direct access to the images and instead embed them in an img element on a page.
-
This is no code-for-free service. If you're talking about automated spam, check out reCAPTCHA. Home-made CAPTCHAs may be fun, but they're no match for any halfway intelligent spam bot. Trap fields also help: You make an invisible field, and if the client fills it out, you can be pretty sure it's a bot. Last but not least, there are blacklists of known spammers. See if they cover “your” spammers as well.
-
That's not really a good idea, because then you have to save all user input in the session so that you can restore it on the form page. And you again run into the refresh issue. I would do it the other way round as explained above: You do the processing on the form page. And then you redirect on success.
-
I understand that you want to check if the fields are empty, and this is perfectly fine. The problem is that you don't understand how empty() works, which is why I'm trying to explain it. But of course we can leave it at that if you don't care. You don't need to. Make a single script which displays the form and processes all form submissions. If the input is wrong, the user stays on the same page and sees the form again. If everything is fine, you redirect the user to some other page. This solves two problems at the same time: You get your form, and the user won't accidentally submit the form data again by refreshing the page (see the POST/redirect/GET pattern): <?php // the form processing logic $field_empty = false; if ($_SERVER['REQUEST_METHOD'] == 'POST') { if (empty($_POST['test_field'])) { $field_empty = true; } else { // The input is fine. Save it and then redirect the user header('Location: https://yoursite.com/success.php'); exit; } } ?> <?php if ($field_empty): ?> <p>You did not fill out the form.</p> <?php endif; ?> <!-- Your form --> <form method="post"> <label for="test-field">Please fill out the field.</label> <input id="test-field" type="text" name="test_field"> <input type="submit"> </form>