Jump to content

mac_gyver

Staff Alumni
  • Posts

    4,736
  • Joined

  • Days Won

    141

Everything posted by mac_gyver

  1. when you fetch and index/pivot the data, index it by both the year and the month - $data = []; foreach ($results as $result) { $data[$result->Year][$result->Month][] = $result; } to produce the output - foreach($data as $year=>$arr) { // start a new year section here... echo "<h3>$year</h3>"; foreach($arr as $month=>$rows) { // start a new month section here... $monthName = date('F', mktime(0, 0, 0, $month, 10)); echo "<h4>$monthName</h4>"; foreach($rows as $row) { // output the data under each month here... echo "<p>$row->Title</p>"; } } }
  2. you are missing a logical operator after one/between the isset() statements. most of this typing is unnecessary. when a form has been submitted all the form fields with be set except for unchecked radio and checkbox fields, which you would detect and validate separately. are any of these inputs radio or checkboxes? If not, then that code is a waste of typing.
  3. it means that there is no fetch() method. if you are going to use a while(){} loop, you would use the fetch_array() method. if you are going to use a foreach(){} loop, you can directly iterate over the rows in the result set.
  4. repeating things that you have seen is not learning. it is just you typing something at your location that someone else has told you to do. you must actually look at and learn what the words and syntax that you are using mean, i.e. internalize the information. there are a huge amount of examples for all the fundamental programming operations to be found on the internet. if you didn't do a web search for sql where with multiple conditions before starting this thread, why not? the second query has two conditions in the WHERE clause, with a logical AND operator between them (must include a AND b.) how did you arrive at that? what did you learn by doing that? to add the third column BETWEEN ... AND ... condition, you would just AND it with the rest of the WHERE conditions (must include a AND b AND c.)
  5. you could always make an attempt and observe the result to see if your query does what you want. SELECT the columns you want FROM your table WHERE all the where conditions here...
  6. the errors are being appended to the end of the downloaded file. in fact, there may be a php error appended to the end of a large file that would explain why it isn't working. for a file download application, you would want to log all php errors.
  7. when you require a .php file using a URL, on a correctly configured and functioning web server, you don't get the php code in the file, you only get any output produced by that php code. you must use a filesystem path in order to require .php files.
  8. if you do the things that have been suggested, you won't get undefined variable/index errors. if there might not be a related row in the candidate_paye table, you would use a LEFT JOIN in the single query. this will result in null values for the columns you select from that table. the column (index) will exist in the fetched data. when you echo a null value in the php code, there is no output, i.e. a blank value.
  9. additionally, for a query that's expected to match data for the page to work, its an application error if it doesn't and you should setup and display a message for the visitor telling them so, rather than to blindly try to use data that doesn't exist. don't use a loop to fetch data from a query that's expected to match at most one row of data. just fetch that single row of data and test if a row was fetched (like the 2nd query code is doing.) you need to validate all inputs before using them. the session variable is an input to this block of code. if it doesn't contain an expected value, that's an application error and you should setup and display a message for the visitor telling them so. don't put external, unknown, dynamic values directly into sql query statements. use a prepared query instead. lastly, don't copy variables to other variables for nothing. just use the original variables. after you execute the single (LEFT?) JOIN query, just fetch the data into an appropriately named php array variable, then use elements in this array variable throughout the rest of the code.
  10. template method - <?php require 'Mustache/src/Mustache/Autoloader.php'; Mustache_Autoloader::register(); $m = new Mustache_Engine; // define template $tpl = " <table{{#class}} class='{{class}}'{{/class}}> <thead> <tr> {{#headings}} <th>{{.}}</th> {{/headings}} </tr> </thead> <tbody> {{#rows}} <tr> {{#.}} <td>{{.}}</td> {{/.}} </tr> {{/rows}} </tbody> </table> "; // fake your existing data $class = "data clickable admin"; $data = []; $data[] = ['c1'=>'r0v1','c2'=>'r0v2','c3'=>'r0v3','c4'=>'r0v4','c5'=>'r0v5']; $data[] = ['c1'=>'r1v1','c2'=>'r1v2','c3'=>'r1v3','c4'=>'r1v4','c5'=>'r1v5']; $data[] = ['c1'=>'r2v1','c2'=>'r2v2','c3'=>'r2v3','c4'=>'r2v4','c5'=>'r2v5']; // array_map call-back function to get only array values function _array_values($arr) { return array_values($arr); } // populate template data $tpl_data = []; $tpl_data['class'] = $class; $tpl_data['headings'] = array_keys($data[0]); $tpl_data['rows'] = array_map('_array_values',$data); // echo the rendered template echo $m->render($tpl, $tpl_data); result - <table class='data clickable admin'> <thead> <tr> <th>c1</th> <th>c2</th> <th>c3</th> <th>c4</th> <th>c5</th> </tr> </thead> <tbody> <tr> <td>r0v1</td> <td>r0v2</td> <td>r0v3</td> <td>r0v4</td> <td>r0v5</td> </tr> <tr> <td>r1v1</td> <td>r1v2</td> <td>r1v3</td> <td>r1v4</td> <td>r1v5</td> </tr> <tr> <td>r2v1</td> <td>r2v2</td> <td>r2v3</td> <td>r2v4</td> <td>r2v5</td> </tr> </tbody> </table> note: htmlspecialchars is applied to all values by default, so any html special characters in a value won't break the html syntax, or allow html, css, or javascirpt to be operated on by the browser.
  11. that's a LOT of typing, especially for the static sections containing no dynamic values. you need to use templates, with tags in it for the dynamic sections, then either write your own templating code or use one of the existing templating engines. here's the tag documentation for one of the popular templating engines showing how to display values, implement if conditional statements, and loops - https://github.com/bobthecow/mustache.php/wiki/Mustache-Tags
  12. the operation is to simply either add one day or subtract one day from the current date - <html> <head> <title></title> </head> <body> <form method="post" name="f1"> <?php error_reporting(E_ALL); ini_set('display_errors', '1'); // Default dates $today = date('Y-m-d H:i:s',strtotime('today')); // Check the form was submitted if ($_SERVER['REQUEST_METHOD'] == 'POST') { $today = $_POST['today']; if($_POST['Submit'] == 'Tomorrow'){ $today = date('Y-m-d H:i:s', strtotime($today . '+1 days')); } if($_POST['Submit'] == 'Yesterday'){ $today = date('Y-m-d H:i:s', strtotime($today . '-1 days')); } } ?> <table border="1" align="center" width="100%"> <input type="hidden" name="today" value=<?php echo $today;?>> <tr> <td align="center" width="20%"><input type="Submit" name="Submit" value="Yesterday"></td> <td align="center" width="60%"> <?php echo $today;?></td> <td align="center" width="20%"><input type="Submit" name="Submit" value="Tomorrow"></td> </tr> <?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { //<!--- Form view ---> echo"<tr><td>query</td></tr>"; } else{ //<!--- Default view ---> "<tr><td>default</td></tr>"; } ?> </table> </form> </body> </html>
  13. the cause has already been posted - only use full opening tags <?php so that your php code will always be seen as being php code.
  14. did you look at the 'view source' of the page as suggested? there's nothing php version specific in this code.
  15. define: stopped working? what does happen and if you are getting a blank page, what does the 'view source' in your browser show? (the problem is probably the short-open tag no longer working.) next, don't do this without validating that $_GET['con'] is exactly and only a permitted value. by using directory traversal or remote code inclusion, i.e. including path information or a remote url in the value, anyone can cause your code to include any file on your server, and if enabled, any code in a remote file, because file_exists($id) will be true.
  16. no. the most likely thing is php's output_buffering setting being previously ON, but now it is off, preventing things like the session_start() from working, combined with bad code not doing things like halting php execution following header redirects. there would be php errors.
  17. the error is because the session variable doesn't contain a value. so, two things - code should ALWAYS validate inputs before using them. if a required input isn't valid, that's an error and the code should setup and display a message for the user telling them what is wrong and not attempt to use the input. you need to determine why the session variable doesn't contain an expected value. either it's not being set or it is being lost somewhere along the way. based on the name of that variable, this either has something to do with the user authentication/login system or a user permission system. do other things requiring user authentication/permissions work? there should be other php errors that will help pin point where the problem is starting at. is php's error_reporting set to E_ALL? beyond that, it would take having the code where that session variable is being set at through to the posted code in order to come up with specific things to look at.
  18. here's a laundry list of items, repeating some already posted above - for a login page, you care - 1) that the current visitor is not already logged in, 2) that the trimmed email and password are not empty strings, and 3) that the email/password matches the email/password_verify() result. you don't care if the email address is properly formatted (in the registration logic, you do care.) in fact, the current code testing $email, the result of the filter_var() statement, will incorrectly report that the email was empty, when it is not properly formatted. the session_start goes near the top of the code in the initialization section, both for consistency and so that you can check if the current visitor is not already logged in before allowing access to the login form and the form processing code. require_once is not a function. the () are unnecessary clutter. also, the _once version takes more processing since php must check the table of already required files. post method form processing code should first detect if a post method form was submitted, then trim, and validate all the input data. you should trim all the post data at once, keeping it in an array variable, then operate on elements of this array variable throughout the rest of the code. htmlspecialchars is an output function. it is used when you output dynamic values in a html context. except for unchecked check-boxes/radio-buttons, all other form field types will be set after the form has been submitted. do not use isset() on these type of fields. the trimmed value will either be an empty string or it will contain the submitted value to use. when you add the error messages to the $err array, use the field name as the array index. this will let you perform any dependent validation steps only if there is not an existing error for the field and will let you test/output the errors adjacent to the corresponding field if you so desire. use the simplest logic/syntax available. boolean tests exist so that you can directly test things in conditional statements. you would test if the $err array is empty before using the submitted data and run the rest of the post method form processing code. at the appropriate location in the html document, you would test if the $err is not empty and display its contents. only catch database statement errors in your code for things that are user recoverable, such as inserting/updating duplicate or out of range values. in all other cases, simply let php catch and handle any database statement errors. if you do catch database statement errors in your code, do not unconditionally echo the raw error information onto a web page. when you make the PDO database connection - 1) set the character set to match your database tables, 2) set the error mode to exceptions, 3) set emulated prepared queries to false, and 4) set the default fetch mode to assoc. if you use ? prepared query place-holders, it will reduce the amount of typing and typo mistakes. the semi-colon ; on the end of sql query statements is not needed/used when executing them through php. if someone successfully authenticates who they are, but their account is inactive, you would want to specifically tell them that, so, you want to query for their row of data regardless of the IS_INACTIVE value. after doing the above item #18, the email column should be a unique index, so there's no point in having a LIMIT clause in this query. as already posted, don't use fetchAll, then use more code/variables to get/test a single row. just use fetch. you can directly test the result of the fetch statement, requiring no additional code. when conditional failure logic is much shorter than the success logic, invert the conditional test and put the failure logic first. this will result in clearer code. the login failure message should be added to the $err array, then displayed at the appropriate location in the html document. the only user value that should be stored in a session variable is the user id. you would then query on each page request to get any other user data. this will allow the other values to be edited and they will take effect on the next page request. after the end of all the validation/authentication logic, if there are no errors, 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 if the user reloads that page or browses away from and back to the page. provide navigation link(s) to allow the user to go to any other page. example code showing these points - // initialization session_start(); // is the visitor already logged in if(isset($_SESSION['user_id'])) { // either redirect or output an error that you cannot access this page if already logged in die; // stop code execution } require "dbcfg.php"; //Create an empty ERRORS array $err = []; // array to hold a trimmed working copy of the form data. access elements in this array throughout the rest of the code $post = []; // post method form processing if($_SERVER['REQUEST_METHOD'] == 'POST') { // trim all the data at once (if any of the fields are arrays, use a recursive trim call-back function here, instead of php's trim function) $post = array_map('trim',$_POST); if($post['email'] === '') { $err['email'] = " - 'Email Address' cannot be empty."; } if($post['password'] === '') { $err['password'] = " - 'Password' cannot be empty."; } // if no errors, use the submitted data if(empty($err)) { $sql = "SELECT ID, PWORD, IS_INACTIVE FROM users WHERE EMAIL=?"; $stmt = $pdo->prepare($sql); $stmt->execute([ $post['email'] ]); if(!$row = $stmt->fetch()) { // email didn't match $err['login'] = "Invalid email and/or password"; } else { // verify hashed password if(!password_verify($post['password'], $row["PWORD"])) { // password didn't match $err['login'] = "Invalid email and/or password"; } else { // successful login // at this point, you would test and setup messages for things like IS_INACTIVE... // only store the user id in a session variable. query on each page request to get any other user data. $_SESSION['user_id'] = $row["ID"]; } } } // if no errors, success if(empty($err)) { // redirect to the exact same url of this page to cause a get request - PRG Post, Redirect, Get. die(header("Refresh:0")); // note: if you want to display a one-time success message, store it in a session variable, then test, display, and clear that variable in the html document } } // the html document starts here... ?> <?php //If the array is not empty, then return the errors back to the user if(!empty($err)) { echo implode("<br>", $err); } ?>
  19. also, your login form processing code should log information at each failure point so that you know what is occurring. if the username check is failing, log that occurrence. if the password hash is failing, log that occurrence. hopefully, you already have error handling for the database statements that is logging db errors and are you using prepared queries so that any sql special characters in the submitted values won't break the sql query syntax? posting your code would get the quickest, most comprehensive solution.
  20. does that mean they are receiving an invalid username/password error when they authenticate themselves or does it mean that they are not being seen as being logged in when navigating around on the site because the login session variable is not working?
  21. that date format is not directly sortable. where is this data coming from/stored at? you should store dates in a YYYY-MM-DD format, which will allow easy sorting by the date, then output the date in the format that you want when you display it. if this data is coming from a database, sort it in the sql query. if this data must be sorted in php, you would use php's usort() function, with a call-back function to sort on the date field. if that incoming date format cannot be corrected at the source, i would first convert the format, all at once, to be YYYY-MM-DD, then sort the data, then format the date back to that format when you display it.
  22. change the code to use arrays for the sets of data under each major category, rather than processing each list/site separately. write two new functions (keeping the old code as is.) the new add_all_subscribers_lists_array() function would build arrays of parameters inside the inner foreach() loop, then call a new add_subscriber_list_array() function once, after the end of the inner foreach() loop. the code in the new add_subscriber_list_array() function would loop over the arrays of input parameters, query for the data and build each .csv file, then call the wp_mail() function once, supplying an array of the attachments. of some concern is that the code is creating a new database connection for each list/site. are all these databases on the same database server, with the only difference being which database is selected? if so, the code only needs to select the database before each query, rather than create an entirely new connection for each list/site query. for the 7warriors .csv, the posted code only outputs three headings, but there are four columns of data. to fix this, you would define a specific $column_names array inside the 7warriors conditional logic.
  23. if the order of the posted code is actually what exists, your validation logic is after the point where you are inserting the data. how do you expect this to prevent the insert query from executing? you would need to validate the data first, then execute the insert query if there are no validation errors. the simple way to do this is add any validation errors to an array, using the field name as the array index, then after all the validation logic, test if the array holding the validation errors is empty. if the array is empty, you would build, prepare, and execute the insert query. to display the validation errors, when you re-display the form, you would test and display the non-empty content of the array. next, validating each different input is not dependent on the result of the previous validation step. you should validate all the inputs at once, so that the visitor can correct all the validation errors at one time. you should also not use isset() for inputs that will always be set when the form has been submitted. only un-checked checkbox and radio buttons won't be set. by using isset() for the always set form fields, you are hiding programming/typo mistakes and cluttering up your code with unnecessary typing. you should trim all inputs at once, then use the trimmed values throughout the rest of your code. if your current code was in the proper order, you are validating the trimmed values, but using the original untrimmed values in the query. the simple way of correcting this is to keep the input data as an array, use array_map() to make a trimmed copy into a different, working variable (you want to leave the original $_POST data as is), then operate on elements in this working array variable throughout the rest of the code. finally, the header() redirect in your post method form processing code 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 the user reloads that page or browses away from and back to that page. the header() redirect also needs an exit; statement after it to stop php code execution. if you want the user to be able to go to a different page, provide navigation link(s.)
  24. the most immediate problem is that the query didn't match any data (or possibly didn't execute at all, but there would have been another php error at the mysqli_fetch_array statement.) see the php.net documentation for mysqli_fetch_array's return value - https://www.php.net/manual/en/mysqli-result.fetch-array.php code should ALWAYS test if data was fetched from a query before trying to use the data, and setup a user message if there was no data. // at the point of using the data if(!$fetch) { echo 'no data was found.'; } else { // use the data here... } the most likely reason for no matching data is either because $_GET['id'] doesn't contain any value or the value it does contain doesn't match any data in the table. you should ALWAYS validate inputs to your code before using them. if $_GET['id'] isn't set, is empty, or doesn't contain an integer value > 0, that's an error. you should setup a user message in this case and not attempt to run the sql query. you should ALWAYS have error handling for statements that can fail. for database statements that can fail - connection, query, prepare, and execute, the easiest way of adding error handling, without adding logic at each statement, is to use exceptions for errors and in most cases let php catch and handle the exception, where php will use its error related settings to control what happens with the actual error information, via and uncaught exception error (database statement errors will 'automatically' get displayed/logged the same as php errors.) next, don't put external, unknown, dynamic values directly into an sql query statement. use a prepared query instead. lastly, don't copy variables to other variables for nothing. this is just a waste of typing. just use the original variables.
  25. it appears that php is not seeing or using the php.ini. there are a couple of common possibilities - the php.ini is actually named php.ini.txt, due to editing by a MS program, such as notepad.exe. have the file extensions been 'exposed' (a web search should show how to do this) on the computer, so that you actually see the whole filename.ext? when you browse to folders, do you see extensions like .exe, .txt. .dll? AFAIK, right-clicking on the php.ini and selecting 'properties' should show the actual full filename? if the php.ini is actually php.ini.txt, rename it to be just php.ini php doesn't report when there are syntax errors in .ini files, i.e. there is not a parse/syntax/reporting phase, just run-time errors for statements that fail when executed. how was php obtained and installed on the computer, i.e. has anyone else been editing the php.ini and could have introduced syntax errors in it?
×
×
  • 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.