Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,508
  • Joined

  • Days Won

    185

Everything posted by mac_gyver

  1. one of the file uploads is failing, but because you don't have error checking and validation logic, you don't know if or why it is failing. the post method form processing code should - detect if a post method form has been submitted. do not attempt to test if the submit button is set. if the total size of the form data exceeds the post_max_size setting, both the $_POST and $_FILES arrays will be empty. you need to test for this condition and setup a message letting the user know that the form data was too large and could not be processed. if there is $_FILES data, you need to test the ['error'] element of each file to make sure it uploaded without any error before using any of the file data. there's a list of the error values at https://www.php.net/manual/en/features.file-upload.errors.php don't copy variables to other variables for nothing. this is just a waste of your time typing. just use the original variables. you need to validate all input data before using it, storing validation errors in an array using the field name as the array index. if an input is 'required' and it is an empty string or it must have a specific format, setup a unique message for each validation error telling the user what was wrong with the data value. after the end of all the validation logic, if there are no errors (the array holding the errors will be empty), use the submitted form data. using a prepared query (the PDO database extension is much simpler to use than the mysqli extension), insert the data and get the last insert id from that query. use the id as the file part of the filename. as already mentioned, user submitted data can be anything and should be carefully used or in this case not used at all as part of the filename.
  2. the key to updating an existing row or inserting a new row is the existence or absence of an id (autoincrement primary index) in the form data. if your database table doesn't already have an id/autoincrment column, add it. when you query to get the existing data to edit, add this column to the SELECT ... list (you should actually list out the columns you are selecting, rather than use *). output the id in a hidden form field. in the form processing code, if the id input is a true value, execute the code for an UPDATE query. if it is not a true value, execute the code for an INSERT query. to handle both having existing data to edit or no data, you should have an intermediate array variable, such as $post, that will initially hold any existing data that you fetch from the SELECT query, then inside the post method form processing code be assigned a trimmed copy of the $_POST form data. in the form value attributes, use php's null coalescing operator (??) to output the corresponding $post value or an empty value - Energie: <input type='text' name='Energie' value='<?=$post['Energie'] ?? ''?>'><br>
  3. the reason the date isn't being used in the first type='date' field is because that's already a php string. don't use <?= ?> tags around the variable, just use the $newdate variable - <input type='date' name='date' value='$newdate' > next, nested forms are invalid. the date search form needs to be closed with a </form> tag, before you start the next form. several of the form fields have the same name, so, only the value from the last one will be used. the post method form processing code should be on the same page as the form. this will simplify all the code and allow you to repopulate the field values if there is a user/validation error in the form processing code. all those lines of code copying one variable to another is a waste of your time typing. just use the original variables. why on earth are you using the PDO database extension to get the existing data to be edited, then using the mysqli database extension in the post method form processing code? just use the much simpler PDO extension everywhere. also, use a prepared query for the UPDATE query and the UPDATE query needs a WHERE clause so that you are updating the correct row. lastly, if there can be more than one row per date, you need to loop to fetch and produce the edit form(s) with either one total form or one form per row and you would need to use an id (autoincrement primary index) to determine which row to update.
  4. then $_POST['submit'] is likely not set and that block of code isn't running or you have some code that you didn't post that's setting it to null. do you have php's error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini on your system, so that php would help you by reporting and displaying all the errors it detects? you should be getting an undefined variable error for $mentor and another error at the foreach() statement about it being null. next, a post method form is using when performing an action on the server, such as inserting, updating, deleting data, or sending an email, ... Yo should be using a get method form/link for searching for data to display.
  5. i suspect the error is due to exceeding some limit at your free/cheap web hosting - you might ask their support group. already stated -
  6. see if the web server error log contains any additional information. you should be using a localhost development system when learning, developing, and debugging code/query(ies). doing this on a live/public server wastes a bunch of time constantly uploading files to see the result of each change and since your code is not secure, can allow someone to abuse your web hosting. only put complete, secure code onto a live/public web site.
  7. also, if you are just starting out, learn and use the much simpler and better designed PDO database extension. don't put data values directly into an sql query statement. you should be using a prepared query when supplying external, unknown, dynamic values to the query when it gets executed.
  8. while this isn't the cause of the problem, you need to validate the resulting web page(s) at validator.w3.org you cannot spread the markup for a form throughout a html table. you can put a compete html table inside a form and you can put a complete form inside a single table data cell <td>...</td>, but you cannot intermix the markup for a table and a form. also, the form and form processing code should be on the same page. this will simplify all the code. the code for a page should be laid out in this general order - initialization post method form processing get method business logic - get/produce data needed to display the page html document post method from processing code should - detect if a post method form was submitted. keep the form data as an array variable, then operate on elements in this array variable throughout the rest of the code. trim all the inputs at once. when you do item #2 on this list, you can trim all the data using one single line of code. validate all the inputs, storing validation errors in an array using the field name as the array index. after the end of all the validation logic, if the array holding the errors is empty, use the submitted form data. an insert/update query can result in duplicate data for things that must be unique, such as a username or email column. your code should handle query errors in these cases. the simplest way of doing this is to use exceptions for database statement errors and have exception try/catch logic only is these cases. the catch logic would test the error number and if it is for something that the visitor can correct, setup a message telling the visitor exactly what was wrong with the data that they submitted, so that they can potentially submit new value(s) that will succeed. for all other error numbers, just re-throw the exception and let php handle it. after the end of the form processing logic, if there are no errors, 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 resubmit the form data should the visitor reload the page or navigate away from and back to that URL. if you want to display a one-time success message, store it in a session variable, then test, display, and clear that session variable at the appropriate location in the html document. if there are errors at item #5 on this list, the code would continue on to display the html document, display any errors, redisplay the form, populating the field values with any existing data. any dynamic value you output on a web page should have htmlentities applied to it to help prevent cross site scripting. the http 405 error means you are using a method that isn't supported or configured correctly. this isn't being cause by anything you are doing with the database server. what is the actual URL of the form page and what is the url in the browser's address bar after you submit the form? as a test, to see if just a basic form will work, make a new .php page with the following and test it - <?php echo '<pre>'; print_r($_POST); echo '</pre>'; ?> <form method='post'> <input type='text' name='somefield'> <input type='submit'> </form> after you submit the form, the print_r output should show an array with the field name as an index and whatever value you type into the field.
  9. since you have provided no actual information about paths in use, i'll guess this has to do with relative paths, which include() will search the include_path to find. to get file_get_contents() to search the include path, add the FILE_USE_INCLUDE_PATH flag as the 2nd call-time parameter.
  10. could you post the ACTUAL url you tried in your markup. i copied the above into a browser's address bar, added #art15 on the end of it, and it went to that point on the web page. there is no id="specialfirewall" on that page, which would explain why a link with #specialfirewall on the end of it only goes to the page and not to a specific location on that page.
  11. there actually is a difference. try a number like .45 it won't match the (\d.+) case. this is because there isn't a numerical digit as the first character. the [] define a character set/class, that will match any of the characters in any order, even just a . character. without the [], there still can be any number of each character, but the first one must be a numerical digit.
  12. there are multiple ways of accoupling a task. you would need to post what you tried, along with the input data that 'worked'.
  13. where are you kids getting this from? there's no good reason to catch a connection error, only to throw a new exception consisting of only the error message and code. this leaves off the filename and line where the error occurred, hindering debugging. for a connection error, just let php catch and handle the exception, i.e. remove all the try/catch logic from that code. the only case where your code should catch and handle a database exception is when inserting/updating duplicate or out of range visitor submitted data. the catch logic would test the error number and if it is for something that the visitor can correct, setup a message telling them exactly what was wrong with the data that they submitted, so that they can potentially submit a different value that will succeed. for all other error numbers, just re-throw the existing exception.
  14. i don't what you are reading, but that's incorrect. if db column is defined as NOT NULL, it simply cannot hold a null value. if you insert/update the column to a null value, it produces an error and the insert/update query will fail. the column must have a non-null value in it. no. every instance of your php script and any data that they insert/update are handled by completely separate processing threads. for the usage you have described, the last insert id from any insert query will be valid for that instance of the script. your database MUST enforce uniqueness, due to the race condition already mentioned. since you must do this, there's no good reason to run a SELECT query first, since the actual insert/update query can fail with a duplicate error if another instance of your script inserted/updated the data first. so, Keep It Simple (KISS), just attempt to insert/update the data and detect if a duplicate index error occurred.
  15. the u and p are alias names. they save a bunch of typing when writing queries. technically, it's AS u and AS p, but the AS keyword is optional. you must prepend the table name or its alias when a column reference is ambiguous. i personally always prepend the alias so that anyone looking at a query will know which columns are part of which tables without needing to know the table definitions.
  16. real-time, multitasking, interrupt/event driven operating systems are a thing now. any one instance of your code does run from start to finish, but it can be interrupted several times for other things that are going on on the computer. and in fact, php will pause, allowing the processor to service other tasks, while waiting for a database query to execute.
  17. did you not read the reply in the existing thread for this task? anyways, the form field values for a get method form will replace any get parameters you try to put on the end of the url in the action='...' attribute. to supply 'additional' get parameters, you would need to use hidden form fields.
  18. $_POST['fname'] IS a perfectly fine php variable and already contains the value from that field. assuming you didn't need to do anything to that value that would change it before using it, just use that variable when needed. don't waste time making up other variable names and typing out code making two copies of that original variable. programming IS a tedious typing activity. don't make it harder than it needs to be. his comment and most of what i wrote are about only doing necessary work/typing that contributes to the overall goal.
  19. correct. this is a waste of your time typing. you wrote out a line of code (10) for each input. if you had 30 or 100 inputs would writing out a line of code for each one make sense? all this is doing, except for the very last one, which will either be set or it won't, is copying variables to other variables for nothing. you should actually keep the form data as a set, in an array variable, then operate on elements in this array variable throughout the rest of the code. this will allow you to then dynamically process the data, rather than writing out repeated blocks of code that only differ in the input they operate on. the only time you should create a new variable for a piece of data is if you modify the value in some way, so that it has a different meaning from the original. one such case is trimming the data. see the next point. forget you ever saw the word sanitize related to data. except for trimming data, so that you can detect if it was all white-space characters, you should NOT modify data. you should only validate data. if the data is valid, use it. if it is not valid, setup a message for the visitor telling them what was wrong with the data so that they CAN correct the value and resubmit it if appropriate. if you keep the data as a set, in an array variable, as suggested above, you can trim all the data at once using ONE single line of code. in this case, you would put the trimmed working copy of the form data into a different array variable name, such as $post, since it no longer has the same meaning as the original data. additionally, you have a bunch more typing and keeping track of things than what is necessary, and some other points - for the initial problem, using simple ? positional place-holders requires much less typing then using named place-holders and would have prevented the error entirely. don't use multiple names for the same piece of data. this just creates more work for you in keeping track of what any particular piece of data is called. if first_name, last_name, post_code, ... are what the database column names are, just use those same names throughout the code and html markup. since the form and form processing code are on the same page, simply leave out the entire action='...' attribute to cause the form to submit to the same page it is on. you can include the form field between the <label></label> tags, letting you eliminate the for='...' and id='...' attributes. use 'require' for things that your code must have for it to work. the post method form processing code should be above the start of the html document. when you validate the data, store the user/validation errors in an array using the field name as the array index. after the end of all the validation logic, if the array holding the errors is empty, use the submitted form data. the ; on the end of the sql query statement is no needed. this query can/should produce a duplicate error for the field(s) that must be unique, such as the email. any field that must be unique should be defined in the database table as a unique index. any insert/update query that can result in a duplicate error should have an exception (since you are using exceptions for database errors) try/catch block. the catch code should test if the error number is for a duplicate index error, then setup a message for the visitor telling them exactly what was wrong with the data that they submitted. for all other error numbers, just rethrow the exception and let php handle it. after the end of all the form processing logic, if there are no errors, 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 resubmit the form data if the visitor reloads the page or navigates away from and back to that url. this is the reason for putting the form processing code above the start of the html document. if you want to display a one-time success message, store it in a session variable, then test, display, and clear that session variable at the appropriate location in the html document. if there are errors at item #8, the code would continue on to display the html document, display any errors, redisplay the form, populating the form field values with any existing data so that the visitor doesn't need to keep reentering data over and over. any value you output on the web page needs to have htmlentities applied to it to help prevent cross site scripting.
  20. the ? place-holder that's put into the sql query statement is only the ? character, no single-quotes, no wild-card characters. any wild-card characters go around the value you are supplying in the execute() call. you should also be using a method = 'get' form when performing a search and to get the form to submit to the same page it is on, simply leave the entire action='...' attribute out of the form tag. also, Don't Repeat Yourself (DRY.) use one single search form. to select which type of search, use either a select/option menu or radio buttons. the serach form should be 'sticky' and repopulate the form fields with any existing search inputs and use css instead of in-line styling.
  21. @phppup, i'm not sure what you read, but the OP is already querying for the correct data, is looping over the result from that query, and producing output. the only issue is needing some specific direction on how to output the store information only once per set of store data (and some extra {} in the posted code.) for the OP, here's an outline of code that will do this - // in your database specific code, index/pivot the data when you fetch it using the store id (first column selected) $result_data = $stmt->fetchAll(PDO::FETCH_GROUP); // at the point of producing the output if(!$result_data) { echo 'There is no data to display.'; } else { foreach($result_data as $arr) { // start a new store section here... // reference elements in $arr[0] to display the unique store information // loop over the sub-array of product data for the current store foreach($arr as $row) { // reference elements in $row to display product information } // end the current store section here } }
  22. you are performing a search based on the expname and period. period is one of 6 possible choices, which determines the starting year/month and ending year/month for the data to match in the sql query. note: for a fiscal year from Apr 1st one year to March 31st the next year, the YEAR(expstartdate) won't be a single value. the sql query should actually build the full start date and full end date for the period that was chosen, then use a BETWEEN comparison in the query to find all the matching data. once you get this to work using a get method form, it is easy to convert to use AJAX to submit the form and output the returned markup from the sever-side code.
  23. for building the select/option menu, do something like this data-driven example - <?php $period_choices = []; $period_choices["CurrentFY"] = 'Current Fiscal Year'; $period_choices["CurrentCY"] = 'Current Calendar Year'; $period_choices["NextFY"] = 'Next Fiscal Year'; $period_choices["NextCY"] = 'Next Calendar Year'; $period_choices["PreviousFY"] = 'Previous Fiscal Year'; $period_choices["PreviousCY"] = 'Previous Calendar Year'; ?> <div class="dropdown"> <select id="periodDropdown" name="period" class="btn btn-outline-primary"> <option value=''>Select Report Period</option> <?php foreach($period_choices as $value=>$label) { // note: you should actually be using $_GET when determining what will be displayed on a page $sel = isset($_POST['period']) && $_POST['period'] == $value ? ' selected' : ''; echo "<option value='$value'$sel>$label</option>\n"; } ?> </select> </div> for the repetitive javascript code, to select the year, mSC or mSF array, and mnthC or mnthF array to use, do something like this (untested) - $("#periodDropdown").on("change",function(){ event.preventDefault(); filterterm = $(this).val(); console.log(filterterm); //Reset header rowmonthS.innerHTML="<th>Summary</th>"; rowmonthI.innerHTML="<th>Income</th>"; rowmonthE.innerHTML="<th>Expense</th>"; // rowinc.innerHTML="<td></td>"; // rowexp.innerHTML="<td></td>"; switch(filterterm) { case "CurrentFY": var yr = "Year "+new Date().getFullYear(); var m = mSF; var mnth = mnthF; break; case "CurrentCY": var yr = "Year "+new Date().getFullYear(); var m = mSC; var mnth = mnthC; break; case "NextFY": var yr = "Year "+new Date(new Date().setFullYear(new Date().getFullYear() + 1)).getFullYear(); var m = mSF; var mnth = mnthF; break; case "NextCY": var yr = "Year "+new Date(new Date().setFullYear(new Date().getFullYear() + 1)).getFullYear(); var m = mSC; var mnth = mnthC; break; case "PreviousFY": var yr = "Year "+new Date(new Date().setFullYear(new Date().getFullYear() - 1)).getFullYear(); var m = mSF; var mnth = mnthF; break; case "PreviousCY": var yr = "Year "+new Date(new Date().setFullYear(new Date().getFullYear() - 1)).getFullYear(); var m = mSC; var mnth = mnthC; break; } //Dynamically change year displayYear.innerHTML=yr; //Populate Month header for(var i=0;i<m.length;i++){ var th = document.createElement("th"); th.innerHTML=m[i]; th.colSpan=2; $(th).clone().appendTo(rowmonthS); $(th).clone().appendTo(rowmonthI); $(th).clone().appendTo(rowmonthE); } element_replace(); // not sure what this is here for }
  24. your apparent question is how to use javascript to change (assign) a php array definition or select which php array to use when building and outputting the page? if that's the question, you cannot directly do this in the browser. the php code is executed on the web server when the page is requested. to actually do this would require sending some value to the web server that tells the php code what to do, then the php code assigns or selects which array definition to use and outputs it back to the browser. if your question actually is how to use the correct mnthC or mnthF javascript arrays (which the definition appears to be backward), depending on which select/option was picked, you would just assign the correct one to a common working variable, then use that common variable where you want. so. don't show us a non-working attempted solution, that doesn't indicate what you are trying to do, tell or show us what the overall goal is you are trying to achieve? are you actually trying to change something happening in the server-side php code or are you trying to do something entirely within the browser? next, don't write out code for every value. the select/option menu should be dynamically built on the web server, by having an array of the choices, then loop over that defining array to build and output the option choices. in the javascript, where the only difference between all the repeated bocks of code is the year value and if using the mSC or mSF arrays. you should detect the filterterm value and setup a common year and common array variable, then use those common variables as the input for one instance of the javascript code.
  25. @gw1500se, a post method form can have get parameters in the url. for performing an action on the server, such as inserting, updating, or deleting data, a post method form is correct. you can get a form to submit to the same page it is on, and 'automatically' include any existing get parameters, by simply leaving the entire action='...' attribute out of the form tag. a number of the $_POST elements you are using don't match what the posted form is submitting. for debugging, add the following line of code before the start of your form processing code - echo '<pre>'; print_r($_POST); echo '</pre>'; next, your post method from processing code should - detect if a post method form was submitted before referencing any of the form data. once you have done item #1, except for unchecked checkbox and radio buttons, all form fields will be set, even if they are empty. all the isset() statements for the always set fields are a waste of typing and in fact are hiding typo mistakes in the current code. trim all the input data at once. external data submitted to your site can come from anywhere, can be anything, and cannot be trusted. you must validate all input data before using it. your current image handling code (i'm not sure where $name is coming from) will allow any type of file, such as a .php file, containing anything, such as php code, to be put anywhere on the server, using directory traversal. validate all inputs, and pieces of inputs, storing validation errors in an array using the field name as the array index. after the end of the validation logic, if there are no errors (the array holding the errors will be empty), use the submitted form data. set the default fetch mode to assoc when you make the database connection so that you don't need to specify it in each fetch statement. list out the columns in the INSERT query. this will help avoid mistakes and make your code self-documenting. after you have processed the form data, if there are no errors, redirect to the exact same url of the current page to cause a get request for that page. if there are errors at step #5, the code would continue on to redisplay the html document, display any errors, redisplay the form, and populate appropriate fields with their existing values so that the visitor doesn't need to keep reentering data over and over. often, the failure logic for a condition test is shorter than the success logic. if you invert the condition being tested and put the failure logic first, it will make your code easier to read and follow. if you want to display a one-time success message (step #8), store it in a session variable, then test, display, and clear that session at the appropriate point in 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.