Jump to content


Staff Alumni
  • Posts

  • Joined

  • Days Won


Everything posted by mac_gyver

  1. stock/inventory should be handled using an accounting/transaction ledger type system, where a separate row is inserted for every +/- transaction that affects a value. this will provide you with an audit trail so that you can tell if a programming mistake, duplicate submission, or nefarious activity has altered a value. you would then query to SUM() the +/- amounts for each item id to get the current stock/inventory amounts. when you submit the items making up an order/sale, you would insert a row into an order/sale table, with the unique/one-time information about the order. you would then get the last insert id from that query and use it when inserting the rows containing the item id/quantity into an order_item table.
  2. there's no need to compare, in php code, the column value fetched from the query with the column value being tested in the where clause. if the query matched a row(s) of data, the where clause was true. next, if you are not actually using the row(s) of data that a query matches, i.e. you are only testing if a value exists or how many times it exists, use SELECT COUNT(*) ..., and if this is for a 'registration' script, where you are deciding if you are going to insert a row of data, instead, just define that column as a unique index, attempt to insert the data, then test if the query produced a duplicate error. lastly, if you switch to the much simpler PDO database extension, a majority of the lines of code will go away.
  3. an ->execute() call can fail due to something wrong with the data being supplied to the query. what's your error handling for that case? i also see you edited a post above to add the code for the addComment method. you are using a prepared query. do NOT also use mysqli_real_escape_string on the data. this will result in the actual escape characters \ being inserted into the database, which will prevent searches from matching data. the main point of using a prepared query is to protect against sql special characters from breaking the sql query syntax, for all data types, not just strings. i also see you are applying nl2br to the input data. this is an OUTPUT function. it is used when you output data in a html context. do NOT use it on input data being stored in a database.
  4. here's an outline of what the code you are showing us should/should-not do - put any php error_reporting and display_errors settings in the php.ini on your system. this will let you make changes to these settings in one place and simplify your code. use 'require', not 'include', for things that your code must have for it to work. also, require/include are not functions and the () around the filename are not needed, simplifying your code. don't write code that isn't being used. in the current code, there are no session variables nor any user written functions. remove the session_start() and include("functions.php"); line, i.e. keep your code simple and uncluttered. the mysqli_report(...) statement should be before the point where you make the database connection, which you were also told in a previous thread on this forum. because the mysqli_report(...) statement causes the connection, query, prepare, and execute database statements to use exceptions for errors, the error handling logic you have now won't ever be executed upon an error, and should be removed, simplifying your code. the post method form processing code should detect if a post method form was submitted before referencing any of the form data. in your previous thread on this forum, you were doing this. why have you now changed from a simple statement to the mess of if()/isset() ... statements and why are you now using both $_POST and $_REQUEST variables? just use $_POST if you expect the data to be from a post method form. keep the input data as an array and operate on elements of this array throughout the rest of the code, i.e. don't write out line after line of code needlessly copying variables to other variables, simplifying your code. the post method form processing code should trim, then validate all the inputs, storing user/validation error messages in an array using the field name as the array index. after all the validation logic, if there are no errors (the array holding the user/validation error messages will be empty), use the submitted form data. if there are errors, you would display the contents of the errors array when you re-display the form. also in that previous thread, member(s) stated to use a prepared query to safely supply data to a query and to use the (much simpler) PDO extension. a prepared query, provided you use the PDO extension, only adds one php statement per query, allows you to eliminate any _escape_string() statements, and simplifies your sql query syntax, helping to prevent mistakes. after successfully completing all the post method form processing code, you should redirect to the exact same url of the current page to cause a get request for the page. this will prevent the browser from trying to re-submit the form data if the user reloads the page or browses back to the url of the page. in most cases, there's no need to close database connections, free query results, or free prepared query statements, since php will destroy all resources used on a page when your script ends, simplifying your code. you will notice a theme in the above of simplifying the code/query. there's a lot of old information to be found in books, course material, and on the web that is no longer needed. the following is a pseudo code example showing these points - <?php // use the much simpler PDO extension require 'pdo_connection.php'; $post = []; // an array to hold a trimmed working copy of the form data $errors = []; // an array to hold user/validation error messages // post method form processing if($_SERVER['REQUEST_METHOD'] == 'POST') { // trim all the form data at once (if any of the form fields are arrays, write and use a recursive trim function here instead of php's trim) $post = array_map('trim',$_POST); // validate the inputs here... // if no errors, use the form data if(empty($errors)) { // build the sql query statement, using a prepared query $query = " the sql query "; // prepare and execute the query // note: the following uses the PDO extension $stmt = $pdo->prepare($query); $stmt->execute([ an array of the input values ]); // note: an insert/update query may result in duplicate data. if this is an error condition // for your application you would define an appropriate unique index for your database table // then you would have exception try/catch logic for this query to detect if a duplicate // error number occurred and setup and display a message (add it to the $errors array) // telling the user what was wrong with the data that they submitted. for all other error // numbers just re-throw the exception and let php handle it } // if no errors, success if(empty($errors)) { // redirect to the exact same url of this page to cause a get request - Post, Redirect, Get (PRG.) header("Refresh:0"); die; } } ?> <?php // at the appropriate point in the html document, test and display any errors if(!empty($errors)) { echo implode('<br>',$errors); } ?> <?php // you would re-populate the form field values with any existing data so that the user doesn't need to keep reentering things over and over ?>
  5. you can use a phpinfo() statement in a .php script to check what the master and local values are for those settings.
  6. if you successfully set the php error related settings to the stated values, you should have gotten a http 500 error page. either they didn't get set to those values or you have settings in your code that are changing the values. a visitor to your site doesn't need to know anything about why a web page is not working and if you let a hacker know anything about what type of error occurred, they will just do more of the same to trigger more errors. you are logging the raw php/database error information on a live/public site so that you, the programmer/developer, will know what type of errors are occurring, so that you can find and fix what's causing them, or in the case of a database server not running, why the site was temporarily not working.
  7. yes. if you have access to the database server, you can temporarily stop it to test what the result will be. if you don't have access to the database server, temporarily introduce a typo mistake in the DB_SERVER value to test what the result will be.
  8. php's error_reporting setting should always be set to E_ALL (or even better a -1 since php has been confused about what the word all means.) on a development system, the display_errors setting should be set to ON. on a live/public server, display_errors should be set to OFF and log_errors should be set to ON.
  9. on a live/public server, you should log all php errors, which since you are using exceptions for the mysqli statement errors, will include the database statement errors. also, since you are using exceptions for mysqli statement errors, there's no point in having discrete logic to test for errors. that logic won't ever get executed upon an error, since execution transfers to the nearest correct type of exception handling, which will be php in the case of the code you posted. remove any such discrete error handling logic, simplifying your code. you should only display all php errors, when learning, developing, and debugging code/query(ies). put any php error related settings in the php.ini on your system, so that they can be changed at a single point.
  10. the session_start() in the messages.php file is probably failing, due to the html markup you are outputting on the register.php page, before the point where you are requiring messages.php. if you set php's error_reporting to E_ALL and display_errors to ON, you should find the actual reason for the code not working. the reason this works on your development system and not on the live server is most likely due to the output_buffering setting, in the php.ini, being set to on (a non-zero integer value) on your development system. you can check both systems using a phpinfo() statement in a .php script file to confirm this. since you may not be able to change this setting on the live server, it will be best if you turn this setting off on your development system, so that any code you produce won't stop, due to this problem, when you move it to a live server. in general, the code for any page should be laid out in this order - initialization post method form processing get method business logic - get/produce data needed for the dynamic content on the page html document your page should have one session_start() statement, it should either be directly or indirectly (via a required file) in the initialization section. item #2 means that your form processing code should be on the same page as the form. this will simplify all the code and provide a better User eXperience (UX), since you can re-populate the relevant form field values when you display any validation/user error messages and re-display the form. btw - you should NOT let the user know if a database or any other internal error has occurred. this information is only useful to you, the programmer/developer. you should display errors like this when you are learning, developing, and debugging code/query(ies) and log this information when on a live server. here's some additional points for the database connection code - name the connection variable $pdo or similar so that anyone looking at the code will know what it contains. set the character set to match your database table(s.) set the error mode to exceptions. the connection always uses an exception for errors, you want to the other database statements - query, prepare, and execute, to do the same, so that you don't need to write out a bunch of program logic to handle errors. set emulated prepared queries to false. you want to run real prepared queries. set the default fetch mode to assoc, so that you don't need to keep specifying it in every fetch statement.
  11. most of the points will actually simplify the code e.g. putting the form processing and the form(s) on the same page will eliminate all those lines of code for the session variables. the only increase in code are for things that don't exist now that the code needs. i thought of two more things that could cause the code/query(ies) to work on one server but not another and you might not get any indication from the current code/configuration as to what the problem is - this has to do with the output_buffering setting (if it's on, turn it off) and using the procedural mysqli statements. the error response for the procedural mysqli statements is different from the OOP mysqli statements. things that would be a fatal runtime error, if using OOP, halting program execution, are just warnings, if using procedural statements, and the code will continue to run, which if output_buffering is on, will discard the php warning messages. this has to do with the database server's strict mode setting and having no error handling for the execute() calls. if strict mode is set to ON, on the cheep/free hosting, out of range values will produce an error, but since there's currently no error handling for the execute() call, you don't know if this is happening or not. using exceptions for errors will solve this since it will give you error handling for all the database statements that can fail. if strict mode is off, on your development system, out of range values will instead be truncated to the nearest legal value for the data type, without producing an error. i didn't state it previously, but switching to the much simpler, more consistent, and better designed PDO extension will also simplify the code.
  12. there are a fairly large number of things that can cause your code to work on one system but not another and if your code is lacking validation and error handling logic, your code won't tell you why it is failing. under perfect conditions, on your development system, your code may work, but if anything goes wrong, you won't get any help from your code. firstly, you need to temporarily set php's error_reporting to E_ALL and set display_errors to ON, so that you will get immediate feedback if any php errors are occurring (the cheep/free web hosts may not allow you to do this.) you also need consistent and useful error handling for all the database statements that can fail - connection, query, prepare, and execute (which you don't currently have any error handling for.) the simplest way of adding error handling for all the database statements is to use exceptions for errors and in most cases let php catch and handle the exception, where php will use its error related settings (see the above paragraph) to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.) this will let you remove the existing error handling logic and skip adding it where there is none. the exception to letting php catch the exceptions is when inserting/updating duplicate or out of range user submitted values, which is what you should be doing to detect if a product is already in the cart. in this case, your code should catch the exception, detect if the error number is for something that your code is designed to handle, then setup and display a message for the user telling them what was wrong with the data that they submitted. for all other error numbers, simply re-throw the exception and let php handle it. it doesn't appear that you have any validation logic? you should always trim, then validate all input data before using it. if there are no validation errors, use the submitted data. if there are validation errors, display them when you re-display the add product form(s). the only product information you insert into the cart is the product id and the quantity. all the other product data exists in the featuredlist table and should not be duplicated in the cart. you have a lot of unnecessary code that isn't helping. by putting the form processing code on a different page from the add product form(s), you have more code, a bunch of redirects, and are producing a bad user experience. when you put these on the same page, there will be less code, you can eliminate all but one redirect (upon successful completion), and you can display any validation/user error messages when you re-display the add product form(s). the only redirect you should have in your post method form processing code is upon successful completion of the processing code and it should be to the exact same url of the current page. this will cause a get request for that page. if you want the user to be able to navigate to other pages, provide navigation links. if you want to display a one-time success message, store it in a session variable, then test, display, and clear the session variable at the appropriate location in the html document. as to another reason why your code may not work, on one system, but not another, and be giving the symptom of going back to the cart.html page - what does using a phpinfo() statement in a php script show for the output_buffering setting? because you are redirecting all over the place (which hopefully you will remove, see the above paragraph), any debugging output from your script and any non-fatal php errors will get discarded if the ouput_buffering setting is ON (any non-zero value.) you should set this to OFF. lastly, you should not attempt to SELECT data in order to decide if it already exists. you should set up the table with a unique composite index for the column(s) that identify the user id and product id combination, just attempt to insert the data, and detect if a duplicate index error occurred (see the above paragraph concerning catching an exception for a duplicate error.)
  13. this doesn't directly answer your question, but you should store the user's id (auto-increment integer primary index) in a session variable to indicate who the logged in user is, then on each page request execute an sql query(ies) to get any other user information, such as the username, email address, or user permissions. this will insure that any changes made to this user information will take effect on the very next page request, without requiring someone to log out and back in again. if the user_id session variable is not set, you would setup a default set of 'user' values, in a regular php array variable, that indicates a non-logged in 'guest.' if the session variable is set, you would use it in a query to get the actual user's information and store it in the php array variable. you would then test and use the contents of this variable in the rest of the code on the page to determine what to display or what action can be performed on the page. if you want to halt execution if the user isn't logged in or is not an admin, per your example, you would test if the final user's permission data doesn't contain the admin permission value.
  14. you would have an actual image containing whatever text or picture you want to use to indicate that there's no image to display and output it instead. for your images, you should store the actual file names in a database table, then use the id (auto-increment) value as the ?label=x parameter in the src="..." link, then query in the label.php code to get the corresponding file name. this will prevent someone from supplying a filename to something like your database connection credentials file and have the readfile() statement output the content of that file.
  15. the Ternary Operator would produce shorter code and can be concatenated directly inside the string being built. you can also change any escaped double-quotes \" to single-quotes ' and put php variables directly into strings without using concatenation, simplifying the syntax. slightly off topic, you are repeating code 6 times, once for every bench_type value/range. there's at least two problems with this - 1) it is taking you a long time to produce code, and now that you are making a change to the code, you must make the change in 6 places, and 2) to add a new value will require that you find all the code using the values and add to it, then re-test the code to make sure there were no mistakes. instead of a hard-code approach, of writing out code for each value, repeated by the number of values, you need to use a dynamic processing approach, where you will organize/preprocess the data, then simply loop over the data to produce the output. it would take knowing what the overall data looks like to specifically help, but if you index(pivot) the data using the details, year, and bench_type, as array indexes, when you retrieve the data, you can probably reduce all the above to three nested foreach(){} loops, that will 'automatically' adjust if any new bench_type values are added to the data. if you do post an example of your $reg_years data, please use var_export() so that the data can be used for testing.
  16. you probably have some broken markup on the form page (nested forms as an example.) the quickest way to get help would be to post all the code for that page.
  17. a. the ? place-holders do not get surrounded by quotes in the sql statement. the single-quotes around them will result in literal ? characters being used as the values. b. as suspected, you cannot supply literal values in a bind_param() statement. you must either put literal values into the sql statement, put them into variables that would then be used in the bind_param() statement, or switch to the much better PDO extension. edit: or set them as the default values in your db table definition, and leave those columns out of the sql query.
  18. you would need to post your current code to get any help with it. the previously posted code doesn't even have a bind_param() statement in it. best guess, you are trying to supply a literal value, rather than a variable as a parameter. this is yet another reason to switch to the much simpler, more consistent, and better designed PDO extension. you can supply an array of values to the ->execute([...]) call that can be anything - variables, function calls, literal values, math expressions, ...
  19. less... $matched = array_intersect_key($all, array_flip($referred_by_Affiliate));
  20. arrays are for sets of data, where you will operate on each member in the set in the same/similar way. by keeping the input data as a array, you can search through your code and find all references to that data, via the array variable name. using variable-variables, you are 'magically' creating those discrete variables and you must now know what they are named in order to search for them. by keeping the data as an array, you can directly operate on the data using php array functions. for your strtoupper example, where you want to apply that function to each entry in an array - $data = array_map('strtoupper',$data); you can then start doing things like trimming all the data, filtering out empty values, applying user written sort, filter, and validation functions to the data, all at once. also, as Barand has shown, you can build and use an array as a dynamic input to things like a PDO prepared query ->execute(...) call, or a templating system, so that you are not writing out lists of variables yourself. you can use general-purpose code to build those arrays of values based on entries you add to your defining $fields array.
  21. you CAN configure the web server to treat .html (or any other extension) as a php file. the default is for only the .php extension.
  22. that opens the file through the file system, not the web server, so, any links in the html will also be read through the file system. you must use a url to the html file, such as http://localhost/phptest.html. this will cause the src="phptest.php?id=1" attribute to be read through http://localhost/phptest.php?id=1
  23. technically, the code you have posted should work. unfortunately, telling us something doesn't work doesn't help. exactly what symptom, error, or output do you get?
  24. GROUP BY some_col consolidates all the rows having the same some_col value into a single row, so, for each user, there would only be one row in the result set. if you want the rows for each user adjacent to each other in the result set, add an ORDER BY term (almost every select query should have one) and/or index/pivot the data when you retrieve it using the user_id as the main array index, to produce an array of sub-arrays for each user. as to why you are only getting the data for a single (the last user), your code inside the loop is needlessly copying variables to other variables, overwriting any previous data, until finally, after the end of the loop, you are left with only the last row of data. once you have fetched all the data into an appropriately named variable, $result_records, simply loop over that variable to produce the output that you want, no need to create 12 lines of code coping data from one variable to another for nothing.
  25. the post method form processing code's purpose is to detect and process the data from a post method form submission. when you are done doing that and execute a redirect, there's no connection between any code that was just executed and what will be executed after the redirect. perhaps this will help your understanding - web servers are stateless. they don't know or care about anything that happens outside of the current request they are servicing. a browser makes a http(s) request to a web server. the web server outputs the requested page, which can contain dynamic portions produced by server-side languages, e.g. php. the browser renders the html, css, and JavaScript on the page. if the page contains a html post method form (what you are currently doing), when that form is submitted, the form data is sent as part of the http(s) request to the page, given by the action attribute (a blank in your case, for the same page as the form. which is not actually valid html5. you should completely remove the form's action attribute in html5.) the section of the code on that page that's testing for a post method form submission will run, doing whatever it was written to do. there are two reasons for putting the post method form processing code above the remainder of the php code on the page - 1) allow any statement that uses a header to work (redirect, cookie, content type, ...), and 2) so that you can make a decision as to what to do on rest of the page based on the result of the post method from processing code. if the result contained any user correctable errors, you would continue running the code on the page, display the errors, and re-display the html document with the html form in it. if the result was successful processing of the form data, you should actually redirect to the exact same url of the current page, with an exit/die statement after it, as @Barand stated, to cause a get request for that page. this will prevent the browser from trying to re-submit the form data should you reload the page or browse away from and back to the page. each of these requests/responses are completely separate. it's up to the code you write on a page as to what happens during any request made to that page.
  • 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.