Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,507
  • Joined

  • Days Won

    185

Everything posted by mac_gyver

  1. the OP's screen prints show something interesting. libmysql is specifically listed, though it is not clear if this is just how the database client is being listed or if both of those are present. on the offending hosting, what does the mysqli section in the output from a phpinfo() statement in a .php script file show? how much overall database specific code do you have? converting to the much simpler and more modern PDO extension would eliminate this problem completely.
  2. your resulting html markup is broken, due to something like the out of date border = attribute value. you need to use modern markup and you need to validate the resulting web pages at validator.w3.org
  3. if you post all the code, less the database connection credentials, someone can provide suggestions on what to start checking. if there's nothing obvious that the code is doing, then you would need to start by profiling/timing the execution of the query(ies) when executed via the php script, to see how long they are taking. however, just based on the symptom, it is likely the php code is doing something extremely inefficient, such as running queries inside of loops, operating on sets of data discreetly, rather than to use php array functions to operate on the set all at once, ...
  4. 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); php only sends two things to the database server when using prepared queries, 1) the sql query statement, with (optional) positional ? place-holders in it, and 2) an execute command, with an (optional) list of values corresponding to the place-holders. when using true prepared queries, supplying an array to the ->execute([...]) call, preserves the data type of the values, so, this works correctly for strings, numbers, boolean, null, and blob data (when it is less then the max packet size setting.) typical prepared query - $sql = "some sql statement with positional ?, ... place-holders in it where values are to be evaluated when the query is executed"; $stmt = $pdo->prepare($sql); $stmt->execute([ a_value_for_each_place-holder, ... ]); // for queries which return result sets, fetch the data here // see the fetch(), fetchAll(), and fetchColumn() methods // php also has some useful fetch modes, which can do things like pivot/index data by the first column selected, return a single-column one-dimensional array when using fetchAll(), ... you are likely to see example code posted on the web that is using exception try/catch logic around all the database statements that interact with the database server - connection, query, exec, prepare, and execute. ignore this. it is unnecessary clutter that does nothing useful. the only time your code should catch and handle a database exception is for user recoverable errors, such as when inserting/updating duplicate or out of range data. in these cases, you would have try/catch logic (specifically dealing with the ->execute() call), test if the error number is for something that your code is designed to handle, and setup an error message for the user letting them know what was wrong with the data that they submitted. for all other error numbers, just re-throw the exception and let php handle it. in all other cases, simply do nothing, and let php catch and handle the database exceptions, where php will use its error related settings to control what happens with the actual error information, via an uncaught exception error (database statement errors will 'automatically' get displayed/logged the same as php errors.)
  5. forget about using the overly complicated and inconsistent mysqli extension. some additional problems - the procedural and OOP notation have different error responses for the same problem. things that should be and are fatal errors with OOP notation, are just warnings using procedural notation, and the procedural code continues to run, resulting in follow-on errors, not directly related to the problem. some of the features that were added to the mysqli extension, to try to make it more usable, are dependent on the mysqlnd driver being used (and they just corrected one of these but not the others.) if you don't manage your php build, you cannot guarantee that the mysqlnd driver will be used, resulting in code that is not portable between php installations. whoever defined the mysqli result fetch_all default fetch mode didn't know what they were doing. the fetch mode refers to the rows of data in the 'all' array, not the all array indexes. the default fetch mode for every other fetch statement is BOTH. the default fetch mode for the fetch_all statement is numeric, meaning you won't get associative indexes for the rows of data unless you explicitly set the fetch mode in the fetch statement. when you use the PDO extension - set the character set to match your database table's character set, so that no character conversion takes place over the connection. (you should do this for all database extensions, but it is rarely done.) set the error mode to exceptions, so that all the statements that interact with the database server use exceptions (this is now the default setting in php8+ for both the PDO and mysqli extensions.) set emulated prepared queries to false. you want to use real prepared queries whenever possible. set the default fetch mode to assoc, so that you don't need to specify it in each fetch statement. when using prepared queries, use implicit binding, by simply supplying an array to the ->execute([...]) call.
  6. also, since filter_input() hides undefined index errors, i.e. typo mistakes between form field names and the php code, it should be avoided. if you are just starting out, get your code to work completely for one form field of one type, e.g. a text field, then add and test the code needed for other types of fields, one at a time. once you have determined how to handle each different type of field, you can worry about the code needed for all the rest of the fields. by writing out code for 13+ fields, before you have working code for even one field, you will waste a huge amount of time making corrections to all that code. you should handle first and last names separately, so that you can distinguish between the two, e.g. is someone Ross Martin, or Martin Ross? other than trimming data, mainly so that you can determine if it is all white-space characters, you should NOT alter input data. just validate the trimmed data. if the data is valid, use it. if the data is not valid, setup an error message for the user letting them know what is wrong with each piece of data, let them correct the problem, and resubmit the data. you should NOT write out line after line of code creating discrete variables for each field. this is just a waste of typing. instead, keep the form data as a set, in a php array variable, then operate on elements in this array variable throughout the rest of the code. once you do this, you can trim all the data at once, using one single line of code.
  7. in real life, data is almost never actually deleted. it is just UPDATEd to mark it as deleted, then it is excluded from most database operations, using a table view. you may want to restore it at some point or by keeping a history, you can detect nefarious activity by users. you would use a post method form when deleting data, not a link. the way to accomplish the operation you are asking about is straightforward. you would enforce ownership or administrator-ship, by only outputting the delete form, with a hidden field containing the id of the data, and enabling the delete form processing code, if the current logged in user's id matches the owner id of the data or the currently logged in user is an administrator (assuming the system has user roles.)
  8. you would use an array name for the checkbox field, with the record id used for either the array index or the checkbox value. only checked checkboxes will be set in the submitted form data, so you can detect if any are set (the field name will be set), and get all the checked record ids. you would then use the submitted status value to update the records with those ids. you can use a single FIND_IN_SET() statement in the WHERE clause to do this using one single database query.
  9. the only redirect you should have on your site is upon successful completion of post method form processing code, and it should be 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 if that page is reloaded or navigated away from and back to. either integrate the login operation on any page that needs it or provide navigation links on the login page to let visitors navigate to other pages.
  10. when you used either scandir() or opendir()/readdir()/closedir(), did you you display everything or did your code attempt to conditionally display only files that started with '1'? could the file names start with a non-printing/white-space character so that they don't actually begin with a '1' character, either when they were created or through some copy or rename operation?
  11. the correct place to assign a value to the session variable is in the post method form processing code, at the point where you have confirmed that the username and password have been matched (it is currently not at this point in the code and needs to be corrected.) it should not be assigned a value in any other place. therefore, remove the assignment statement you currently/still have in sayfam.php. the debugging line of code, with print_r($_SESSION, true), should still be in sayfam.php, until you get this to work, since is shows if the session variable is set and what value it contains.
  12. the date format string to get the first day of the current month is - 'Y-m-01' you would not write out conditional logic (switch/case, if) for every possible value. if you did have a need to match a set of input values to output values, you would use an array, where the array index is the input value and the stored array value is the output value. you would display the redeem button based on a non-redeemed status value in the row of data. then update that status value to a redeemed value when the offer is redeemed.
  13. on each page request, you would query to find the date (holding the first day of the month) of the last row holding this free-play data for the currently logged in user. if it is older than the start of the current month, you would insert enough rows to get up to the current month. you should store related data using the user id (autoincrement primary index in the user table), not the username, so that the username can be edited without needing to go through and update all the related data.
  14. can you describe, in your native language, what $_SESSION['nik'] = $_POST['nik']; does and why it is in sayfam.php? in English, this line of code is assigning a post method from variable $_POST['nik'] to the session variable $_SESSION['nik'] and it doesn't belong in sayfam.php at all. that post variable only exists on the page that the form submits to, denetim.php. it doesn't exist when sayfam.php is requested, producing the undefined index error you are getting and clearing that session variable. what does the print_r() output show after you have removed that line of code from sayfam.php? note: as i already posted, you must completely close all instances of your browser and start over to cause the session variable to be set to the expected value. post the current code for sayfam.php? are you using google's online/browser translator to translate our replies into your native language? my first reply in this thread contains a lot of helpful information that would allow you to create an application that - is secure, provides a good User eXpeinace (UX), is simple and doesn't contain a lot of unnecessary typing, and through having error handling and validation logic, will either work or it will tell you why it doesn't work.
  15. the print_r() output is showing that the "nik" session variable is set, but it is empty. the warning on line 5 in sayfam.php is therefore coming from a reference to an undefined array key "nik" in some other variable. probably $_POST["nik"]. the OP's first post in this thread contained the code for sayfam.php. on line 4 in that code is an incorrect line of code setting - $_SESSION['nik'] = $_POST['nik']; the later post in this thread, with the three files of the code, where the last one is for sayfam.php, does not contain the line setting - $_SESSION['nik'] = $_POST['nik']; yet, there is now an error indicating that line of code is probably in (never removed from) sayfam.php, so, two problems. 1) the OP is not posting the actual code that is being executed, and 2) that line of code needs to be removed from sayfam.php, since it is setting the session variable to a null/empty value.
  16. the reason @dodgeitorelse3 asked you to identify, by filename, the three files, is because it is not clear to us (we only see the information you provide in your posts) if the form submits to the same page it is on (why is the line $_SESSION['nik'] = $_POST['nik']; on the form page) or if it submits to a different page. if you had shown us that the 2nd file is denetim.php, we could have the ignored that line of code setting the session variable on the form page. you changed the code on sayfam.php, which originally had that same line - $_SESSION['nik'] = $_POST['nik'];, which would have set the session variable to a null/empty value, because the post data only exists on the page the form submitted to. did you completely close your browser and start over after making that change to the code? next, here's a list of things you should/should not be doing - the login form processing code and the form should be on the same page. by putting them on separate pages, you are creating more work for yourself, in maintaining two pages. this also provides a bad user experience, since the use must now navigate back to the form page upon an error and depending on how you were going to display error messages on the form page, it makes your site open to a phishing attack. the code for any page should be laid out in this general order - 1) initialization, 2) post method form processing, 3) get method business logic - get/produce data needed to display the page, 4) html document the piece of code that @Barand posted, checking the server request method, is the conditional logic that goes around the post method form processing. it insures that the form has been submitted before referencing any of the form data. don't copy variables to other variables for nothing. this is just a waste of your time typing. in the post method form processing code, 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. you should trim all input data, mainly so that you can detect if all white-space characters were entered. you should validate all inputs before using them, storing user/validation errors in an array, using the field name as the main array index. after the end of the validation logic, if there are no user/validation errors, use the submitted form data. you should not store the plain-text password. use php's password_hash(), in the registration code, and password_verify() in the login code. don't put external/dynamic values directly into an sql query statement. use a prepared query instead. testing if $sonuc is a true value doesn't tell you if the query matched a row of data. it only tells you that the query executed without any error, and in fact in php8+, both the mysqli and PDO extensions use exceptions for errors and any conditional logic you have testing the returned value from a query is unnecessary and should be removed. if execution continues to the line following the execution of a query, you know that the query didn't produce an error. you must fetch and test the result of the fetch statement to know if a query matched any data. fetching the data is also necessary to use password_verify() and the value you store in the session variable upon successful login should be the user's id (autoincrement primary index), not the username. you should query on each page request to get any other user data, such as the username, user permissions, ... this insures that any change made to this use data will take effect on the very next page request after it was changed. the only redirect you should have upon successful login is to the exact same url of the form processing code. this will cause a get request for that page so that the browser won't attempt to resubmit the form data if that page is reloaded or navigated away from an back to. if you want to allow the user to go to a different page, provide navigation links. every redirect needs an exit/die statement after it to stop php code execution. a header() statement doesn't stop the php code from running. the session variable is an input to the code on a page. you must validate it before using it. if it is a 'required' input and it doesn't exist, that's an error. you would setup and display an error message instead of trying to use the session variable in the code. if it is not required, you would instead display a default value or skip displaying it at all.
  17. we can only help with specific programming questions. what exactly are you currently having a problem with? have you successfully used the month and dealerid inputs (which should be from a get method form) to query for the data that you want?
  18. this implementation has two problems. 1) by getting the existing value (wherever and whenever $rgy['mainbalance'] is being gotten and/or passed to/through the code), modifying it (wherever $newamount is coming from), then executing an update query, if there are concurrent operations on this data, they will all get the same starting value, modify it, then the last update query to be executed will replace any previously updated value. so, if for example there were two (or more) concurrent operations to subtract values, such as 1000 and 100, and the last update query to be executed is for the 100 value, then it would look like the 1000 value was never subtracted, leaving the wallet with a larger value in it then expected. if you continue to just update the value in a column (see the next point), you would modify the value completely within the update query, e.g. SET main = main - ? 2) by updating a value in a column, there is no audit-trail that would let you detect if a programming mistake, duplicate submission (hopefully you are using a run-once token for form submissions), or nefarious activity modified the value or let you produce statements/reports of who, what, when, where, and why the amount got changed. the correct way of doing this is to insert a new row of data into an accounting table for every transaction that affects the value. you would then simply SUM() the +/- amounts in a query whenever you need the current total, the same way that all your banking, credit card, loans, utility accounts, medical billing, ... do it. also, since the op didn't post all the code necessary to reproduce the problem (he was asked elsewhere for this), the values themselves could be determined from an external submission, rather than only being determined on the server.
  19. ids in the html markup must be unique. you cannot use id='anything' more than once and any javascript code using a static getElementById('anything') cannot be used. rather than showing non-working attempted code, show a couple of examples of server-side data and describe what operations you are trying to accomplish in the browser for that data.
  20. indexing/pivoting the data is a completely separate step. you need to build and execute the query (which isn't even attempting to use the dealer id, year, and month) to match the data that you want. index/pivot the data. then - edit: i recommend that you get up to the point of using print_r() on the indexed/pivoted data so that you can see what it is. this may give you an idea of what the code that produces the output will need to do.
  21. the key to converting row data into column output is to index/pivot the data using appropriate array index values when you fetch the data from the query. you would then loop over the indexed data, and for each row of data, loop over the expected column indexes, and test if there is data for the current column. if there's not, you would output an appropriate indicator value or an empty html table cell. if there is data, you would output the existing target value in the 'target' column and output the form field for the entry of the actual value in the 'actual' column. to index/pivot the data when you fetch it from the query, you would do something like this - $data = []; foreach($stmt as $row) { $data[$row['Description']][$row['Category_Name']] = $row; } you can examine what the result of doing this looks like using print_r($data). the form field names would NOT include the category_name as part of them. you would use an array field name, such as 'Actual', with the description value and the category_name value as the array indexes, e.g. - name="Actual[Rock Breaker][Excavator]" and as was pointed out in one of your previous threads - the point of DRY (Don't Repeat Yourself) code is to NOT write out , copy/paste/overtype, the same logic/markup for every possible value. you should be dynamically outputting things like the html table headings and the target/actual html table cells. to do this for the code in this thread, you would write out or query for an array of the category_name values for the columns. while you are doing that, you should also define the static parts of the target/actual heading text in variables, e.g. - $col = ['Excavator','Grader','Wheel Loader','SLM','Revenue']; $target_txt = 'Target in lakh'; $actual_txt = 'Actual in lakh'; once you do that, you can dynamically produce the html table headings - <?php foreach($col as $c) { echo "<th style='width:6%;'>$c $target_txt</th>"; echo "<th style='width:6%;'>$c $actual_txt</th>"; } ?> you would loop over the $col values again at the point of dynamically producing the target/actual html table cells.
  22. the error is (most likely) because you haven't validated ALL the inputs to your code before using them and because your schedule data is not properly stored. you should build any sql query statement in a php variable, so that you can echo it to see what it actually is. $_SESSION['shown_id'] is an input to your code. you must validate it before using it. if it isn't set, it means that there is no a current/selected teacher and all the code that's dependent on that value should not be executed. you would instead setup and display an error message letting the user know what's wrong and how to correct it. e.g. there's no current/selected teacher. either login or select a teacher. what does adding var_dump($_SESSION['shown_id']); show? if it's not set or it is not an expected value, you will need to find out why. you should have ONE table holding the schedule data for all the teachers, with a separate row for each teacher (faculty_number) , day, and period. there would only be rows for data that exists. as to the posted code - the code for any page should be laid out in this general order - 1) initialization, 2) post method form processing, 3) get method business logic - get/produce data needed to display the page, 4) html document. the post method form processing should - 1) detect if a post method form was submitted, 2) keep the form data as a set, in an array variable, then operated on elements in this array variable throughout the rest of the code, 3) trim all the data at once, 4) validate all the form data, storing user/validation errors in an array using the field name as the main array index, 5) after the end of the validation logic, if there are no errors, use the form data, 6) after using the form data (which can produce more errors), if there are no errors, perform a redirect to the exact same url of the current page to cause a get request for that page. use 'require' for things your code must have for it to work. include/require are not functions. the () around the filename are unnecessary clutter and should be removed. don't copy variables to other variables for nothing. just use the original variables that data is in. for data fetched from a query, fetch it into a uniquely named array variable, then use elements in this array variable throughout the rest of the code. some major comments in your code, describing what each section is doing, would be helpful. e.g. get the name for the current/selected teacher, get the schedule for the current/selected teacher on the selected day and period, ... you would query the single schedule table, using a SELECT COUNT(*) ... query, to find if the selected substitute teacher (faculty_number) is available on the selected day and period. if this query doesn't match any data (the COUNT(*) term is zero), it means that the selected substitute teacher is not available. you would then query the single schedule table to get the row of data for the current/selected teacher (faculty_number) on the selected day and period, to build the sms message. you should use a prepared query any time you are supplying any dynamic value to the query when it gets executed. if using a prepared query with the mysqli extension seems overly complicated, this would be a good time to switch to the much simpler and more modern PDO extension. type='text/javascript' is no longer used in the <script> tag.
  23. don't bother with the mysqli extension. it is overly complicated, inconsistent, and in the case of procedural vs OOP statements, has different error responses for the same root problem. instead, use the much simpler, consistent, and more modern PDO extension. in php8+, both the mysqli and PDO extensions use exceptions for errors by default. the line of code that @Barand posted enables exceptions for errors for the msyqli extension. when you use exceptions for database statement errors, php will 'automatically' display or log the raw database errors, via an uncaught exception error. therefore, you can remove any existing error handling logic, since it won't ever get executed upon an error, simplifying the code. you should also name the connection variable as to the type of connection it contains, $mysqli/$pdo. this will let anyone looking at the code know what extension it is using, and also let you search for which code has been converted and which hasn't. you also need to use a prepared query when supplying external, unknown, dynamic values to a query when it gets executed, so that any sql special characters in a value cannot break the sql query syntax, which is how sql injection is accomplished. if you switch to the much simpler PDO extension, after you prepared the query, you can simply supply an array of the input values to the ->execute([...]) call.
  24. the database server must find the row(s) being update. it then reads the data in those row(s), for two main reasons - if a column value doesn't change, it doesn't write the data back to the disk, skipping an operation. the database server performs this comparison for you, using the current 'locked' values from the row, in one ATOMIC operation, so that you are not potentially comparing new values with 'stale' data that could have been changed by some other concurrent operation on the data. so that you can perform things like SET count = count + 1 ... in a single query
  25. ps, everyone on the same network will have the same ip address. if you are going to use a database based cart, you need to generate a unique value per visitor to use to identify each cart. the simplest way of doing this is to start a session, then use the session id as the identifier. pps, your cart should have a quantity column, so that someone could have more than one of each item.
×
×
  • 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.