Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,352
  • Joined

  • Days Won

    173

Everything posted by mac_gyver

  1. 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.
  2. 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.
  3. the above is why you are not seeing any errors. those two are not the same. E_ALL is a defined constant. putting quotes around it makes it a string consisting of the characters E, _, A, L, and L.
  4. i just noticed the cause of the problem. you have a stray semi-colon ; on the end of the while() statement. this short-circuits the loop, so that it loops over all of the data first, then your code that you think is part of the loop, inside the {}, is actually after the end of the loop, where there is nothing in $row. this is the the correct syntax for a while() loop when using { } around the conditionally executed statements - while (some condition is true) { code to execute inside the loop } // or even better, put the opening { on the next line so that it is alighned with the matching } while (some condition is true) { code to execute inside the loop } - you shouldn't even be using a loop to fetch the data from a query that will at most match one row. just directly fetch the row of data. btw - since you are comparing the user number in the query, if the query matched a row of data, you know that the user number was found. you don't need to compare it again in the php code. also, your comparison in the php code, because you are using an exact, not equal !== match, will always fail. by definition all form data are strings, regardless of what value they hold and the fetched data from a mysqli query (if using the default settings) is the actual data type of the column in the table. a string data type (the variable with the form data) will always be not equal to an integer data type (the variable holding the fetched user number from the query.)
  5. what does var_dump($row); show? btw - you should INSERT a new row for every transaction that affects a user's account balance, not update the value in a column. you currently don't have an 'audit trail' to detect if a programming mistake, duplicate form submission, or nefarious activity has altered the value. your current code will also update the value to the wrong amount if there are concurrent instances of your script being executed since the 'last' update query to get executed will replace any previously updated value.
  6. code that unconditionally (always) outputs the raw database statement errors for the connection, query, prepare, and execute statements, only helps hackers when they intentionally trigger errors, since these errors contain things like the database hostname/ip address, database username, if a password is being used or not, part of the sql syntax, and web server path information. the only time you should output the raw database statement errors is when learning, developing, or debugging code/query(ies) and you are viewing the site as the developer/programmer. at all other times, you should log these errors. the simple way of doing this 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 to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.) you would then remove any discrete error handling logic, since it doesn't add any value for a legitimate visitor to your site, and it will no longer get executed when there is an error (execution transfers to the nearest exception handler for the type of exception or to php if there is none.) the line that Barand posted enables exceptions for errors for the mysqli extension.
  7. the main reason requinix stated that is because you are not validating input data before using it (which i have mentioned doing multiple times in this thread.) someone can cause your code to execute any php function, like phpinfo(), by simply setting $_GET['form_type'] to phpinfo when they request your page. do you really want someone to be able to see the phpinfo output from your site or execute any php function? your code needs to have direct, positive control over what gets executed on any page request.
  8. that's not what i posted. php's short opening php tag may not be enabled and shouldn't be used anyway. what does the 'view source' in your browser of the main page show?
  9. you still have not done the most important thing that has been suggested, repeatedly. validating all inputs that your page expects and setting up/displaying user error messages for each validation error. this will get your code to either work or it will tell you why it isn't working. no. your queries also expect $_POST["first_name"] and $_POST["marital_status"] as inputs, all this extra code using session variables, repeated database connections, function definitions around parts of your main code, function definitions inside of other function definitions, ... is unnecessary clutter. i recommend that you start over, adding and testing one feature at a time. 1. produce a get method search form, that's 'sticky' (repopulate the field values with any existing submitted values), that sets up/displays user error messages for each required input that doesn't exist. 2. once you get that to work, add the two queries and the logic needed for pagination, that use those required inputs. another recommend to add to the list is to use an array to hold user/validation error messages, using the input/field name as the array index. this array is also an error flag. if the array is empty, there are no errors and you can use the input data. if the array is not empty, there are errors. you can test/display the content of this array at the appropriate point in the html document.
  10. use 'require' for things your code must have for it to work. this will stop code execution if the required file could not be found and prevent follow-on errors in code trying to use things that don't exist. do you have an opening <?php tag in the file? use a .php extension for this file. by using .inc for the extension, anyone can browse to the file and get the raw php code in it, exposing your database connection credentials. by using a .php extension, the php code would instead be executed if someone browsed to it and they cannot see the raw php code.
  11. if you layout the code on your page in the following general order, it will be much easier to design, write, test, and debug your code/query(ies) - 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. you would have validation logic in both items #2 and #3. next, you don't need to understand OOP in order to use existing OOP classes. if you switch to the much simpler and more consistent PDO database extension, over half of the database related statements will go away.
  12. i just realized why you are not getting any helpful php errors at the point of the problem. it's because you are using the ridiculous mysqli extension. the following is using a reference to the variables and if they don't exist, there's no php undefined variable/index error when the variables are evaluated. so, i'll repeat this - your search form should use method='get' and if your code was validating the inputs before using them, you would know why your code is not working,
  13. the most immediate problem is you have a logic 'hole' in the username/password check, where not all possibilities are addressed. when you use negative logic, you must complement both the conditional comparison in each term and the logic combining the terms. the complement of - if(a == b && c == d) is if(a != b || c != d). it is not if(a != b && c != d), in general, you should avoid using negative logic. you also need to use php's password_hash() when registering/storing the initial submitted password and use password_verify() when testing if a submitted password matches the saved hashed value. also, don't use a loop to fetch the data from a query that will at most match one row. just directly fetch/test the result from the query. lastly, the recommendations given in your last thread, less the ones that were specific to an INSERT query, apply to what you are currently doing. using those recommendations will result in the least amount of code/variables.
  14. how about the display_errors setting? any of php's error related settings should be in the php.ini on your system, so that they can be changed at a single point and don't clutter up your code.
  15. the pagination after page 1 is not working because you are not propagating the get parameters that your code expects, nor are you validating those inputs, so your code is not telling you what is wrong (you are probably getting php errors though.) you must validate all inputs to a page before using them and any 'required' inputs should cause some type of user error message to be displayed if they are not present. when you get to the point of producing pagination links, you should include any existing get parameters by starting with a copy of the $_GET array, modify the page element in that array, then use http_build_query() to produce the query string part of the url. you should also be passing any search term/filters as get parameters.
  16. the mistake is probably at the binding/execution for the insert query. i won't mention what i saw because it is more important that you develop simple coding that will either work or it will tell you (display/log) why it isn't working. because you have no useful error handling for all the database statements that can fail (connection, query, prepare, and execute) and probably don't have php's error related settings set up to get php to help you, you are not getting any feedback that would allow you to solve the problem yourself. start by doing what was written here - https://forums.phpfreaks.com/topic/310992-mysqli-count-query-prepared-statements/?tab=comments#comment-1579137 next, this code is full of unnecessary things that don't add any value to what you are trying to accomplish (a form and form processing code that inserts data into a database table.) some recommendations that will result in simple code - put the form and the form processing code on the same page, with the form processing code above the start of the html document. this will allow you to directly display any validation errors and re-populate the form field values with the submitted data so that the user doesn't need to keep reentering the same things over and over. forget about that dumb test_input() function you found or were given. the only thing it is doing that's appropriate is trimming the data. everything else is either wrong for the context or needs to be conditionally applied. you should not test if the submit button isset. there are cases where it won't be. you should instead test if a post method form was submitted. don't write out line after line of code for each form field. just keep the set of form data as an array, then operate on elements in the array in the rest of the code. this will lead to dynamically validating and processing the submitted form data, further simplifying the code. validate all inputs separately, setting up a unique and helpful error message for each validation error, storing the validation errors in an array, using the form field name as the array index. this array is also an error flag. if there are no errors, it will be empty, and you can use the submitted form data. you can also test/display the contents of this array at the appropriate location in the html document. as has already been stated, your database definition must enforce unique entries. since it must do this to prevent duplicates, there's no good reason for the extra code/query to try to select the data first. just attempt to insert it, then detect if a duplicate key error occurred. this is also mentioned at the linked to forum reply. if you switch to the much simpler and more consistent PDO extension, over half of the database related statements will go away, which will eliminate the mistake i saw, because you don't have to produce multiple statements with things in them for each column in a query. in most cases, you don't need to close prepared statements or close database connections, since php will automatically do this for you when you script ends.
  17. there are two main points for using a prepared query - to prevent sql special character in external, unknown, dynamic data values from breaking the sql query syntax. to speed up the overall process when executing the same query more than once within an instance of your script, since the communication and execution planning phase for the sql query statement is performed only once. if you are not doing either of these, don't use a papered query. when learning, developing, and debugging code/queries, you should display all php errors (when on a live/public server, you should log all php errors.) set php's error_reporting to E_ALL and display_errors to ON, in the php.ini on your system. if you put these settings into your code, parse/syntax errors wont be reported (the case of the missing } ) since your code never runs to change the settings for this type of error. putting these settings into your code also means more work for you later when you must find and change/remove them when moving the code to a live/public server. you also need error handling for all statements that can fail. for database statements, the easiest way of adding error handling, without adding logic at each statement that can fail (connection, query, prepare, and execute) is to use exceptions and in most cases let php catch the exception where it will use its error related settings (see above) 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 duplicate or out of range user submitted values. 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 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. to enable exceptions for errors for the mysqli extension, add the following line of code before the point where you make the database connection, then remove any existing error handling logic, since it will no longer be executed if there is an error - mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  18. for this part of your question, it depends on the operating system. for a case-insensitive operating system, such as Windows, Hello.php and hello.php are the same. for a case-sensitive operating system, such as lunix, those are two different file names.
  19. the warnings and notices are from php. they have nothing to do with with any framework the site is using for the presentation of information. the glob() is not matching any files and your code should test ( !empty($var) would work) before trying to access any of the results and output an appropriate message if no matching file was found. as to why the glob calls are failing, it would either be due to a problem with the spelling, capitalization, actual path being used, or there are no matching files inside the folders.
  20. the posted code contains at least three places where it looks like characters were cut off from wherever this code was copied from, which would be producing fatal php parse/syntax errors. you should have the php error_reporting/display_errors settings in the php.ini on your system so that ALL php errors will get reported and displayed. putting these settings in your code won't help for parse/syntax errors since your code never runs to cause the settings to take effect. next, you have probably 5 times too many queries, code, and variables. some suggestions - use exceptions for database statement errors and in most cases let php catch the exceptions, where it will use its error related settings to control what happens with the actual error information. you can then remove all the error handling logic that you have now. INSERT queries don't have WHERE ... clauses. the account_number column should be added to the list of columns being inserted. don't put external, unknown, dynamic values directly into an sql query statement. use prepared queries. you would also want to switch to the much simpler PDO database extension. don't copy variables to other variables for no reason. you should NOT maintain a balance column in a single row by updating the value. any transaction that increases or decreases an amount should be handled by inserting a new row in the transactions table. the sets of INSERT queries that deducts the amount from the source account and adds the amount to the destination account need to be part of a database transaction, so that they will either both succeed and be committed or they will be rolled back. the post method form processing code should be before the start of the html document and should store any validation error messages in an array, then test/display the contents of this array at the appropriate location in the html document. any header() redirect needs an exit/die statement after it to stop program execution. don't use a loop to fetch a single row of data from a query. just directly execute the fetch statement one time. any dynamic value you output in a html context (email, web page) needs to have htmlentities() applied to it to help prevent cross site scripting.
  21. the blank page is either due to $_POST["submit"] not being set (all the code is skipped over) or it's because you are not displaying the contents of the $error variable when it contains error(s).
  22. the database extension is responsible for providing the interface between your application code and the database server. it is used to make the connection, execute queries, and fetch/test the result from queries. so, updating old code to use a new and different database extension would involve replacing the existing connection, query, fetch, and result-test statements with the equivalent statements from the new extension. the PDO extension brings two things to php that eliminates a lot of old implementation logic, 1) prepared queries, when supplying external, unknown, dynamic data values to the query when it gets executed, and 2) exceptions for errors. a prepared query is a one that has a simple ? place-holder in it for each data value, the query is then prepared, as a separate step, and is supplied the actual data values when the query gets executed. all the extra code/syntax you may have now that's trying to make each different type of data safe and get the values into the sql query statement are removed. for your posted code, that would eliminate the protect() calls and eliminate all the extra quotes and concatenation dots around each variable in the sql query. for the UPDATE query you have shown, it would look like this - // build the sql query in a php variable. this helps when debugging, you can echo the query, it separates the sql syntax from the php syntax as much as possible, reducing typo mistakes, and will lead to further simplification of the code (common/repetitive logic can be consolidated) $sql = "UPDATE eusers SET Online = ? WHERE id = ?"; // prepare the query - this sends the sql query statement to the database server, where it will be checked for syntax errors and the query execution will get planned // $pdo in the following is the name of the variable holding the instance of the PDO database connection $stmt = $pdo->prepare($sql); // execute the query, supplying the variables that were removed from the sql query statement as an array. $stmt->execute([ $time, $_SESSION['uid'] ]); // for an INSERT, UPDATE, or DELETE query, use the following to get/test the number of affected rows - $affected_rows = $stmt->rowCount(); for a non-prepared query, all types - SELECT, INSERT, UPDATE, DELETE, you would just use the query() method, instead of the prepare()/execute() calls. for a SELECT query, you would then use one of the available fetch methods to retrieve the data. // for a query that will match at most ONE row of data, use the following to fetch a single row - $var = $stmt->fetch(); // for a query that will match a set of zero or more rows of data, use the following to fetch all the rows at once - $var = $stmt->fetchAll(); // the rowCount() method isn't available for all database types that PDO can be used with. // the universal way of testing if or how many rows of data a query matched is to just fetch the data and test the fetched result (a true value means there is data) or use the php count() function to get the number of rows of fetched data. // for the above two fetch... examples, to just test if the query matched any data - if($var) { echo "the query matched some data. var contains the data from the query."; } // if you actually want a count of the number of rows a query matched $num_rows = count($var); echo "the query matched $num_rows rows."; next, exceptions for errors. you ALWAYS need error handling for any statement that can fail. for database statements, if you use exceptions for errors and in most cases let php catch and handle the exception, php 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.) the exception to this rule are for errors that are 'recoverable' by the visitor to your site. these would be things like inserting/updating duplicate or out of range values. in this case, your code would catch the exception, test if the error number is for something that your code is designed to handle, then setup a message for the visitor telling them what was wrong with the data that they submitted. if the error number is for anything else, just re-throw the exception and let php handle it. lastly, the following is typical PDO connection code that shows setting some common options - $DB_HOST = ''; // database host name or ip address $DB_USER = ''; // database username $DB_PASS = ''; // database password $DB_NAME = ''; // database name $DB_ENCODING = 'utf8'; // db character encoding. set to match your database table(s) character set $options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // set the error mode to exceptions PDO::ATTR_EMULATE_PREPARES => false, // run real prepared queries PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC // set default fetch mode to assoc ]; $pdo = new pdo("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=$DB_ENCODING",$DB_USER,$DB_PASS,$options); this should cover everything needed to address the database statements in the posted code. i'll let others comment on what your code is doing that it should do differently.
  23. your code is apparently (there's too much code to sift though to really tell what it is doing in all cases) using the product_code as the cart's array index. this is the preferred method, since you can DIRECTLY test or reference the data in the cart via its index. to test if the item is already in the cart, all you need is an isset() test. to modify or delete existing data, just directly modify/unset it via the index. to insert a new item into the cart, just set/assign it using the new array index value. if the submitted product_code isn't valid (doesn't match any product/school choices) either due to a programming mistake, a product/choice being deleted after someone views the choices (choices shouldn't actually be deleted, just updated to indicate they are no longer available), or a nefarious data submission, you should setup an error message and report this condition to the visitor, i.e the selected product was not added to the cart, not a valid choice. you have a select/option menu for size choices that there's currently no processing code for. different sizes of something should be a unique and separate product_code. if you cannot change the design to do this, you will need to validate the submitted size choice, store it in the cart, display it when the cart is displayed, then finally store it when the cart is converted to an order. you will also need to qualify any cart add/remove operation with the submitted size selection. if there's 2 large size of some product_code and 1 small size of some product_code in the cart and someone adds one more small size of that product_code, the correct quantity needs to be modified. i would add a second array index to handle this and for anything that doesn't have a size choice, use some unique size value to indicate not to treat the entry as a size choice. lastly, don't put external, unknown, dynamic values directly into sql query statements. use a prepared query instead.
  24. the key to this working is probably emulated prepared queries vs true prepared queries. when you make the database connection are you setting the pdo emulated prepared query attribute to a false value? are you really sure you want or care to do this? since this doesn't return the data types for a non-prepared query you will always need to use a prepared query, with the overhead of an extra round-trip communication with the database server, for every SELECT query, even if you are not supplying any data via a place-holder.
×
×
  • 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.