Jump to content
Old threads will finally start getting archived ×

mac_gyver

Staff Alumni
  • Posts

    5,503
  • Joined

  • Days Won

    184

Everything posted by mac_gyver

  1. in the mysql documentation, where the year() and curdate() functions can be found, there's a date_format() function that has a way of doing what you are asking - https://dev.mysql.com/doc/refman/8.4/en/date-and-time-functions.html#function_date-format didn't everyone learn from the y2k problem not to store years as 2 digits?
  2. secondary to the problem in this thread, if you are at the point of updating data, you should be using a unique id to reference specific row(s) of data.
  3. you should use a decimal data type. a float data type suffers from floating point conversion errors, because some values cannot be exactly stored. the = comparison doesn't work because the actual value as a float is something like 27.550001 (just an example) the like comparison works because the value is converted to a string and the like compares the values character by character.
  4. what is the data type of the cost column?
  5. i'm going to guess that the overall goal you are trying to accomplish is reading data from an api and insert new data into a database table or update existing data? if so, you can accomplish the insert new data/update existing data using a single query. see - https://dev.mysql.com/doc/refman/8.4/en/insert-on-duplicate.html
  6. danger of what? your example doesn't do what you think. the javascript is NOT calling the php function. the php code runs on the web server when the page is requested. the php code is echoing whatever the function produces (and the echo tester(); statement echoes a null value because the function is not returning anything.) if you look at the 'view source' in the browser of the page that this code is on, the output from the php code is already there. all the javascript is doing is taking what was assigned to the test variable and putting it into the id="tx1" element. the code might as well just directly echo whatever the function produces in the markup for the id="tx1" element. how often does this remote data change? you would need to cache/persistently store this remote data somewhere in order to avoid reading it again. web servers are stateless. they don't know or care what happens outside of the current http(s) request they are serving. when the php code on a page ends, all the resources used in the code are destroyed, so the remote data that you read is destroyed. perhaps if you provide a more helpful example of what you are trying to accomplish, rather than your proposed solution for accomplishing it?
  7. browsers, including javascript running in the browser, make http(s) requests to web servers. the browser/javascript is not directly calling anything in the php code. the server-side code, on the page that you make the http(s) request to, would build and execute any edit/update query for a database. to use javascript to make a http(s) request, after the page has been requested and sent to the browser, you would make the request using ajax. see - https://developer.mozilla.org/en-US/docs/Glossary/AJAX all data submitted in http(s) requests to a web site can come from anywhere, not just your web pages, can be set to anything, and cannot be trusted. you must use the data securely in whatever context you are using it in. if the edit/update operation requires a logged in user having permission to perform an update query, the server-side code must have logic to enforce these conditions. the actual query must securely use the data to protect against any sql special characters in a value being able to break the sql query syntax. the simplest way of providing this protection, for all data types, is to use a prepared query. what does reading information from a source that takes a long time have to do with editing/updating data in a database?
  8. you didn't answer what is wrong with the last posted code/output? i understand your code perfectly. the list of programming practices will help to - secure your web site, provide a good User eXperience (UX), simplifies the code, and corrects some mistakes. i looked back at the search form, here's a similar list for it (repeats some things already posted) - to get a form to submit to the same page it is on, simply leave out the entire action attribute. as already written, this should be get method form and it should be 'sticky' and reselect any existing option choices. you need to validate the resulting web pages at validator.w3.org you should list out the columns you are SELECTing and only list the ones you are using in the code. you should (almost) always fetch data using an associate index name so that if your database table gets rearranged the code will still work and your code will be self-documenting (anyone reading it can tell what it is doing without needing to know what your table definitions are). any query that can match more than one row of data needs an ORDER BY ... term so that the data is in an expected order. some of your queries have an ORDER BY, some don't. using a character data type for numerical data won't sort correctly once you have values with more than a single character length. you should use a numerical data type for numerical data. the default ORDER BY ... direction is ASC. you don't need to specify it in a query. if a query doesn't match any data, you should output a message stating so, instead of outputting nothing. you need to apply htmlentities() to dynamic values being output in a html context, right before/as they are being output in order to prevent any html entities in a value from being able to break the html syntax. if you use php's short-open-print-tag <?= it will save typing. also, you can leave out the closing ; right before a closing tag ?> saving typing. there's a ; on the end of all the while ():; statements. this should either be a syntax error or is short-circuiting the loop and should be removed. for the 'required' attribute to work for a select/option menu, the first option choice must have an empty value and serve as a prompt to make a choice. you only need to use the 'required' attribute, you don't need the ="required" value. for a <label> to work, you must either have a for='...' attribute and a corresponding id='...' attribute in the field or more simply just put the closing </label> tag after the form field it corresponds to. if you have a <label>, you cannot have an empty display item for the first <option></option> choice. don't use a series of name-numbered variables. you are/should be completely dealing with the result of one query before going on to the next. just reuse simple variable names.
  9. and what exactly is the problem with the last posted code? here are some points for the current code - you should use a single database extension. now that you have used the much simpler and better designed PDO extension, all your code should be updated to use the extension. you should NOT use the mysqli_real_escape_string() function, which probably doesn't have the character-set set, to match your database tables, when the connection was made, then put these pieces of data directly into the sql query statement, as this can allow sql special charters in a value to break the sql query syntax. you should use a prepared query. converting a query that has php variables being put into it into a prepared query is straight forward. if you need, someone can post a list of instructions how to do this. you should use a get method form when determining what will be displayed on a page. this is so that if someone finds a result they want to return to or share with someone, they can bookmark the URL or share the URL and be able to return to the same result. the search form should be on the same page as the result and the form should be 'sticky' and repopulate the fields, selected options, checkboxes, and radiobuttons with any existing values so that if the search doesn't find what the user expects, they can simply make changes to the search values and try again. all the search form processing code should be inside the conditional statement testing if the form has been submitted. the current code will produce a bunch of php errors and likely produce no search result and output if the page is requested without any form data. you need to trim, mainly so that you can detect if all white-space characters were entered, then validate all input data before using it. the search inputs you have shown are all 'required'. if they are not all valid, you should output error messages stating what is wrong with them and NOT run any of the query/output code. if you want to make any of these search inputs 'optional' you will need to dynamically build the WHERE part of the query and only include the terms that have search values. the use of LEFT JOIN doesn't make sense (to me). it indicates that you want to get marks data that may not have any student or school associated with it. you should just use a JOIN if you only want marks data that has school/student data. if a query doesn't match any data, you should output a message stating so, rather than outputting nothing. you need to apply htmlentities() to dynamic values being output in a html context, right before/as they are being output in order to prevent any html entities in a value from being able to break the html syntax.
  10. this is the thead section - <thead> <tr class="text-center"> <th class="th-sm text-center">Subject </th> <th class="th-sm text-center">Class Score <br>(30%) </th> <th class="th-sm text-center">Exam Score <br>(70%) </th> <th class="th-sm text-center">Total <br>(100%) </th> <th class="th-sm text-center">Grade </th> <th class="th-sm text-center">Position </th> <th class="th-sm text-center">Remarks </th> </tr> </thead> it is the same for every student. your output is incorrect because the markup you are producing is broken. the code inside the loop is incorrect. the reason I posted an outline of what the code should do is to help you to be able to produce the correct output that will work. i recommend that you validate the resulting web page at validator.w3.org
  11. in looking at the markup you are creating, id's must be unique. if you are using the id attributes for styling, you need to use css classes instead. also, since the thead section is the same, you should build it once, in a php variable, before the start of any looping, then just echo that variable when needed.
  12. i recommend indexing/pivoting the data using the 'studentid' as a main array index when you fetch the data. this will give you an array of sub-arrays, with one sub-array for each student. this eliminates the need for conditional logic to test when the student changes and eliminates repetitive code and logic to close out each student section, but not for the very first one, before starting a new student section, and again after the end of the output. // index/pivot the data using the studentid as the main array index $data = []; while ($row = mysqli_fetch_assoc($run)) { $data[$row['studentid']][] = $row; } this also allows you to use print_r() or var_dump() on the data to make sure it is what you expect, before trying to produce the output. you can then use two nested foreach loops to produce the output. you also need to define the markup you are trying to produce, before writing any code, something like - // foreach data as student // reference the zero'th row of student data to get the one-time values for the heading // output heading information // start table // start the thead section // output the tr // end the thead section // start the tbody section // foreach student as row // output the tr // end foreach // end the tbody section // start the tfoot section // end the tfoot section // end the table // end foreach
  13. yes. which you can determine by testing. unchecked checkboxes are not set in the submitted form data. your code should only be concerned if the checkbox data isset() or is (not) !isset(). the logic would be - if (isset($p) && !isset($d) && !isset($c) && !isset($o)) { echo "error"; }
  14. the 'successful' case is: $d == "Yes" || $c == "Yes" || $o == "Yes" because you are using negative logic to produce an error, the complement of this is: $d != "Yes" && $c != "Yes" && $o != "Yes" // what i think you want if ($p == "Yes" && $d != "Yes" && $c != "Yes" && $o != "Yes") { echo "error"; }
  15. your written statement is ambiguous. please post some examples showing what result you want for different input combinations. specifically, what is the 'successful' case, which can then be complemented to produce the error case? what do you want when $p is not Yes? is that an error or does it mean that you don't care about the other three values?
  16. are you asking this because something you have shown us doesn't work or for a critique of the method? here's a list of points for the posted code - i recommend naming the connection variables more uniquely, such as $db_host, $db_name, $db_user, $db_pass. you are going to require this code into a main file. depending on where it gets required at, you could have other $user and $pass variables that will conflict with this code. there's no good reason to catch and handle a connection exception in your code and re-throwing the exception you just caught with only the message and code looses the file and line information, hindering debugging. the only database exceptions you should catch and handle in your code are for user recoverable errors, such as when inserting/updating duplicate user submitted data. for all other query errors, all other type of queries, and for the connection, you should do noting in your code and let php catch and handle the database exceptions, where php will use its error related settings to control what happens with the raw database error information, via an uncaught exception error (database errors will 'automatically' get displayed/logged the same as php errors.) don't use the global keyword to make your code 'work'. doing this breaks function scope, is not general purpose, and makes it harder if you ever need to use more than one database connection in a script. you should supply inputs to a function as call-time arguments. query builders, like this, usually have a 'raw' query function/method to handle cases beyond what the code itself can handle. i hope you are NOT planning on directly using the submitted form data to supply the column definitions to these functions, as this is not secure. your code must be where the defining array is defined at, so that YOU have control over what happens with the data and what columns and data gets used when dynamically building the queries. having the definition in your code also allows you to define labels, for use in building error messages and dynamically producing form fields and validation rules, for dynamically validating data on the server before using it. because you are dynamically building these queries, you should surround the table and column names with back-ticks so that you don't need to worry about what the actual identifiers are at the point of building the query. because you are using exceptions for errors, the conditional logic you have for the ->execute() call in the insertData() function will never see a false value and should be removed. one of the main points of exceptions is that your main code only 'sees' error free execution, since execution goes elsewhere upon an error. if execution continues past a statement that can throw an exception, you know there was no error without needing to test using conditional logic. as already mentioned, you need the ability to test for a duplicate index error (number) from a query in the exception catch logic to handle the case of inserting/updating duplicate user submitted data. for both an insert and an update query, they produce a PDOStatment rowCount() and a PDO lastInsertId() values (yes you can get a lastInsertId() value from an update query, which can be used to get an arbitrary value from the query, such as the id of the row that was updated or the initial or final value that was updated.) you should return an array with both of these values in it. you need to consistently validate the $table and $data/$conditions inputs before using them. the deleteData function() should return the rowCount() value, not the boolean value from the ->execute() call, which again due to using exceptions will always be a true value. when you get to the point of writing the update function() you need to distinguish between the columns/values used in the SET ... part of the query and the columns/values used in the WHERE ... part of the query. WHERE ... terms often involve more than just = (equal) comparisons and only ANDing multiple terms. there are LIKE, IN(), BETWEEN, greater/less, ... comparisons and combinations using AND/OR between terms. insert, update, delete, and select queries can get prepared once, then executed multiple times with different input values. to handle this you can define the variable holding the PDOStatement object as a static variable inside the function, then only prepare the query if the PDOStatement object doesn't already exist. you need a way of destroying the PDOStatement object when you are done using it. you have set the default fetch mode to assoc when you made the database connection, why are you also putting it in the fetch call?
  17. is phpmyadmin working? your initial symptom is that the raw php code is being output to the browser. did this change to the file being downloaded? about the only thing that comes to mind (ignoring that you apparently directly created a file on the server and it didn't work) is that when you uploaded (ftp) the files to the web hosting they got changed, possibly due to using a binary transfer mode instead of text transfer mode.
  18. The point of programming help forums is for you to post your code and the error or symptom you are getting and someone with the ability (and often without) will attempt to help you with the problem.
  19. you should use var_dump() on the values for debugging, since it indicates the length of the value. unfortunately, you didn't show us what you saw when you echoed the variables and if you made a change to the sql query statement and it didn't work, showing us what you changed would help someone solve the problem. converting a query that has variables being put directly into it into a prepared query is straight forward - remove, and keep for later, any php variables that are inside the sql query statement. note: any wild-card characters in a LIKE comparison are supplied as part of the data value not as part of the sql query statement. remove any quotes or {} that were around the php variable and any concatenation dots/extra quotes that were used to get the php variable into the sql query statement. put a simple ? prepared query place-holder into the sql query statement for each value. call the PDO prepare() method for the sql query statement. this returns a PDOStatement object. call the PDOStatement execute([...]) method with an array of the variables you removed in step #1. for a query that returns a result set, fetch the data from the query. see the PDOStatement fetch() method when fetching a single row of data. the PDOStatement fetchAll() method when fetching all the rows of data at once. and occasionally the PDOStatement fetchColum() method when fetching a single column from a single row of data. forget about any num rows function/method/property. just fetch then test if/how many rows of data there are. for a query that doesn't return a result set, you can use the PDO lastInsertId() method and the PDOStatement rowCount() method to get the last insert id and the number of affected rows. for the query in this thread, this would look like - // i recommend that you build the sql query statement in a php variable. this makes debugging easier since you can echo the sql $sql = "Select * FROM weekends WHERE Weekend_Number = ? AND Men_Women = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([ $_SESSION['Weekend_Number'], $_SESSION['Men_Women'] ]); // if this query can match a set of data $result = $stmt->fetchAll(); // if this query can match at most one row of data $result = $stmt->fetch(); typical PDO connection code - $DB_HOST = ''; // database host name or ip address $DB_USER = ''; // database username $DB_PASS = ''; // database password $DB_NAME = ''; // database name $DB_ENCODING = 'utf8mb4'; // db character encoding. set to match your database table's character set. note: utf8 is an alias of utf8mb3/utf8mb4 $options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // set the error mode to exceptions - this is the default setting now in php8+ 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);
  20. i second the use of prepared statements. you MUST protect against sql special characters in a value being able to break the sql query syntax, which is how sql injection is accomplished. a prepared query is the simplest (provided you use the much simpler and better designed PDO extension), fool proof way of accomplishing this for all data types. also, if the 'th' (ordinal indicator) is actually part of the value, it should not be. this is a human convention and should only be displayed, not actually submitted or stored. you should only submit or store the integer value. the code copying session variables to other variables is both unnecessary (just use the original variable that data is in) and indicates that your form and form processing code is on different pages. by separating these, you are nearly doubling the amount of code and since it takes more code to accomplish a task, you are likely leaving out things that provide security or a good User eXperience (UX.) the code for any 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
  21. have you done or checked the 3 possible things that were already posted above? are you actually including SecureFunctions.php? also, do you have multiple sets of these files in different paths and there is more than one SecureFunctions.php and the wrong one got updated?
  22. if this is the only session variable you are getting an error for (i didn't get an error for this variable, but did for some other ones when i ran your code), here are some possibilities - your actual code has some non-printing characters in or smart/curly-quotes around the index name (that posting code on this forum filtered out). i would delete and retype the entire index name, including the initial and final double-quotes, in each reference to this array index name. is any of the other code that gets executed in the functions being called, referencing or setting that variable and could be unsetting it? are you sure that the latest code got saved/uploaded so that you are actually initializing that variable? most of these session variables exist solely to pass data from the form processing code back to the form. you should instead put the form processing code and the form on the same page. this will greatly simplify all the code. the code for any 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 at the completion of the post method form processing code, you should preform a redirect to the exact same URL of the current page to cause a get request for that page. this will prevent the browser from trying to resubmit the form data should that page get browsed back to or reloaded. you should not copy variables to other variables for nothing. just use the original variables that data is in. in the current code, a significant number of lines are there only to copy variables back and forth, yet you have instances of using the original variable that data is in. you should apply htmlentities() to any dynamic value being output in a html context, right before/as it is being output, to prevent any html entity in value from breaking the html syntax.
  23. what this would look like using the method i posted above - <input type="text" maxlength="32" size="42" name= "<?=$Comment_Name?>" value="<?=$_SESSION["DE_Retain"] == 1 ? $_SESSION["DE_Comment"] : ''?>">&nbsp;&nbsp;Max 32 Characters<br><br> likewise for the checkbox logic - Retain comment:&nbsp;<input type="checkbox" maxlength="1" size="1" name="Retain" <?=$_SESSION["DE_Retain"] == 1 ? 'checked' : ''?>> i'm pretty sure that checkboxes don't have maxlength or size attributes. if any of these variable may not exist, to prevent php errors, you need to use the null coalescing operator ?? to set default values. if you want to clear all the session data, you can use session_destroy();. if you only want to clear this 'form' data you are passing around, while keeping the current user logged in, you should store this data in a session array variable, such as $_SESSION['post']. you can then clear this data by just unsetting it - unset($_SESSION['post']);
  24. my reply was a possible reason why php would work on your localhost system but not on actual web hosting. you have already checked, by trying, that the files are not being treated as php on the web hosting. you should not have needed to create a .htaccess file or put an addhandler ... line in it. this may in fact be why php isn't working. did you do this as an attempt to get the php to work after you discovered that it didn't or did you do this prior to trying to run any php code? has any php code ever worked on your web hosting? i would use your cpanel file editor to create a new .php file, and put the following in it, then request the URL of the this file in a browser to see if php works - <?php phpinfo();
  25. do these files have a .php extension, i.e. you didn't configure your localhost system to treat .htm/.html extensions as being php code?
×
×
  • 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.