Jump to content

Jacques1

Members
  • Posts

    4,207
  • Joined

  • Last visited

  • Days Won

    209

Everything posted by Jacques1

  1. You can try it yourself. <?php echo 'Output from required file'; session_start(); Unless you have output buffering enabled, the session_start() call will fail due to the previous output. HTTP messages (which is what PHP sends to the browser) have headers on top and the content below. As soon as you send the content, it's no longer possible to go back and add headers for cookies or other purposes. I'm talking about Twig sandboxing. It allows you to specify exactly what a template can and cannot do. Programming is all about using libraries! If your application doesn't use any library, then it's either trivial, or you're spending way too much time reinventing the wheel. PHP has several package manager (like Composer) which make it very easy to include third-party libraries. You can avoid a lot of things. Like I said, you could replace your PHP scripts with thousands of lines of C code. But why would you? Being a good programmer means choosing the right tools for the job, not limiting yourself to the most basic tools. I understand that a library like Twig can be scary at first, simply because it's something new. But it pays off. You've already decided to use jQuery instead of plain JavaScript, so why not do the same with PHP?
  2. Twig is a completely separate language designed specifically for templating. Compared to PHP, it has a much more compact syntax, several security features (like auto-escaping and sandboxing) and intelligent templating techniques like inheritance and macros. For example, a base template would look like this: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>{{ title }}</title> {% block head_items %} <link rel="stylesheet" href="res/style/main.css"> <script src="res/js/lib/jquery-1.11.3.js"></script> {% block additional_head_items %}{% endblock %} {% endblock %} </head> <body> {% block content %}{% endblock %} </body> </html> This allows you to safely insert data (all variables like the title are automatically HTML-escaped) append new scripts or styles to the ones you already have by default completely override the default head elements in case you have a page that doesn't need jQuery or has a special style simply insert the page content into the body element (no need to assemble the various document parts yourself) A concrete page template might look like this: {% extends "base.twig" %} {% block additional_head_items %} <script src="res/js/lib/uploader.js"></script> {% endblock %} {% block content %} <p>This is the content of the example page</p> {% endblock %} This appends an uploader script to the document head and then inserts the page content into the body. PHP has none of those features. Yes, Twig happens to be implemented with PHP, but that doesn't mean it's “just PHP”. This is like saying that we might as well use C instead of PHP, because PHP happens to be implemented with C. (Ab)using PHP as a template engine is inherently insecure for two reasons. First, even the tiniest HTML fragment is technically a full-blown PHP application which can do just about anything: read and change files on the server, access the database, load arbitrary code (possibly even from a remote location), perform network operations. This is completely unnecessary and a huge risk, because if any of those mini-applications gets compromised, you're screwed. Secondly, PHP has no concept for systematically escaping data. It assumes that the programmer escapes everything by hand and never makes a mistake. We all know this is unrealistic. In the real world, many programmers have never even heard of escaping, and those who do know it constantly screw up. Just look at the security history of any PHP application, and you'll see the same cross-site scripting vulnerabilities over and over again. Twig has a far more realistic and robust approach: If you use sandboxing, your templates can only do what they're supposed to do (i. e. generate HTML markup). And if you use auto-escaping, you can eliminate the vast majority of XSS vulnerabilities.
  3. If you do the inclusion on top of the script, that's a problem, because PHP cannot start/resume a session or send cookies once there's output (unless buffering is enabled). And as NotionCommotion already said, you should really use a template engine. Assembling HTML documents from various PHP scripts is 90s technology. Yeah, it kinda works, but it's cumbersome, inflexible, insecure and just hopelessly outdated. Modern template engines are far more powerful. You can define a base document and then override the page-specific parts. You can even change the title or add new CSS/JavaScript links to the head, which is not possible with a plain require_once.
  4. Handing out fake e-mail addresses is a bad idea. Either make it clear that the user isn't supposed to use the From address (e. g. the classical noreply@yourdomain.dom). Or use real addresses on your domain which accept and forward mails. I would avoid the latter at all costs, because it makes you responsible for managing potentially sensitive data and preventing spam/malware. If there's no need for that, don't do it.
  5. What is the number you think is incorrect, and what is the number you think is correct? Looking at the code alone, there are several errors: The outer loop must run while $i < $numberCount - 12, otherwise you're skipping the last two digits. The inner loop must run while $j<= $i + 12, otherwise you're multiplying 14 numbers rather than 13. The optimization is wrong. I recommend you first get your code right and then worry about optimizing it.
  6. The whole code is strange, to say the least. For example, why would you try to store the database connection in the session? It's not possible, and it doesn't make any sense. You also need to learn how to use mysqli correctly. Or better yet, forget about mysqli and learn PDO instead. It's much more programmer-friendly. Then you absolutely must learn the basics of security. This tiny piece of code is already full of vulnerabilities, and if you plan to put it online, you put your server and all of its data at a huge risk. Learn how to prevent cross-site scripting, SQL injections and cross-site request forgery. That's the minimum every programmer needs to know. The function for connecting to the database, implemented with PDO: <?php const DB_HOST = 'localhost'; const DB_USER = '...'; const DB_PASSWORD = '...'; const DB_NAME = '...'; const DB_CHARSET = 'UTF8'; function connectToDB() { $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHARSET; return new PDO($dsn, DB_USER, DB_PASSWORD, [ PDO::ATTR_EMULATE_PREPARES => false, // use actual prepared statements, don't emulate them PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // make PDO throw an exception in case of an error PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // fetch associative arrays by default ]); } Helper function for HTML-escaping to prevent XSS attacks: <?php const HTML_ENCODING = 'UTF-8'; function htmlEscape($rawInput) { return htmlspecialchars($rawInput, ENT_QUOTES | ENT_SUBSTITUTE, HTML_ENCODING); } The main script: <?php session_start(); $databaseConnection = connectToDB(); // check if the user is logged in if (!isset($_SESSION['id'])) { die('You must be logged in to view this page.'); } // Did we receive a POST request? if ($_SERVER['REQUEST_METHOD'] == 'POST') { // check if all required parameters are present if (!isset($_POST['username'])) { die('Missing parameter: username'); } // validate the username if (trim($_POST['username']) === '') { die('Username must not be blank or consist only of whitespace.'); } // create a prepared statement to safely pass the username to the database system $usernameUpdateStmt = $databaseConnection->prepare(' UPDATE users SET username = :username WHERE id = :id '); $usernameUpdateStmt->execute([ 'username' => $_POST['username'], 'id' => $_SESSION['id'], ]); // the query will automatically throw an exception in case of an error, so if we've reached this point, everything is OK die('Username updated!'); } $userStmt = $databaseConnection->prepare(' SELECT username FROM users WHERE id = :id '); $userStmt->execute([ 'id' => $_SESSION['id'] ]); $user = $userStmt->fetch(); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Title</title> </head> <body> <!-- If you want to post the form to the same page, leave out the action attribute entirely; do not use $_SERVER['PHP_SELF'] --> <form method="post"> <!-- The for attribute of labels must point to an ID, not a name; alternatively, just wrap the input in a label element --> <label >Username <input type="text" name="username" value="<?= htmlEscape($user['username']) ?>"></label> <button type="submit">Update</button> </form> </body> </html>
  7. My prepared statement only updates the columns where the input value is not NULL, all others keep the old value. This a conditional update just like yours, but it doesn't require you to literally leave out the columns. You shouldn't use empty(), though, because it has some confusing results. For example, the string “0” is considered “empty” and will be skipped, which makes no sense from the user's perspective. If you want to skip empty strings, do that explicitly: 'title' => (isset($_POST['title']) && $_POST['title'] !== '' ? $_POST['title'] : null) By default, in_array() uses sloppy comparisons, which is very confusing and a common security problem: var_dump( in_array(0, ['foo', 'bar']) ); // true var_dump( in_array(true, ['foo', 'bar']) ); // true var_dump( in_array('1e3', ['1000']) ); // true (WTF) As you can see in the last case, even two strings(!) will be affected by PHP's crazy type juggling. If you want in_array() to only return true when the input is fact present in the array, you need to enable strict checks with the third parameter.
  8. You don't need dynamic columns at all: $updateStmt = $databaseConnection->prepare(' UPDATE table SET title = IFNULL(:title, title), data = IFNULL(:data, data) WHERE userID = :user_id '); $updateStmt->execute([ 'title' => @$_POST['title'], 'data' => @$_POST['data'], 'user_id' => $id, ]); When you do encounter a case where a dynamic query is in fact necessary, I would use a carefully tested function instead of inline code always set the strict flag when calling in_array() – weak typing is a bad idea for security, especially PHP's version of weak typing insert the hard-coded string rather than the user-provided one; again, PHP is a crazy language
  9. Don't just randomly add code somewhere in your application. All that will do is break your shop. First off, have you checked if WooCommerce can skip products that are out of stock? Have you looked for plug-ins? This is a standard problem, so I'd be surprised if you were the first person ever to have it. Secondly, if you do have to implement this yourself, a) create a module/plug-in, don't modify the core application, b) filter the database query, not the HTML stuff.
  10. So the only line of code you've written yourself is the one I've already asked you about: $text = 'date','time','pua','doa','passenger','pax'; Long story short: This is not valid code. Like every language, PHP has a specific syntax, and if you want your code to run, you need to learn and apply those syntax rules. Codeacademy has a crash course for PHP which can help you with that. I'm guessing you want string concatenation: $text = $_GET['date'].' '.$_GET['time'].' '.$_GET['pua']; // ... and so on But again, you have to learn the syntax. Blank pages also mean you haven't set up a proper test environment. Install XAMPP (or similar software) on your PC, then make PHP display all errors directly on the screen.
  11. You should be more specific. What exactly does the script do? Crash? Show an error message? Send a wrong SMS? The var_dump() function is very helpful for analyzing variables and figuring out what's going on. What is this line supposed to do: $text = 'date','time','pua','doa','passenger','pax';
  12. No. When the code is syntactically invalid, it doesn't get executed at all, so any runtime error settings have no effect. Besides that, it makes a lot more sense to set up a proper development environment with the right PHP settings rather than messing with the configuration on a per-script basis.
  13. You definitely need to group functions by their purpose. Stuffing everything into one big functions.php script will quickly lead to an unreadable, unmaintainable mess.
  14. The jQuery 2 and 3 branches don't support very old browsers like IE8. You have to either give up IE8 support yourself or stick with jQuery 1.
  15. Yes. It's not incorrect. I'm simply saying that you can get rid of the inner loop when you realize that only two factors change when you move to the next 13 numbers: The first factor is removed, instead you append the following number as a new factor. All other factors are identical, so you don't have to recaculate the entire product.
  16. You cannot have arbitrarily long integers in PHP (and most other languages). If you want to do arithmetic with big numbers, you need to use strings and a special library. A lot of your variables don't make sense either. It seems you're trying to do variable declarations like in statically typed languages, but PHP is a dynamic scripting language. Variables are created automatically when you first use them. As to the actual problem: You can get rid of the inner loop if you use a “rolling” product which you just multiply by the next number and divide by the first factor (if that factor isn't 0). The if statement is also in the wrong place.
  17. I couldn't agree more. Aggressive ads are already the cancer of the Internet, but popping up a new window when I want to close the current one makes me want to punch the developer in the face. Seriously, stop it. Even if you manage to get your code past the browser's malware filter, your users will be truly annoyed and either turn their ad blocker all the way up or leave your site forever. It's just counter-productive.
  18. You can make the code a lot shorter and safer: Remove all this try-catch clutter. It's useless, repetitive and potentially dangerous, because printing internal error messages on the screen gives an attacker lots of information about your system. Instead, cover all errors (not just exceptions) with a central error handler. PHP actually has a pretty good system built in: If you turn display_errors off (which is what you should do in production), fatal errors lead to a blank page and a 500 response code. Your webserver should then be able to show a custom error page. See The mystery of errors and exceptions. Take advantage of standard PDO fetch methods instead of reinventing the wheel. For example, if you need all rows, just call PDO::fetchAll(). Consider using a template engine like Twig to get a clean interface between the PHP code and the HTML markup. So this: try { $result = $dbConnection->query('SELECT id, name FROM author'); } catch (PDOException $e) { $error = 'Error fetching list of authors.' . '<br />' . $e -> getMessage(); include '../includes/error.php'; exit(); } foreach ($result as $row) { $authors_in_db[] = array( 'id' => $row['id'], 'name' => $row['name'] ); } include 'form.php'; exit(); should be replaced with this: $authors = $dbConnection->query('SELECT id, name FROM author')->fetchAll(); // now pass $authors to the template; or use your old form.php script See the difference?
  19. A lot of things “can be done”. I can punch myself in the face while singing Ave Maria. But does it make sense? Not so much.
  20. I understand that you find your own ideas “totally logical”, but as you already said, you're a newbie, so you're not qualified to make this statement. You clearly don't understand the technical background. Updating the eBay stock is illegal? Who on earth said that? I said that an order confirmation is a legal matter. If you don't understand that either, you're in the wrong business. Anyway, if you're not interested in advice, I wish you good luck with your “files”.
  21. The clutter you currently have is far, far worse. You can also reduce the number of rows if you only store the opened boxes (all other boxes are implicitly closed).
  22. Your goals and ideas don't make any sense from a technical standpoint. If you want to be sure that the eBay stock is updated during the purchase, there will be a delay for the user, even a potentially infinite delay. Network operations can be slow. Network operations can fail (yes, this happens). The only way would be to wait for the response indefinitely, and if there's any error, try again indefinitely. This is obviously unrealistic. And you may still end up selling out-of-stock items: What if somebody purchases the last item on eBay right after your user has clicked on the “order” button and before you make your API calls? Note that this is also a legal question, so if you're a newbie, you definitely shouldn't invent your own processes. Either find a widely accepted standard solution. Or discuss this with an e-commerce expert. The shops I worked on had a non-binding order confirmation on the website and a separate binding confirmation sent by e-mail. But I'm not a lawyer, so I cannot tell you if this works in every country and in every context.
  23. My point is that the weird column name is the symptom of a deeper problem (a data structure which doesn't fit into the relational model). Yes, you can suppress the symptom in all sorts of ways. You could replace each dot with a “Z”, for example; this technically “works”. But then you still haven't done anything about the actual problem. In fact, it will only get worse as the application becomes more complex. So my suggestion was to either make the data structure compatible with SQL or not use SQL at all. Both can be valid choices depending on the data (which the OP hasn't posted yet).
  24. I think the reason why everybody is confused is because you keep talking about “files”, and files don't make a lot of sense in your context. If you want to make API calls in the background, the easiest way is to create a cronjob which periodically scans the database for new orders, sends request to the ebay API and then marks the order so that it won't be processed again. So the purchasing script doesn't communicate with ebay at all. It just stores the order. Then a separate script is triggered by the operating system every n seconds and takes care of the API calls.
  25. I hope that was a joke. Otherwise I suggest the OP teaches you some SQL basics, because unlike you he at least understands the problem.
×
×
  • 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.