Jump to content

mac_gyver

Staff Alumni
  • Posts

    5566
  • Joined

  • Days Won

    200

Everything posted by mac_gyver

  1. $_SERVER['DOCUMENT_ROOT'] is a file system path. it is used when you reference a file through the file system on the server, such as when you require a file through php code or use a statement like file_get_contents(). these are not the same as URLs that a browser uses when it makes a request to a web server. you would need to post examples showing what you are trying to do to get more specific help.
  2. you should only have one user/authentication database table. a staff member is a user with specific permissions/privileges (and you should query on each page request to get the user's current permissions.) what you currently have either duplicates user id's and/or has a extra code/queries in it. some other points, most of which simplifies what you are doing - because logoutUser() is a function, you WOULD use the $user_id input parameter in the code, like it was written. you apparently have two different functions, since the last code is using $userId as the input parameter. you should be using php8+, where the default setting is to use exceptions for database errors. when using exceptions, if the code continues past any statement that can throw an exception (connection, query, exec, prepare, and execute), you know that no error occurred and you don't need conditional logic to confirm so. you should never unconditionally output raw database errors onto a live web page, where it gives hackers useful feedback. when using exceptions, simply do nothing in your code for most errors and let php catch and handle the exception, where php will use its error related settings to control what happens with the actual error information (uncaught database exceptions will 'automatically' get displayed/logged by php.) a session can hold things other than the user's id. the logout code should only unset that specific session variable. the redirect you preform upon successful completion of post method form processing code MUST 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 should that page get browsed back to or reloaded. for a logout this doesn't matter, but for something like registration/login, if you browse back to the form's action page, you can use the browser's developer tools to look at the data that the browser resubmits and see what the username/password is. there's no need to close database connections in your code since php destroys all resources when you script ends. in fact the close statement you have shown is never reached since your current logic exits in all cases before ever reaching it. you cannot set display_startup_errors in your code because php has already started by the time your code runs.
  3. mac_gyver

    num_rows

    you are trying to pattern match to convert one language/syntax to another. do you accept that from your students, or do you actually expect them to learn the meaning of the words and syntax you are trying to teach them? writing code is no different than a writing assignment in a foreign language. the pdo rowCount() method is not guaranteed to work with a SELECT query. as has already been written in your replies, simply fetch the data from a query into an appropriately named php variable, then test if there is any data in the variable. if there isn't, display an appropriate message. if there is, loop over the data to produce the output. here's a pattern for you to use - // the database specific code, that knows how to query for and fetch the data // a prepared query, with a place-holder where the dynamic value will be used $sql = "SELECT * FROM ember_students WHERE teacher = ?"; // prepare the query $stmt = $pdo->prepare($sql); // execute the query with an array of the dynamic value(s) you removed from the sql query statement $stmt->execute([$uname]); // fetch all the data from the query $result= $stmt->fetchAll(); // the presentation code, that knows how to produce the output from the data if(!$result) { echo "<p>There is no data to display.</p>"; } else { foreach($result AS $row) { // you can put php variables into a double-quoted php string. no need for error-prone extra quotes and concatenation dots print "{$row['lname']}, {$row['fname']}<br>"; } }
  4. the current markup will only submit the last checkbox value that is checked. to submit a set of values, the form field name needs to be an array, e.g. name='team[]' you also need to apply htmlentities() to dynamic values being output in a html context so that any html entity in a value, such as a ', cannot break the markup.
  5. this is a symptom of the browser not recognizing quotes around a value attribute in the markup. you would need to post your code and a sample of your data that reproducers the problem for anyone here to be able to help. also, what does the 'view source' in the browser show for the markup? btw - instead of escaping double-quotes inside a php string, you can simply use single-quotes.
  6. it's a matter of functionality/purpose, not preference. a non-prepared query is used when there are no dynamic values being supplied to the query. a prepared query is used when you are supplying dynamic values to the query, in order to separate the parsing of the sql query syntax, from the evaluation of the values during the execution of the query. this is so that values like didn't or O'tool, which contain an sql special character, cannot break the sql query syntax, which is how sql injection is accomplished. in one of your previous threads i gave detailed instructions on converting an sql query with php variables being put directly into it, into a prepared query.
  7. PDO examples - a non-prepared query. assuming the literal 4 (which is not a string, it's a number) is hard-coded in the query - $query = "SELECT * FROM ember_features WHERE id = 4"; $stmt = $pdo->query($query); $row = $stmt->fetch(); a prepared query. assuming the value being shown in this query is a dynamic value - $query = "SELECT * FROM ember_features WHERE id = ?"; // a simple ? place-holder where the dynamic value is used at in the query $stmt = $pdo->prepare($query); // prepare the query $stmt->execute([ 4 ]); // execute the query, suppling dynamic value(s) as an array to the execute() call $row = $stmt->fetch(); where did you find this connection code? here's everything that's wrong with it - it's not setting the character set to match your database tables, so character conversion can occur, breaking multiple-byte characters it's not using exceptions for errors, which is the default setting now, which simplifies all the error handling it's not using true prepared queries. by using emulated prepared queries (the default) and not setting the character set, your queries are open to sql special characters in a value being able to break the sql query syntax, which is how sql injection is accomplished it's not setting the default fetch mode to assoc, so you will need to specify the fetch mode in each fetch statement there's no point in catching and handling a connection error in your application since a user to your site can do nothing about it and doesn't need to know it is the reason a page isn't working. catching and outputting the raw error information also helps hackers when they intentionally trigger connection errors (by flooding your site with requests that consume all the database connections.) if you have ever looked at a connection error, it lists the database server host/ip address, the database username, if the connection is using a password, and web server path information. do you really want to give someone this much information about your site? you should only catch and handle user recoverable database errors in your application, such as when inserting/updating duplicate user submitted data. for all other query errors and all other type of queries, simply do nothing in your code and let php catch hand handle database errors.
  8. the problem is most likely going to be something preventing the session_start() from working, which php's error reporting and display/logging will tell you. so, setup php's error_reporting and display_errors/log_errors as suggested, and confirm that they actually got set to those values by using a phpinfo() statement in a .php script. doing this ^ opens your site up to a phishing attack, where someone can trick one of your users to enter their login credentials on the phishing site, then redirect them to your site and get your site to display a message to make it look like they just mistyped the values. don't redirect all over your site and don't put values on the end of the URL that determine what the user will see in the way of messages.
  9. you are likely getting a php error that would help identify the problem. is php's error_reporting set to E_ALL (it should always be this value) and either temporarily set display_errors to ON so that the reported errors will get displayed, or set/make sure that log_errors is set to ON and check the php error log. also, either check what a phpinfo() statement shows on both systems for the output_buffering setting, since it can both affect how your code works and can hide non-fatal php errors and debugging statements you put into your code. next, your description of the coding has you writing an maintaining a bunch of extra code and redirecting around on your site. the code for any form processing/form should be on the same page. the only redirect you should have in your code should be upon successful completion of the post method form processing and it should be to the exact same URL of the current page to cause a get request for that page.
  10. in the phpinfo output, there's a value near the top named - Loaded Configuration File. is this the same php.ini that you checked? next, search for the error_reporting and display_errors output. what are both the local and master values for these? here's 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); in your previous thread, i have instructions on converting a query, that has php variables being put directly into it, into a prepared query. also from that thread - if you want to post examples of your existing code, i/we can show what it would look like using current practices. a lot of the coding suggestions given in that thread actually eliminate code, so that you can just remove things, rather than spending time updating them.
  11. it's your php code that accesses the database, not the students that use your web site. your students login via the php authentication script that runs on your web site. if you set the php error related settings to the values that i posted, instead of getting a http 500 error page, you will get the actual php errors, assuming that php is setup and works on the server. have you created a .php page with a phpinfo(); statement to confirm that php works at all? because the mysql_ extension has been removed, along with magic_quotes, that provided some protection against sql special characters being able to break the sql query syntax for string values, which is how sql injection is accomplished, ALL of the code dealing with data values being put directly into the sql query statements MUST be updated. if you are not interested or capable of doing this level of changes, you are going to need to hire someone. the PDO extension provides the simplest way of accomplishing these changes.
  12. also, name the database connection variable as to the type of connection/extension you are using, e.g. $pdo, so that you can see or search through your code to find which database specific code has or has not been updated.
  13. did you read the replies in your previous thread? they went into great detail what changes you will need to make to the database specific code and to your code in general. you should be updating and testing your code on a localhost development system, xampp or similar. constantly uploading files to a remote server to see the result of each change is huge waste of time. to get php to help you, by reporting and display all the errors it detects, you need to set php's error_reporting to E_ALL (it should always be this value) and set display_errors to ON. these settings should be in the php.ini on your development system. when you put these settings into your code, they won't do anything for a fatal parse/syntax errors because your code never runs in this case to cause the settings to take effect. when you move your tested code to the live server, you would have display_errors set to OFF, and log_errors set to ON, so that all php detected errors will get logged.
  14. assuming you are using the PDO extension, it has a fetch mode that will index/pivot the data for you - // build and execute the query here... // index/pivot the fetched data using the first column in the SELECT list $data = $stmt->fetchAll(PDO::FETCH_GROUP); // at the point of producing the output if(!$data) { echo "<p>There is no data to display</p>"; } else { foreach($data as $index=>$items) { // output the section heading echo "<li class='current'><a href='#'>$index</a></li>\n"; // loop over the data in the section foreach($items as $row) { // output each row of data echo "<li>{$row['Sub']}</li>\n"; } // if needed, close the section here... } }
  15. you need to index/pivot the data when you fetch it, using the Lvl value as the main array index. you can then simply loop over the data using two nested foreach loops to produce the output, like was shown in your previous similar thread.
  16. you can use the MySql LAST_INSERT_ID(expr) function in an insert/update query to make the expr value present in that query accessible following the execution of the query. expr can be anything, such as a column (which would be the id column for what you are asking. i typically use it in an insert ... on duplicate key update ... query to tell if the update part was executed by getting the id of the row that was updated), the result of a calculation (such as incrementing and updating a page count column and accessing the resulting count), or the result of a comparison (i've got an example in my project archive where it is being used to return the true/false expr1 value from an IF(expr1,expr2,expr3) statement in a query) . you can then access the resulting value using the last insert id method/property for the php database extension you are using.
  17. perhaps you have seen my suggested page layout posted in the forum? 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 when editing existing data, you would test for a requested edit id $_GET input in the get method business logic, if the form has never been submitted, to query for and fetch the existing data to be edited. you would fetch the data into a common array variable that also holds a trimmed working copy of the form data that gets set inside the post method form processing. this common array variable being empty or not is how you determine if the form has never been submitted (requires at least one valid $_POST field in the form.) by using a little conditional logic in the form code to control a hidden field value indicating which post action (create/update) to preform, a hidden field with any requested edit id, and switch/case logic in the post method form processing to control which form processing code to execute, you can (re)use the same code for creating new entries or updating existing data. also, once you have more then 2-3 form fields you need to dynamically validate and process the data and dynamically produce the form fields by creating a defining array with the expected fields, along with their field/data type, select/checkbox/radio choices, validation rules, processing rules, and any other unique values that define each field. you would then loop over this defining data to validate, process, and produce the form fields, instead of writing out code for every field.
  18. converting an old query that has variables being put directly into it to to use prepared queries, with the much simpler and better designed PDO extension, is fairly straightforward - 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 with an insert/update/delete query to get the last insert id and the number of affected rows. you should be using exceptions for database statement errors (this is the default setting now in php8+). for an insert/update query that could result in duplicate data (the appropriate column(s) need to be defined as unique indexes in the database table), you will need to catch and handle database exceptions from the insert/update query, test if the error number is for a duplicate index error, and setup a message for the user letting them know what was wrong with the data that they submitted. for all other query errors, simply rethrow the exception, and for all other type of queries, simply do nothing in your code, and let php catch and handle any database exception, where php will use its error related settings to control what happens with the actual error information via an uncaught exception error (database errors will 'automatically' get displayed/logged the same as php errors.)
  19. your own connection.php code may be running w/o error. the tutorial script has its own connection code in config.inc.php. this is where the message you are getting is coming from. downloading and running code you find on the web, without reading it to learn what it is doing, doesn't teach you anything. as to the connection code you found and posted here. mysqli_error($con) requires a valid connection, when using mysqli procedural statements. therefore, this code won't report the actual reason for the connection failure and will produce its own error at the mysqli_error($con) statement. as to both the connection code you found and what is included in this out of date tutorial, modern php (8+) uses exceptions for errors and any discrete error handling logic will never get executed upon an error and should be removed, simplifying the code. i recommend that you update to use php8+ and find a recent tutorial.
  20. where is this data coming from and how do you know which values belong in which group?
  21. where is the form and form process code hosted at? is on on the web site you previously posted the URL for?
  22. that's why you need to make an attempt at doing this yourself, so that you will actually learn the meaning of the words and syntax you are using.
  23. @Abi2702, the only technically relevant parts are the two sql queries - $query = "SELECT invoice_id, service_provider, reg_name, acc_no, acc_name, invoice_no, invoice_date, invoice_amount, eft_no, pay_status FROM invoices"; and - $sql = "SELECT name FROM admins inner join invoices on admins.user_code = invoices.user_name"; wouldn't you add the admins name column to the list of columns you are SELECTing and JOIN the invoices query with the admins table ON the same join condition being used in the second query? i recommend that when you write JOIN queries that you use table alias names and that you prefix every column reference with the corresponding alias, even when it is not necessary to make the query work, in order to prevent mistakes and to make it clear to anyone reading the sql query what you are attempting to do. i also recommend that you rename the invoices user_name column to user_code, since it is not holding user_name values.
  24. i'm going to guess the answer involves a JOIN query or the number 42?
  25. what is your goal for doing this? to have a working form to email application or to learn programming? if it's to have a working, secure, application, you need to hire someone or use an existing service. if it is to learn how to do this, i recommend that you start with a blank page (don't copy/paste out-of-date things you find on the web), and get the code to fully work for a single form field, then worry about adding all the code necessary for the rest of the fields. some points for creating an application - put the form processing code and the form on the same page. 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 web page, 4) html document validate any web page you create at validator.w3.org the form processing code should detect if a post method form was submitted before referencing any of the form data. 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, i.e. don't create discrete variables for every form field. trim all the input data before validating it. once you do item #4 on this list, you can trim all the data using a single line of code. validate the now trimmed data, store user/validation errors in an array using the field name as the array index. don't roll your own email valuation. use php's filter_var() with the FILTER_VALIDATE_EMAIL flag. after the end of the validation logic, if there are no errors (the array holding the user/validation errors will be empty), use the submitted form data. any value you use in a html context (web page, email) needs to have htmlentities() applied to it, right before being used, to help prevent cross site scripting. these emails are not being sent from the email address that someone entered in the form. they are being sent from the mail server at your web hosting. the From: mail header must be an email address that corresponds to your web hosting. the Reply-to: mail header can be set to the entered email address. don't use the php @ error suppressor, ever. you must test the returned value from the mail() call and take an appropriate action depending on the value. if it is a false value, you need to setup a message for the user (add it to the array holding the user/validation errors) that the email was unsuccessful. for a true value, you would let the post method form processing code run to completion. at the end of the form processing code, if there are no errors, you need to perform a redirect to the exact same URL of the current page to cause a get request. this will prevent the browser from trying to resubmit the form data should the URL get browsed back to or reloaded. to display a one-time success message, either store a flag value or the message in a session variable, then test for, display the success message, and clear the session variable at the appropriate location in the html document. if there are user/validation errors at item #8 or #13 on this list, the code will continue on to redisplay the html document, where you would test for and display the user/validation errors, and redisplay the form, populating field values, select choices, checkbox/radio fields with any existing data, so that the user doesn't need to keep reentering/reselecting data over and over upon an error. as an advanced programming subject, if you have more than 2-3 fields, you need to dynamically - validate and process the form data, and dynamically build the form.
×
×
  • 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.