Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,356
  • Joined

  • Days Won

    173

Everything posted by mac_gyver

  1. if you have any type of account (bank, credit, loan, itunes, cell phone data plan, in game purchases, ...) that keeps track of an amount (quantity or money) or have ever done any in person or on-line shopping, you have seen this being used. it's not overkill, it's a necessity that's used everywhere in real situations. it gives you a record/audit trail of each transaction, so that you know all the who, what, when, where, and why information about each transaction. this lets you detect and correct errors, produce reports,... this method also has the advantage of correctly working with multiple concurrent users, since the changes made by each user will be recorded separately (at least the OP removed a race condition, by eliminating a separate SELECT query to get the 'current' starting amount.) without doing this, by just maintaining the amount in a field, there's no record of any duplicate data submissions, incorrectly entered values (transposed digits, hitting the wrong key), programming errors, fraud/cheating, ... the first sign of a problem is when someone tries to use an amount, that the system says exists, but it doesn't. if the OP is really doing an inventory system, that's more than just a classroom assignment or part of a beginner's attempt at making a game, the current method will eventually get out of sync with the actual products and you won't know which of the possible reasons why because there's no record being kept of what values have affected the total.
  2. in addition to not being able to execute multiple queries in one sql statement (unless you use a php statement/method call that supports it), your form has two fields named quantity and three fields named id. only the last field for any name will 'win'. you need to get your form code under control so that you will know which field is going to actually supply the values that your form processing code will use. next, you shouldn't add/subtract values to maintain a quantity. your current method has no way of detecting/preventing multiple form submissions from incorrectly altering the data. you can end up with the wrong quantity values and you won't even know if this has occurred. the correct way of maintaining a quantity (or any other 'account' total) is to insert a new record for each transaction that adjusts the value, inset a positive value to add to the quantity and negative value to subtract from the quantity. you would then simply SUM() the quantity for any id value (use GROUP BY id) to get the current quantity.
  3. this is a very common application. there are countless examples posted on the web showing the logic needed to do this. the only portion of an authentication script that would be Postgres specific would be the DNS (Data Source Name) used when making the connection to the database server and any database specific sql and php statements and if you use php's PDO extension, the php statements would be generic, simple, and straightforward.
  4. the code at the top of your post has - setcookie('hs_user_sess', $session, time() + (86400*30));, but there is no $session variable present in that code, so it would set the cookie to an empty value. also, break; only works for loops and switch statements. it has no affect on if() statements, so in the cases where you have used it in the code above, all the logic is still being executed. if your code testing if the cookie is set is being executed on the same page request where you are setting the cookie, the $_COOKIE variable won't be set until the browser makes a request to the web server after you have set the cookie.
  5. you probably have a type conversion problem or a null value that's matching all values. a) how do you know the second query is (apparently) matching 5 rows? you have only shown the code getting the result from the queries. perhaps there's a logic error or a mis-display of the results? b) what exactly does using var_dump($motionid); show and what ARE the motions_id values in the incorrect result set? c) how did the rows of data get inserted into the votes table and what is the column definition for the motions_id column?
  6. the code on your page should be laid out in this general order - initialization, start of database dependent code, determine user state and permissions, post method form processing, get method business logic, end of database dependent code, get method presentation logic, and html docuement/template. 1) initialization - create/define things your code needs - session_start(), require files holding configuration data/function definitions, setup an autoloader for class definitions... 2) start of database dependent code - create a database connection. 3) determine user state and permissions - check if the current user is logged in and retrieve any permissions the user has. the rest of the code on the page would make use of the logged in state and permissions to determine what code can be ran and what content will be produced. 4) post method form processing - the post method form processing code, which causes an action or change in state or change in data values on the server, should come near the start of your file so that you aren't tempted to output anything to the browser before the action/state/or data operation has been performed by the processing code. if your page has multiple sections of form processing code, you would have them all groped together in this section of code. after successfully (no errors) processing any post data, do a header() redirect to the exact same url that the form submitted to. this will cause a get request for your page. this will cause the browser to forget that a form was just submitted to that url and it won't try to resubmit the form data if you refresh the page or browse back to the same url. this also enforces separation of concerns. post method form processing is a separate concern from displaying data due to a get request for your page. if you want to display a one-time 'success' message after the header() redirect, pass it in a session variable, then clear he session variable after the the message gets displayed. if there are errors while processing any post data, you would not redirect, stay on the page, let the rest of the code on the page display the errors, (re)display the form, and repopulate the form fields with (some of) the previously submitted values. 5) get method business logic - code that produces/gets data needed for the dynamic content on the page. this code contains any database specific code that knows how to retrieve data from your database tables. the result of this code should be php variables that the code later on the page uses as its input. this code should contain NO html/css/javascript markup. 6) end of database dependent code - you can (or let php do this when the script ends/exits) destroy any query result resources (to free up memory) and the database connection at this point since you won't need them any longer. 7) get method presentation logic - code that knows how to take the data (database data, errors, form data...) from ALL the above code and produce the dynamic output for the page. if the output doesn't require any 'heavy' processing/formatting, just use the data directly in the html page/template code. the result from this code should be php variables that the html page/template uses. this code should contain NO database specific statements. if your page has multiple sections of get method presentation logic, you would have them all groped together in this section of code. html document/template - this section starts with the <!DOCTYPE ... tag and ends with the </html> tag. it is the actual html document that the dynamic output is put into to make the complete page. if you use php (rather than an actual template system) only simple php conditional logic/loops, function calls (that are responsible for producing output), and echo statements should be present in this section of code. any data you output on the page needs to be passed through htmlentities() in order to prevent any html content in it from being operated on by the browser. if you organize the code on your page like this, it will separate all the different concerns, making it easier to see what your code is doing, easier to test, and easier to get help with because you can isolate and post just the relevant part. next, if you put the form processing code and the form on the same page, it will reduce the amount of code you have to produce, since it will eliminate the repetition of the common items. this will also let you re-populate the form field values in the case where there were validation errors with the submitted form data. some specific comments for the code you have posted - 1) the global keyword only has meaning when used inside of a function (which you are not doing) and even then it should be avoided as it breaks the encapsulation and scope. remove any lines of code containing the global keyword. 2) if you use a php array variable to hold validation error messages, it will also serve as an error flag. if the array is empty(), there are no errors. if the array is not empty(), there are errors. after you have validated all the input data, you would use that data if there are not errors. at the point of (re)displaying the form, if there are errors, you would display them, either as a group or display them individually near the form field they go with. 3) you should NOT be using addslashes() at all. 4) whatever your validateInput() function code is, is probably not actually validating anything. if you want help with the validateInput() code, you need to post it. 5) this is a bit tongue in cheek, but a person's age is not a fixed value, unless they are dead, and you should not be storing a person's age. you should be getting and storing the date of birth and then calculating the age when needed. edit: since you are using a file to hold the data, substitute 'file operations' for any mention of 'database' in the above information.
  7. your opening <table ... tag is broken, so either all the markup is being considered as being inside that tag and isn't being rendered when it is sent to the browser or the markup is being rendered, but not as a table. rather than to just tell us something didn't work, tell us what result you are getting and if it's not obvious what is wrong with that result, tell us what result you expected.
  8. @kessie, i have the same commentary about non-specific replies and replies repeating information already posted, just made for the purpose of posting a reply, any reply. when someone has a specific problem on any kind of help forum (cars, appliances, programming), replies that don't specifically and directly help with the subject matter, and are nothing more than supposition, just knock the thread off topic. an example i've had to deal with in finding a car part - someone asks about finding a replacement for a non-standard light bulb, for a specific year and model of a car, not listed in the operating manual, not available in the local auto parts store, which costs $10-20 from the dealer, and is available for less than $1 at electronics parts suppliers. anyone not posting specific, accurate, and relevant information about that light bulb for that year and model of car didn't help at the time of posting and doesn't help anyone who finds the thread later. @mbrown, if you form your sql query statement in a php variable, it will help avoid the type of sql syntax error you have, because it will separate the syntax of the sql statement from the php syntax that's using the sql statement.
  9. does your form page have any php code in it to retrieve the correct data from the database table? wouldn't that explain the undefined variable errors? next, the php code you have posted is a jumble of things that make little sense, and if they don't make sense to a human reader, they will make zero sense to the computer. it's got multiple session variables that indicate the logged in state (you should only have one), a call to some custom query() function that doesn't appear to be defined anywhere, no apparent code making the database connection, a mix of mysqli and mysql (no i) statements that won't work together, looping to retrieve data from a query that's expected to match a single row of data, not doing anything to validate the data, not doing anything to protect against sql special characters in the data from breaking the sql query statement (which is how sql injection is done), it is retrieving the correct row of data from the database table but is not using it, and it's processing the form data after the query that's retrieving the data, so any changes made to the data won't show up until the next page load, if you were using the retrieved data somewhere. i recommend that before you try to write code to do something, that you define what you want the code and data to do. you have two tasks - 1) display a form with the form fields populated with existing values (or the submitted values if there are validation errors), and 2) processing the form data. both of these tasks should first test that the current visitor is logged in. break each of these tasks down into a list of steps needed to accomplish the task, then write and test the code needed for each of the defined steps. only go onto the next step after you have successfully tested that the code for the previous step works. what should your form code do? - 1) detect if the current visitor is logged in. if not, either display a message or redirect elsewhere, then stop program execution so that the form will not be displayed. 2) make a database connection. note: depending on what else your page may be doing, the point where you make the database connection can be different then in this list. i also recommend that you use the php PDO extension (the mysql extension is obsolete and the mysqli extension is not the easiest to use.) 3) query for and retrieve the correct row of data from the users table. 4) use the retrieved row of data to populate the form field values. what should your form processing code do? - 1) detect if the current visitor is logged in. if not, either display a message or redirect elsewhere, then stop program execution so that the form processing code will not be executed. 2) detect if a post method form has been submitted. 3) validate the submitted form data. note: using an array to hold validation error messages will result in the simplest code and if you put your form and form processing code on the same page, it will be simple to display any validation errors and re-populate the form field values when you (re)display the form. 4) if there are no validation errors, use the submitted form data. 5) make a database connection. note: depending on what else your page may be doing, the point where you make the database connection can be different then in this list. 6) produce the sql query statement to UPDATE the data. note: you should use a prepared query to do this as it is the simplest and most effective way of preventing sql special characters in the data from breaking the sql query syntax/preventing sql injection. 7) execute the sql query statement. you can setup a success message, but the lack of an error would generally be the indication that the query worked. also, your current error message, to go back and try again, is not correct. if the query failed with an error, it means you have a programming problem and if the query ran but didn't update the row, it could just mean that none of the data values were 'edited'.
  10. readdir() returns the entries in the order that they are stored in the directory. to do what you want will require sorting by the raw filemtime() value. to do this, you would store the filenames and filemtime in an array, with the filename as the array index/key and the filemtime as the array value. you would then use either asort() or arsort() to sort the data by the filemtime values, then loop over the sorted data to display the information. i also recommend just using glob(), rather than all that opendir/readdir/filetype logic, to get the starting list of the files into an array.
  11. you should validate each input separately and set up a specific error message for each input so that the user doesn't need to guess which value(s) was(were) not selected. you would validate any empty values first, before testing if the first two values are not the same. if you use an array of arrays to hold the error messages, with the main array index being the key/section value (0, 1, 2, ...) and the secondary array index being the select name, you can either output all the errors as a group at the start of each section or you can output each individual error at the select menu it corresponds to. you would also want to validate all the sections of data at once (no break; in the loop) so that you could display all the errors at once. by breaking out of the loop upon the first error, the user will have to fix the error(s) with one section before seeing if there are more errors later in the submitted data. if you set up an array that defines the form fields and the label for each, you can use this to produce your table heading and to dynamically validate the data and dynamically set up the error messages. i also hope you are dynamically producing the select menus, which would allow you to select any existing option choices should there be validation errors so that the user doesn't have to re-select everything when there is a validation error.
  12. the universal method (no OOP pun intended) would be to fetch all the data from the query into a php array variable (see the PDO fetchAll() method), then you can test if the array is empty or not using the empty() function or how many rows are in the array using count() function. doing this (fetching all the data into a variable) also serves to separate the database specific code (that knows how to query and fetch the data) from the presentation code (that uses the data.) it also eliminates the 'out of sync' errors should you ever be in a position of not fetching all the data that you queried for. this also tends to force you to finish with the result set from one query before going onto the next query.
  13. you cannot (successfully) use the ip address to identify the visitor, since several people can share the same ip address and an ip address can even change during a single visit to a site. to avoid writing a bunch of extra code and queries, for a database based cart, just store the data as though it is an order with a status of 'pending'. see the following post (and the entire thread it is part of) for more information - https://forums.phpfreaks.com/topic/302627-how-may-i-able-to-getpost-my-code-that-allow-to-retrievepost-data-to-payment-page-and-to-get-the-total-from-myorder-page/?hl=%2Bpending&do=findComment&comment=1539851 this linked to post lists the database tables you need to accomplish this. also, as mentioned in the linked to post/thread, the php PDO extension is simpler and more constant to use than the php mysqli extension, especially when using prepared queries, which you need to use to supply data values to your sql query statements, to prevent sql injection. lastly, the best advice i can give to help you solve your current problem is to define what you want the code and data to do before writing any code. for your update_cart form processing code, define what inputs you have or need, what processing you are going to do based on those inputs, and what result or output you are going to produce. your form processing code should just process the form data. it should not be responsible for producing any output on the page, other than error or success messages related to the processing of the form data. there's no reason your form processing code should be calculating a sub-total or a total (these should be part of the code producing the dynamic output for the page and are not part of the form processing code) and since your cart is stored in a database, there's no reason to be storing any quantity values in session variables.
  14. as to your connection code. the 4th parameter CAN be a database name, but it's optional. you can leave it out, provide the name of the common database that most of your application code uses, or select the database by separately calling the ->select_db(...) method. since your query will be specifying the database name in front of each table name, it doesn't matter if or what database is selected for the single connection.
  15. before anyone bothers with the OP's code, be advised - 1) it totals ~ 500 lines of uncommitted code. 2) it uses the mysql_ extension. 3) there's no sql injection security. 4) there is some javascrpt in it that evaluates escaped strings to various <td ,,,,,> html values. hopefully the OP won't replace that with something else by the time his thread edit time expires or when he posts more code. 5) there are a bunch of verbose lower-case variable names, like $upgrademoneyorcredits and $newleveltime... 6) the func.php file contains several sections of in-line php code along with some function definitions, one of which could be replaced with a number_format() call. 7) the main file has post method form processing code interspersed with html. in short, it's impossible to tell what the code is doing now, in order to determine why it isn't working. to the OP, this code needs to be rewritten, reversing everything mentioned in my list.
  16. your change_password.php script contains a php syntax error on line 36. you need to set php's error_reporting to E_ALL and display_errors to ON in the php.ini on your development system to get php to help you. if you try to set these settings in your code, it won't help find php syntax errors in the same file because your code never runs when there is a php syntax error and the code trying to set the settings is never executed. next, as NotionCommotion posted above, you don't have a session variable named email, so the logic testing that session variable will always be false. when you log in a user, the only thing you should store in a session variable is the user id from the row in the user table. to get any of the other user data, you would use that user id to query for it when you need it. and, as you have probably seen in forum posts, you need to use php's password_hash() and password_verify() functions for your password hashing and you need to remove any @ error suppressors in your code.
  17. to summarize some of the information that has already been mentioned in this thread - what you seem to be missing, in trying to add newly submitted values into an array with previously submitted values, is that web servers are stateless. each request made to the web server is completely separate from every other request. to make data persist between requests, you must store it somewhere on the server (session variables, database) or you must pass it through the request (as hidden form field data or in cookies.) also, by definition, all values that are part of a http request are strings, regardless of what they represent. it's up to your application code to treat them as what they actually represent.
  18. this specific error text occurs when the database server is not running.
  19. the reason the code went from working to not, when you changed to the * is because the capitalization of your actual column names don't match what the php code is using. when you were specifically selecting the columns, the names in the SELECT statement are what was used in the retrieved data AND they matched the letter case of whatever the column names actually are because in the sql statement the letter case of the column names don't matter. if you do a print_r($row); in your code, you will see what the associative array index names are. constancy counts in programming, whatever your column names are, should be used throughout your code. also, if had php's error reporting set to E_ALL and display_errors set to ON (preferably in the php.ini on your development system), php would help you by reporting and displaying all the errors it detects. next, don't write out line after line of code who's only purpose is to copy variables to other variables. use the original $row[...] variables. finally, when something doesn't work, provide the actual output you are getting. getting 'no results' has different meaning depending on who you are and what your definition of results is.
  20. if that question is about doing things automatically, you would set up a cron job/scheduled task to run a php script, once a day. the php script would check if there are any operations to perform on the particular date or day of the month. for the add rent operation, it would query for the active tenancies (where the current date is between the start date and the end date of the tenancy), and add 'rent due' records with the appropriate field values to the payment table.
  21. actually, i see a mis-statement - the late fee would be a negative amount (an amount due), waiving of the late fee would be row with a positive amount (a credit made to the account.)
  22. the problem is in the 'save the data' part of the process. all the posted information, except the one line of php code with the escape string call in it, is about the google map auto-fill api, which occurs before you submit the form. you haven't shown the form (is there a form? is the form field inside the form? does the form use method='post'?), how the form gets submitted (is the browser submitting the form or are you using ajax?), or enough of the form processing code (could the form processing code be running, but you are redirecting/re-requesting the page and the error you are seeing is from the second execution of the page?) in short, post the code that's relevant to the problematic part of the process, that would be needed to reproduce the problem, in order to get the quickest solution.
  23. this is/should be the same as a bank or credit card account. you are inserting rows that represent positive and negative amounts for an account, the tenancy_id in this case. you can SUM the amounts for each account/tenancy_id to determine what the balance is on any date. when the rent becomes due in a month, you would add a row to the payment table, with a negative amount and the appropriate amount_type_id for rent due, along with the correct tenancy_id and date. this will result in a negative balance (amount due) when you SUM() the amount column for each tenancy_id (you would GROUP BY tenancy_id in the sql statement.) if payment(s) are made (row(s) with a positive amount) they offset the rent due, when you SUM() the amount column on the 'late fee date' you will get a zero. if you get a negative result, it would mean that the (whole) rent has not been paid and you would insert a row in the payment table for the late fee (a negative amount with the appropriate values for the other columns.)
  24. the tables that hold 'defining' data should contain the unique/one-time and generally static information for what they define. a property table should only contain information about properties. a property can have a succession of tenants, each with different rent amounts, so the information about each instance of a tenancy needs to be stored in a second table. the payment table holds information related to the instances of tenancy. the actual tenant/renter personal information is separate from this data. see the following list of tables i would start with - property - id | title | address tenancy - id | property_id | tenant_id | rent | start_date | end_date tenant - id | first_name | last_name | email | phone payment - id | tenancy_id | amount | amount_type_id | date | note amount_type - id | name most of this should be self-explanatory. the amount_type would be things like full rent, partial rent, late fee, waived late fee, rent refund, ... the payment table would hold actual payment amounts. plus amounts are payment in and minus amounts are payment out. the code that calculates the late fees would add row(s) to the payment table, with the amount_type_id for a late fee. if a specific late fee is waived, the row that gets added to the payment table would have a negative amount equal to the late fee amount and an amount_type_id for a waived late fee.
  25. to create a multi-user system, you must first have a login system. this will define user ids that you would store in any related data table to identify who the data is for. you would NOT have columns in your data table for each user. you would instead store a row in your data table for each user/exercise combination. if your page(s) can only be accessed when there is a logged in user, you would detect if there is a logged user first and only display information and process forms if there is. if there is not a logged in user, you would display a login form and enable the processing of the login form. next, you would have a table where the exercises are defined, that has an id (auto-increment) column and an exercise name column. you would query this table to get a list of the exercises for the select/option menu. you would store the exercise id in any table holding data related to the exercises. your data table would then have columns for the user id, the exercise id, and the weight. you would insert a new row if the data for a user/exercise doesn't exist and update the row if it does. there's a single query that will do this, an INSERT ... ON DUPLICATE KEY UPDATE ... query. you would define the user id and exercise id columns as a composite index to allow this query to work. lastly, your code needs to be organized as follows - define or require any configuration/settings and functions that your main code needs. start the session. create the database connection. you should only do this once. process any post method form data. there would be a section of code for each form the page must process. get/produce any data needed to display the page. the data should be stored in php variables. there would be a section of code for each different thing that can be displayed on the page. output the html document.
×
×
  • 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.