-
Posts
4,207 -
Joined
-
Last visited
-
Days Won
209
Community Answers
-
Jacques1's post in Function returns wrong value? was marked as the answer
You're trying to compare a number (0) with a string (ufo::LARGE). In a strongly typed language, your code wouldn't even run. In a weakly typed language like PHP, the values get converted.
And the integer value of "LARGE" is in fact 0:
<?php var_dump((int) 'LARGE'); var_dump(0 == 'LARGE'); If you don't want this to happen, don't compare apples and oranges. I wouldn't even allow invalid values for the $mp_size attribute. Write a proper setter which rejects invalid values.
-
Jacques1's post in A data structure problem ! was marked as the answer
The problem of the above database layout is that it doesn't implement any of the rules, thus allowing nonsense data. For example, a single staff member with an arbitary rank (let's say the janitor) can recruit, pre-approve and approve an assistent manager.
You can try to fix this with lots of application-side checks, but then you may still end up with nonsense data. What if the data is inserted or edited directly? What if one day there's a bug in the ever-changing application code? You'll never know if the data you're relying on is actually valid.
I'd do this the other way round: Spend a lot of time on a proper database layout which will only accept correct data. This will in turn save you a lot of code and bugs.
I see three different recruiting cases:
The manager can recruit a person as an assistent manager or deputy manager An assistent manager can suggest a person as a deputy manager or executive, which must then be approved by the manager A deputy manager can suggest a person for an executive role, which must then be approved by both an assistent manager and the manager (or just the manager, I assume) Possible relations:
staff(staff_id, last_name, first_name, ...) assistant_managers(staff_id) deputy_managers(staff_id) applicants(application_id, last_name, first_name, ...) manager_recruitments(applicant_id, role) assistent_manager_recruitments(applicant_id, role, approved_by_manager) deputy_manager_recruitments(applicant_id, role, approving_assistent_manager_id, approved_by_manager) You can simplify the relations with views. The physical layout isn't necessarily the layout you have to use when accessing the data.
Note that the above data model allows an applicant to have multiple roles at once. If you want to prevent that as well, you'll need an additional table for all applications (which consist of an applicant and a role).
-
Jacques1's post in autosetting a field in a mysql based on the value of another 2 fields in the same table was marked as the answer
Why do you need a physical column for the AND operation when the value can simply be derived ad hoc? Precalculating the result is actually a bad idea, because you need to update it whenever any of F1 or F2 change. And if you forget to update it just once, you'll end up with garbage data.
Simple calculate the AND result in the query. You could also use a view which contains a virtual F1_F2 column that is calculated from the physical F1 and F2 columns.
-
Jacques1's post in identifying a page to be the true one. was marked as the answer
What do you mean by “impersonating”? Phishing? This cannot be fixed with code, because phishing attacks happen outside of your application.
However, you can do something about other attacks:
The entire site including the reset pages should be delivered over HTTPS so that e-mail addresses and passwords cannot be intercepted. Use a CAPTCHA on the request page so that an attacker cannot automatically make you send a large amount of e-mails to an arbitrary address. Make sure the request page doesn't reveal if an address is registered or not. Either ask for the public username instead of the e-mail address. Or send out an e-mail for any address (if it's not registered, simply say that in the e-mail itself). -
Jacques1's post in Using this famous password library gives me an error on live server. Why's that? was marked as the answer
So what is line 19 in your password.php script? There's no opening brace on line 19 in any of the official versions.
Is it “namespace {”? Then you're appearently running an ancient, long-abandoned PHP version (something prior to 5.3).
-
Jacques1's post in Using urlencode() was marked as the answer
The second code snippet doesn't make a lot of sense, because you're blindly applying urlencode() to a complete part of the URL. This will not only fudge up forward slashes. A query or fragment will also be affected.
You need to apply the encoding while you assemble the URL or URL part so that you know exactly what you encode (e. g. an individual path segment or parameter).
-
Jacques1's post in When is http_response_code() ever needed? was marked as the answer
Yes. It does not somehow alter the PHP configuration to send a 400 response code forever – if that's what you're worried about. Only the pending response is affected.
-
Jacques1's post in phpmailer was marked as the answer
PHPMailer validates the provided e-mail addresses, so they cannot be used to inject headers.
However, a library doesn't magically prevent all possible vulnerabilities. For example, in your above code you print mail errors directly on the screen, which can leak critical information about you server. Another common problem is to insert raw input into an HTML mail, which can lead to cross-site scripting vulnerabilities.
So writing secure code is still your responsibility as a programmer. A library can only take care of specific problems.
-
Jacques1's post in email verification security concerns was marked as the answer
Your send_mail() function has no protection against mail header injection. The above code with mostly hard-coded arguments may not be vulnerable, but that's just a happy coincidence. As soon as you have to deal with dynamic input, you will run into security problems.
Using the low-level mail() function is generally a bad idea, because it's far too dangerous and error-prone. You should use a proper library like PHPMailer instead.
This code makes no sense.
A HMAC is a message authentication code used to protect data from manipulation. You don't have this kind of data. And the third argument must be a (binary) cryptographic key, not a simple name. I'm surprised that PHP even accepts that input.
Neither hashes nor HMACs make sense in this context. You need to generate a binary random number and then encode it to make it human readable. A hash is only used to safely store the random number. So the procedure is as follows:
generate random bytes encode the random bytes (hex-encoding is usually the most robust variant) and send the encoded token in an e-mail hash the raw random bytes and store the hash in the database; a simple SHA-256 hash is enough in this case, because random bytes cannot easily be brute-forced like a password from a human user -
Jacques1's post in Is chaining methods considered good or bad practice? was marked as the answer
It's considered good practice, simply because it's both nice to read and nice to write. There's even a design pattern for it: The Fluent Interface.
The only reason why PDO isn't fluent is that it supports legacy error handling and uses the return values to indicate errors. Without this baggage, I'm sure our code would look exactly as you suggested (including the formatting).
-
Jacques1's post in possible to print the current value of enum? was marked as the answer
// Moved from JavaScript forum
Whatever language that is, it's not JavaScript. Are you confusing Java and JavaScript? Those are two entirely different languagues not related in any way.
If you do mean Java, your question still makes no sense to me, because you've already answered it yourself:
System.out.print(car); This does exactly what it says. It prints the name of the enum constant.
-
Jacques1's post in "global" nginx configuration was marked as the answer
nginx has the include directive which does exactly what the name says. I'm surprised you couldn't find it, Darghon.
Many settings can also be declared at the top level rather than per server block. This makes life even easier, because the values are automatically inherited but can still be overriden whenever needed.
What are those global settings, anyway?
-
Jacques1's post in XSS prevention was marked as the answer
XSS has nothing to do with databases or input validation. It's an output problem caused by programmers who naïvely insert data (from any source) into HTML contexts.
This cannot be solved with validation, because
formal validity doesn't mean that the data is safe in every possible context. For example, I could give you a perfectly valid e-mail address which is an XSS vector at the same time. Why? Because the format of e-mail addresses was never meant to protect web applications from XSS attacks. Why should it? it's impossible to predict the context in which the data will be used. There's not just HTML. There are thousands of different languages and data formats with distinct syntax rules, and the data may be a threat to every single one of them. a lot of data cannot be validated at all. For example, how would you “validate” the posts on this forum? We obviously have to write down HTML markup and JavaScript code all the time. That's the whole point of this site. XSS must be prevented during the HTML rendering process. The best solution is to use a proper template engine like Twig which automatically applies HTML-escaping to all outbound data. The second-best solution is to write a wrapper for the htmlspecialchars() function. Using htmlspecialchars() directly is not recommended, because it's extremely error-prone. In my experience, almost nobody understands how to use it correctly.
In addition to HTML-escaping, you should use Content Security Policy. This allows you to define strict rules for JavaScript execution and block many attacks.
-
Jacques1's post in php timer was marked as the answer
The whole approach sounds rather weird.
You've implemented a timer with pure PHP? How does that work? Timers are classical client-side features, i. e. a task for JavaScript. Of course you can and should also store the time on the server to prevent cheating, but all the visuals should be done entirely with JavaScript.
Since you're storing the time in the session, what happens when the session is destroyed before the building is finished? Does it simply disappear? You'll probably want to use the database instead.
And why exactly do you have to use this weird date("his") stuff instead of a proper timestamp? Do use time()!
-
Jacques1's post in xss protection? was marked as the answer
Using htmlspecialchars() directly is difficult and often leaves your application open to more subtle attacks. Use a proper wrapper:
/** * HTML-escapes a string so that it can safely be included in an HTML document * * @param string $unsafe_input the string which should be escaped * @param string $encoding the character encoding of the input string * * @return string the escaped string */ function html_escape($unsafe_input, $encoding) { return htmlspecialchars($unsafe_input, ENT_QUOTES | ENT_SUBSTITUTE, $encoding); } Note that escaping is dependend on the character encoding, so you should have a constant or configuration value for the encoding of your HTML documents:
<?php // UTF-8 is recommended for modern applications const APP_HTML_ENCODING = 'UTF-8'; <?php // require_once the functions and constants here // unless your webserver already sets the encoding attribute in the Content-Type header, do it here header('Content-Type: text/html;charset=utf-8'); $test_input = '"></div><script>alert("XSS")</script><div data-dummy="'; ?> <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"> <title>Page title</title> </head> <body> <!-- testing the escape function --> <div data-test="<?= html_escape($test_input, APP_HTML_ENCODING) ?>"></div> </body> </html> -
Jacques1's post in Restful Api was marked as the answer
The order of your parameters is wrong: In the bind_param() call, you assume it's (ID, name), but in the query it's actually (name, ID). So you need
$stmt->bind_param("si", $name, $id); Using the number of affected rows as an error condition is also a bad idea, because it's perfectly normal for an UPDATE query to have no effect (e. g. when a previous process has already updated the value). At best, you'd include the affected rows as informational data. To get real errors, enable error reporting for MySQLi before you establish the database connection:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); Now you'll get a mysqli_exception whenever a query fails. If you leave the exception alone (meaning: you don't catch it), PHP will automatically emit a 500 response code to signal an error.
-
Jacques1's post in trying to create a 2d array on the fly was marked as the answer
Assuming the subject/grade combinations are unique:
$descriptors[$row['subject']][$row['grades']] = $row['descriptor']; You need better variable names than "descriptors" and "row", though.
-
Jacques1's post in elseif syntax was marked as the answer
You can't have an "elseif" after an "else". The "else" marks the end of the statement (as in: If none of the above is true, execute the following code).
It's
if (...) { ... } elseif (...) { ... } elseif (...) { ... } ... else { ... } If your code "just gets stuck", that means you need to fix your error reporting as well. PHP always tells you exactly what's wrong.
-
Jacques1's post in Turn off error message at Get_file_content was marked as the answer
There's the error suppression operator.
Whether that's a good idea is debatable, though, because it will suppress all errors, including serious ones. Consider using a more professional HTTP client like cURL.
-
Jacques1's post in Script not working was marked as the answer
The bigger picture is that you need to stop writing spaghetti code.
Right now, you have JavaScript code within 90s HTML markup within PHP code, next to CSS within HTML within PHP. No wonder you spend most of your time struggling with syntax errors! You've reached the point where you no longer understand your own code.
JavaScript code and CSS declarations belong into external files. This will massively reduce the complexity and size of your PHP scripts, making syntax errors much less likely. The PHPHTML pasta can be untangled with a template engine like Twig, which will also fix dozens of cross-site scripting vulnerabilities in your current code (it seems you haven't even thought about security before).
While it's theoretically possible to generate dynamic web pages with pure PHP, this requires a lot of discipline and security awareness. I don't recommend it.
Last but not least, you should replace your current code editor with a proper IDE (integrated development environment) like Netbeans or Eclipse. This will warn you immediately when you fudge up the syntax, giving you a chance to fix the error yourself.
-
Jacques1's post in how to use php associative array in JS was marked as the answer
Objects aren't ordered, so the loop can start anywhere. The (inefficient) loop also isn't necessary. Use the built-in hasOwnProperty() method mentioned above.
-
Jacques1's post in Evaluating POST data in PHP was marked as the answer
So you want to check if the grade parameter does not exist at all?
if (!isset($_POST['grade'])) ... or
if (!array_key_exists('grade', $_POST)) ... -
Jacques1's post in check files exist was marked as the answer
You have to move the return true behind the loop that that it's only executed if all files exist.
Or use a boolean variable for clarity:
$filenames = ["index.html", "areas.html", "test.html", "example.xls"]; $all_files_exist = true; foreach ($filenames as $filename) { if(!file_exists($this->skeleton_dir.$filename)) { $all_files_exist = false; break; } } return $all_files_exist; -
Jacques1's post in structuring array help was marked as the answer
array_push() appends a value to an array, so there are necessarily two arguments (or more). If you have less, your code makes no sense.
It seems what you actually want to do is store a value at a specific index, which has nothing to do with array_push():
$array[$location][$i] = $connection->sheets[0]["cells"][$i][2];