Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,450
  • Joined

  • Days Won

    175

Everything posted by mac_gyver

  1. the following debugging code will show you what the submitted form data looks like - echo '<pre>'; print_r($_POST); echo '</pre>';
  2. where's your attempt at doing this? just repeating something someone else told you to do isn't programming and isn't learning how to program.
  3. for the first step - make the checkbox field an array, with the array index being the user_id value - <td><input type="checkbox" name="checkbox[<?php echo $row['user_id']; ?>]"></td>
  4. the checkbox and user_id fields are not arrays, so there's nothing to loop over in the form processing code. also, since only checked checkboxes as submitted, there's nothing that relates each existing checkbox to a user_id. do this instead - make the checkbox field an array, with the array index being the user_id value. if you want to display the user_id in the html table, just echo it like the rest of the columns. if any of the checkboxes are checked, you will get an array with the indexes being the user_ids (i would use array_keys() to get all of them as an array to loop over). you would then use a prepared query, prepared once before the start of any looping, to insert each row of data.
  5. the posted code has almost no error handling/validation logic and the error handling it does have is not being used ($msg is not being displayed anywhere in the html document.) to answer your question of how to test if a 'required' file was uploaded and display a message, your code needs to test for upload errors and then validate the submitted form data, only using the form data if there are no errors and the data passed all the validation tests. the simplest, general-purpose way of doing this is to use an array to hold user error/validation messages. this array is also an error flag. if the array is empty, there are no errors and you can use the submitted form data. if the array is not empty, there are errors. you can test and display the content of this array in the html document to let the visitor know what problems occurred with the data that they submitted. here's what your form processing code should do - detect if a post method form was submitted. detect if the total size of the form data exceeded the post_max_size setting. if this condition occurs, the web server will abort the form submission, and both the $_POST and $_FILES arrays will be empty. since you expect a non-empty $_FILES array, to keep it simple, you can just test for this (there are actually other reasons the $_FILES array can be empty - an invalid upload form, uploads are not enabled.) if there is data in the $_FILES array, you would then test if the upload was successful - $_FILES['image']['error'] will be UPLOAD_ERR_OK (0). for the case of not selecting a file in the form, the ['error'] element will be UPLOAD_ERR_NO_FILE (4). your code would add an error message to the array of error messages. if you want to add other validation of the uploaded file, such as file extension, mime type, file size, image size, ... you would perform those tests next. validate the other input(s), adding any validation error message(s) to the array of error messages. if the textarea input is 'required' you would validate that it is not an empty string. after all the validation logic, if the array holding the error messages is empty, you would use the submitted form data, adding any new error messages to the array of error messages. at the end of the post method form processing code, if there are no errors, you should redirect to the exact same URL of the page to cause a get request. this stops the browser from trying to re-submit the previous form data. if you want to display a one-time success message, store it in a session variable, the test, display, and clear that variable in the html document. some other suggestions for the code - make only one database connection and use it throughout the rest of the code. use a prepared query when supplying external, unknown, dynamic data to a query. switch to the much simpler PDO database extension. this is even more important when using prepared queries since the mysqli prepared query interface is overly complicated and inconsistent. put the database specific code, that knows how to query for and retrieve the data needed to display the page, before the start of the html document, fetch all the data from the query into an appropriately named php variable, then test/loop over this variable in the html document. if there is no data from the query to display, you should output an appropriate message on the web page. apply htmlentities() to all dynamic values when you output them on a web page to help prevent cross site scripting. all database statements that can fail - connection, query, prepare, and execute, ALWAYS need error handling. the simplest way of adding this without adding logic at each statement that can fail is to use exceptions for errors and in most cases let php catch the exception where it will use its error related settings to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.)
  6. from the php.net documentation - the 3rd parameter is a result mode flag. are you using it this way in your code?
  7. i think (i cannot tell for sure without having all the code and actual testing, because of how overly complicated this code is) your issue is due to how your code is laid out (your form processing code is inside the html document), that you are not validating inputs w/user error messages for 'required' values, have too many variables being copied to other variables, too many database connections, and that you are using session variables when they are not needed. you need to Keep It Simple (KISS.) your code needs to ALWAYS validate inputs before using them, setting up validation errors for the visitor for 'required' inputs. doing this would at least help you find where the problem starts at and will eliminate follow-on errors that aren't directly due to the actual problem. the session variable in question IS an input to your page and needs to be validated before use. the code for any page should be laid out in this general order - initialization - define, require, create, ... things your page needs, such as the session_start() statement, a database connection, configuration values, ... post method form processing code - a post method form should be used for things that create/update data on the server or perform an action such as sending an email. get method business logic - get/create data needed to display the dynamic content on the web page. html document/template - using simple php code or an actual template system, produce the actual html document, using the data produced from the above sections of code. lastly, don't put external, unknown, dynamic values directly into sql query statements. use prepared queries.
  8. this is because your code is fetching the first row from the result set, see the first line in the following code, not using it, then looping over the remaining rows in the result set, starting at the second line in the following -
  9. in html5, no action attribute at all means that the form submits to the same page. you can also set action='#' to submit to the same page, but an empty action attribute, action='', is not valid html5 markup (as of the last time i checked.)
  10. no. it will set php's error related setting so that php will help you find what's causing the problem by reporting and displaying all the errors it detects.
  11. that's not E_ALL. as an integer, E_ALL would be 32767
  12. do you have php's error_reporting set to E_ALL and display_errors set to ON, in the php.ini on your system, so that php will help you by reporting and displaying all the errors it detects?
  13. here's a list of things your login code needs to do differently - do NOT store the user_id in a cookie to identify who is logged in. anyone or a bot script can supply any value for a cookie when they request your page and appear to be anyone, such as you or an administrator on your site, just by going through all possible user id's until they find one that works. you would instead generate a random unique value, similar to what a session id cookie is, and store it in a database table that relates it to the actual user_id and store it in the cookie. you must have an exit/die statement after every header() redirect to STOP code execution. your current code is executing all the rest of the code on the page at each header() redirect. don't use fetchAll() and a loop for a query that will at most match one row of data. just directly call the fetch() method and test if a row of data was found. as to your current problem, the code you are dealing with is the login form processing code and the login form. however, you have put the login form processing code at what appears to be the top of the main index.php page. this doesn't make any sense, logically, because you would be redirecting to the main page, that you are already on, if the cookie is set. you are also testing a different cookie name then the one you are setting (id vs user_id), and there's no code setting the $user_id variable you are testing on the page to determine if there is a logged in user.
  14. what have your tried? this assignment seems pretty straight-forward - SELECT the things you want, one of them being the SUM() of the column you want to add up FROM your two tables JOINed together ON the column that relates the data between the tables GROUP BY the column that identifies which rows to SUM() together and any ORDER BY column(s) that get the data into the order that you want to display it as
  15. an attribute like this is usually related to a wysiwyg theme/template/markup editor and has nothing to with how the web page operates. if you are doing something that you believe this will have an affect on how the page operates, you would need to share that information with us. the post method form you build and the corresponding form processing code you write determine what the web page does.
  16. your function should not be responsible for making a database connection or querying for the choices. those are the responsibility of your main application code. i would make your function general-purpose, reusable, and supply an array of option choices, with id, label entries, and an optional array, to support the multiple attribute, of currently selected choices.
  17. see the following example code, using an array for the form field name, on how to retrieve existing data, populate a form with it, then do whatever you want with the submitted form data - <?php // example of editing existing data, even if not saving the result, i.e. the U in CRUD session_start(); // fake a logged in user $_SESSION['user_id'] = 123; // recursive trim call-back function function _trim($val){ if(is_array($val)){ return array_map('_trim',$val); } else { return trim($val); } } // require 'pdo_connection.php'; // the pdo connection code should - set the error mode to exceptions, set emulated prepared queries to false, and set the default fetch mode to assoc // if the user is not logged in, go elsewhere if(!isset($_SESSION['user_id'])) { header("Location:index.php"); exit; } // if the user must have a rank or 'edit' permission to access this page, query to get that information and test it here... // at this point, the user has permission to access this page $post = []; // array to hold a trimmed working copy of the form data $errors = []; // array to hold error messages // post method form processing if($_SERVER['REQUEST_METHOD'] == 'POST') { // input(s) - sku, an array with an sku as the index for each element and the submitted price as the element's value // trim all the input data at once $post = array_map('_trim',$_POST); // since some of the form fields are arrays, use a recursive trim call-back function here. // validate all the inputs here, storing error messages in the $errors array, using the field name as the array index... // in no errors, use the input data if(empty($errors)) { // examine the submitted data echo '<pre>'; print_r($post); echo '</pre>'; // loop over the submitted data foreach($post['sku'] as $sku=>$price) { // use each set of submitted $sku/$price for anything you want... } } // if no errors, success if(empty($errors)) { // redirect to the exact same url of this page to cause a get request - PRG Post, Redirect, Get. //header("Refresh:0"); //exit; // note: if you want to display a one-time success message, store it in a session variable, test, display, and clear that session variable in the html document } } // if there's no form data, get the initial data needed to populate the form fields if(empty($post)) { $sql = "SELECT sku, price FROM your_table ORDER BY sku"; // if you have a WHERE term, add it to the sql statement, change this to be a prepared query, and supply an array of inputs to the ->execute() method call. /* $stmt = $pdo->query($sql); foreach($stmt as $row) { $post['sku'][$row['sku']] = $row['price']; } */ // fake some data for demo purposes $post['sku'][12134] = 10.00; $post['sku'][5567] = 5.99; } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Edit/Update example</title> </head> <body> <?php // display any errors if(!empty($errors)) { echo '<p?' . implode('<br>',$errors) . '</p>'; } // display the form if(empty($post['sku'])) { echo '<p>There is no data to edit.</p>'; } else { ?> <form method="post"> <input type='submit'><br> <?php foreach($post['sku'] as $sku=>$price) { $price = number_format($price,2); echo "<label>$sku: <input type='text' name='sku[$sku]' value='$price'></label><br>"; } ?> </form> <?php } ?> </body> </html>
  18. you are the UPDATE'ing the submitted prices back into the database table? what is the significance of multiple same sku values? are there multiple rows in the database table with the same sku, which would indicate bigger problems in the design?
  19. whatever this code's purpose is, you should probably be using an array for the form field name, with the sku value as the array index. so, what is the purpose of this? who uses it, what are the input(s), how many sets of inputs are there, what processing will be done using those inputs, and what is the desired result or output for some sample input data?
  20. the error you are getting is a follow-on error, due to code being executed when a 'required' input is not present. if you have a section of code that requires a logged in user, your code should test if the session variable isset() before ever executing that code. this will stop the follow-on error. the actual problem is a session variable that should be set but isn't. in the first post and your post above, you have stated/implied that the SELECT query in the first post is being executed/working. how do you know it's working. what code is using the result from that query and what result or output are you getting that leads you to believe that particular query/section of code is working? taken by itself, a symptom of code that seems to work and also produces an error is usually a sign that the code is being executed twice, once with and once without the expected input data. next, there's a bunch of issues with the rest of the code you have posted - you should have an auto-loader to load the class definitions. also, 'require' isn't a function and the () around the filenames are not needed. the responsibility and most of the code in model.php is not needed. if you want to do something useful for a database class, extend the PDO class with a general-purpose prepared/non-prepared query method that accepts a second optional array of input parameters and prepares/executes the query if there are input parameters and just calls the PDO query() method if there are no input parameters. your main code should be responsible for making a database connection, since it knows if, how many, and where those connections should be used, then use dependency injection to supply the connection to any class that needs it. you should not use defined constants for the database connection credentials. this limits the code to using only a single database connection. you should use exceptions for database statement errors and in most cases let php catch and handle the exception, where php will its error related settings to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.) the exception to this rule is when inserting/updating user submitted data and a duplicate or out of range error can occur. in this case, your code should catch the exception, test if the error number is for something that your code is designed to handle, setup and display a message for the user telling them what was wrong with the data that they submitted. for all other error numbers, just re-throw the exception and let php handle it. you should set emulated prepared queries to false, you want to run real prepared queries, and set the default fetch most to assoc, so that you don't need to specify it in each fetch statement. by having a 'query' method that is actually preparing the query, you have created confusion and more work for anyone who will have to read/maintain this code. if you simply supply an array of the input data to the execute([...]) call, you don't need any of the code for binding inputs. also, by using bindValue(), you cannot directly execute the same query again with different data and is_int() in that code isn't doing anything for integer values that are in a string variable type. the verify() method also has responsibility and code issues. just some of them - the only user data you should store in the login session variable is the user id (auto-increment primary index.) you should query on each page request to get any other user related data/permissions. this is so that any change in the user data/permissions will take effect on the very next page request, without requiring the user to log in again. also, all header() redirects need an exit/die statement after them to stop code execution.
  21. they are settings actually - name = value error_reporting = E_ALL (or even better, a -1 to future proof it, as the E_ALL value can have more added to it) display_errors = on another setting to change, since it is probably off on a live/public server and you may not be able to set it there, is - output_buffering = off the runtime issue with putting these settings into your code is that if the code contains a parse/syntax error, the code where these settings are at never runs to cause the settings to take effect.
  22. this problem goes away if you switch to the much simpler and more consistent PDO extension, because you can fetch data from a PDO prepared query exactly the same way that you fetch it from a traditional, non-prepared query. a PDO prepared query also uses ? for the place-holders, so you can reuse your existing sql query syntax. all you have to do is make the connection using the PDO extension (setting the character set to match your database tables, set the error mode to exceptions, set emulated prepared queries to false, and set the default fetch mode to assoc), which i'm pretty sure has already been posted in some of your threads, but which someone would be willing to re0post, then change the remaining mysqli statements to the equivalent PDO statements, which you can do using by rote/A-B pattern matching. the statements needed for binding input and output parameters also go away. you simply supply an array of the input values to the execute([...]) call and use one of the fetch statements to retrieve the data. yes. you should be internalizing the meaning of the php, sql, html, and css statements/words you are using so that you know what they actually do, so that when you read or write code you know what each statement/word contributes to the 'story' on the web page. you basically need to become fluent enough in each of those languages so that you can write a meaningful and understandable short story using them. when i/we read code that someone posts, we start at the top and actually read the statements/words that have been posted, adding up what the meaning of each statement/word is contributing to the story being told. when we get to the end, if the statements/words all made sense and all have something to do with the task at hand, we know that the code will probably work (through testing will determine if it actually does.) when we see code that has all kinds of unnecessary, repetitive, missing, misused, and out of order statements/words, what do you think pops into our minds? as to your posted code - you are no longer requiring (you should use 'require', not 'include', and both of these are not 'functions' so don't put ( ) around the filename) either the connection or the error .php files. Instead, you have attempted to insert the code into the main file, introducing errors in the code and adding repetitive logic. why did you change this? did you miss the point about putting common code into a .php file and requiring it when needed? php's error related settings should be put into the php.ini on your system. this is so that they will report ALL php detected errors, even parse/syntax errors. this also allows your development system and your live/public server to be configured with their own error related settings and you don't need to remember to edit any code when moving it between those two systems. when you were initially and most lately given the mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT); line, you were told and shown to put it before the line where you make the database connection. that would mean that it belongs in the conn.php file. if you had put it there and left it there, you wouldn't be mucking around with it now. you have also been told a number of times that when using exceptions for database statement errors, which is what the mysqli_report() line of code does, that none of the connection, query, prepare, and execute error handling logic will get executed upon an error and all that existing logic should be removed, simplifying and de-cluttering the code. you were also told that using exceptions for database statement errors and letting php catch and handle the exception, meaning there is no try/catch logic in your code, will cause database statement errors to 'automatically' get displayed/logged the same as php errors. you are now asking in the conn.php code how to cause a connection error to get displayed/logged. you have been told how to do this. you also don't display these errors to the user/visitor to your site. you only display these errors to the programmer/developer, i.e. you, when you are learning, developing, and debugging code/query(ies.) you don't even tell the visitor, which could be a hacker, anything about an error that has occurred, since that will just encourage them to do more of the same things that caused the error in the first place. you are putting unnecessary double-quotes around php variables in the conn.php code. again, what do you think pops into our minds when we have to look at unnecessary things that could be causing a problem when someone asks us to look at their code? you have both a die() and an exit() statement in the conn.php code. that do the same thing. are you even looking at and reading your code? the search form should use method='get' (which is the default if you leave the method attribute out.) get is used when determine what will be displayed on a page. post is used when creating/altering data on the server or performing an action, such as sending an email. an empty action='' attribute is not valid html5. you were actually told to remove the entire action attribute. the search form should be 'sticky' and re-populate/select the form field values/choice(s) that correspond to any submitted data. only <input ... > or <button ... > tags that have a type='submit' attribute are capable of submitting the form. use one or the other, not both. only form elements with a name='...' attribute will be included in the submitted data. if you have only one post method form on a page, after you have tested the server REQUEST_METHOD, that's all the logic you need to start the form processing code. except for unchecked/unselected form elements, all other form fields will be set once the form has been submitted. using isset() around always-set form fields is a waste of your typing time. your form processing code should trim, then validate all inputs, storing any validation error messages in an array, using the field name as the array index. if after the end of the validation logic the array holding the error messages is empty, you can use the submitted form data. the get method 'business' logic, that knows how to get/produce the data needed to display the dynamic content on the page should come before the start of the html document. you would fetch all the data from any query into a php variable, then test/loop over that variable at the correct point in the html document. if you are going to continue to use the mysqli extension, just use the single $stmt = mysqli_prepare($conn,$query); statement, instead of $stmt = mysqli_stmt_init($conn); and mysqli_stmt_prepare($stmt,$query). i'm pretty sure you have been told this point before. i don't know why you are using the most complicated way of doing things. remember these two acronyms - Don't Repeat Yourself (DRY) and Keep It Simple stupid (KISS.) if you find yourself repeating the same code over and over or doing something in the most complicated way possible, you are probably doing something wrong. don't do this - if($bind_result === FALSE) the rest of the mysqli stmt error logic you have... the mysqli_stmt_bind_result() statement will produce a php error if it fails, which would be due to a programming mistake on your part. it won't produce a database statement error, and you won't get anything useful from the current code. the only things that produce database statement errors/error numbers are the connection, query, prepare, and execute statements. don't do this are well - if($stmt_fetch === FALSE) the rest of the mysqli stmt error logic you have... there's two problems with this - 1) your code is fetching the 1st row from the result set, but not displaying it, so you will be missing a row of data, and 2) a false value when you fetch data only means that there was no data to fetch. this is not an ERROR, it's how your code knows to stop fetching data. there won't be any mysqli statement error/error number values to display. php will destroy all resources when the script ends, so in most cases, you don't need to close a prepared query statement or close the database connection. most of these things will actually simplify and clean up your code, leaving you with just the implementation logic that you should be concentrating on to get the application to work and the forum members will be more happy about looking at what you are posting since it won't contain a wall of unnecessary elements.
  23. the error is because you are not using an index in the sql query, meaning that it will have to scan through all the data in the table to find rows that satisfy the WHERE clause, and you are just copy/pasting things you see without even reading what they are saying. the MYSQLI_REPORT_ALL value you are using is causing this. if you read the section of the mysqli error report documentation that i posted in one of your threads, you will see what the ALL value does. it includes the MYSQLI_REPORT_INDEX - Report if no index or bad index was used in a query value. it doesn't. all you have done is randomly change the code so that it is no longer executing that query. btw - since you are using exceptions for database statement error handling, none of the discrete error handing logic you have in your code will be executed, and is therefore pointless, since execution transfers to the nearest exception handler, or to php if none. its php that's giving you the current error output.
  24. INSERT queries don't have WHERE clauses. they have a list of columns and corresponding values. you would add the user_id column next to the date column and supply the user id value for that column when the query gets executed. you should not put external, unknown, dynamic values directly into a query. use a prepared query. here's the insert query documentation definition with the most commonly used elements highlighted - the value_list definition - for a prepared query, the value_list would contain a ? place-holder for each value.
×
×
  • 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.