Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,382
  • Joined

  • Days Won

    173

Community Answers

  1. mac_gyver's post in Update Price based on Quantity Selected was marked as the answer   
    <script> const format = (num) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(num); </script> replace $('#totalPrice').text(totalPrice); with $('#totalPrice').text(format(totalPrice));
  2. mac_gyver's post in Not connecting to MySql database using $CONN in attempting to set up ElementorPro CRUD was marked as the answer   
    you should be learning, developing, and debugging your code/queries on a localhost development system. trying to use public/online hosting is a waste of time, constantly uploading, and making sure there were no upload errors, to see the result of each change. until your code is secure, this opens the possibility of your web hosting getting abused by hackers. also, most cheap shared web hosts disable things like php's error related settings and database error settings that you need in order to get php and your database statements to help you. they also set disk and web server caching so that you won't immediately see the result of changes you make to your code.
    the database hostname on shared hosting is generally not going to be localhost. your web host should have an FAQ section that gives examples of connection credentials. the control panel where you created your database user/password should also list the hostname/ip address to use and any prefix for the username.
    if you can setup php's error related settings, you need to set error_reporting to E_ALL and set display_errors to ON. these should be in the php.ini on your system so that they can be changed at a single point.
    next, you always need error handling for statements that can fail. for database statements that can fail - connection, query, prepare, and execute, the simplest way of adding error handling, without adding logic at each statements, is to use exceptions for errors and in most cases simply let php catch and handle the exception, where php will use its error related settings (see the above paragraph) to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.) to set the error mode to exceptions for the mysqli extension, add the following line of code before the point where you make the database connection -
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); lastly, if you are just starting with php/MySql, learn and use the simpler and more modern PDO database extension.
  3. mac_gyver's post in Some Real Beginner's Questions was marked as the answer   
    the code for any php 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 the code for any particular section can all be in the main file or divided between the main file and any number of separate files that get 'required' when needed. the html document should only contain simple php code, acting like a template engine, that operates on the input data supplied to the html document from the other sections of code OR more simply just use a 3rd party template engine.
     
  4. mac_gyver's post in Php mysql edit data was marked as the answer   
    the key to updating an existing row or inserting a new row is the existence or absence of an id (autoincrement primary index) in the form data.
    if your database table doesn't already have an id/autoincrment column, add it. when you query to get the existing data to edit, add this column to the SELECT ... list (you should actually list out the columns you are selecting, rather than use *). output the id in a hidden form field. in the form processing code, if the id input is a true value, execute the code for an UPDATE query. if it is not a true value, execute the code for an INSERT query.
    to handle both having existing data to edit or no data, you should have an intermediate array variable, such as $post, that will initially hold any existing data that you fetch from the SELECT query, then inside the post method form processing code be assigned a trimmed copy of the $_POST form data. in the form value attributes, use php's null coalescing operator (??) to output the corresponding $post value or an empty value -
    Energie: <input type='text' name='Energie' value='<?=$post['Energie'] ?? ''?>'><br>  
  5. mac_gyver's post in Need Help tp simplify a function. was marked as the answer   
    assuming the function code already exists and you don't want to change it, you can use php's splat ... operator to call the function with an array of values that will get expanded into the individual input parameters.
    $gift_fields = [77, 80, 65, 66, 67, 83, 74, 87, 88, 90, 92]; $params = []; foreach($gift_fields as $field) { $params[] = $form_data['field'][$field]; } echo SpecificGifts(...$params); if you rewrite the function code to accept and operate on elements of a single array input parameter, you would change the last line to - echo SpecificGifts($params);
  6. mac_gyver's post in Need Help with PHP Function - newbie here was marked as the answer   
    $form_data doesn't exist inside the function (there would be php errors.) 
    you could actually just define the function to accept an array of data as the input and call the function with $form_data['field'][77] as the input parameter. this will allow the processing to be applied to any array of data, not hard-coded for $form_data['field']...
  7. mac_gyver's post in Match issue with /u switch was marked as the answer   
    substr() deals with single byte characters. try mb_substr()
  8. mac_gyver's post in Error 405 Not Allowed nginx was marked as the answer   
    i suspect the error is due to exceeding some limit at your free/cheap web hosting -
    you might ask their support group.
    already stated -
     
  9. mac_gyver's post in "SQL LIKE Keyword" search not functioning as it should was marked as the answer   
    the ? place-holder that's put into the sql query statement is only the ? character, no single-quotes, no wild-card characters. any wild-card characters go around the value you are supplying in the execute() call.
    you should also be using a method = 'get' form when performing a search and to get the form to submit to the same page it is on, simply leave the entire action='...' attribute out of the form tag.
    also, Don't Repeat Yourself (DRY.) use one single search form. to select which type of search, use either a select/option menu or radio buttons.
    the serach form should be 'sticky' and repopulate the form fields with any existing search inputs and use css instead of in-line styling.
  10. mac_gyver's post in GET form being posted to "index.php" every time / not doing what expected was marked as the answer   
    did you not read the reply in the existing thread for this task?
    anyways, the form field values for a get method form will replace any get parameters you try to put on the end of the url in the action='...' attribute. to supply 'additional' get parameters, you would need to use hidden form fields.
  11. mac_gyver's post in search for unknown number in a string? was marked as the answer   
    $string = 'Joe has 5 large apples'; // find any digit(s) in the string if(preg_match('!\d+!', $string, $matches)) { print_r($matches); // result in $matches[0] } else { echo 'no number found'; } // find digit(s) with the specific before/after text if(preg_match('!Joe has (\d+) large apples!', $string, $matches)) { print_r($matches); // result in $matches[1] } else { echo 'no number found'; }  
  12. mac_gyver's post in Upgrade from php 7 to 8 broke class code was marked as the answer   
    i just tried the code, and there is one php version difference. a method named the same as the class is no longer automatically called when an instance of the class is created. you must specifically name the method __construct. change function PicSQL($DBName = ""){ to function __construct($DBName = ""){
  13. mac_gyver's post in Login Form Username / Password Values was marked as the answer   
    @Barand, the OP is using PDO.  bindValue(), PDO::PARAM_STR, and errorInfo() are all PDO elements.
    the error you are getting, assuming that php's error_reporting is set to E_ALL, means that the query didn't match a row. you need to test when you fetch the row if anything was fetched. if a row was fetched, it means that the WHERE clause was true and there's no need to test in the current php code if the form username matched the fetched username. however, if no row was fetched, this indicates that the WHERE clause was false. that's the condition where you would setup the login failure message.
    as to why the query isn't matching a row, and isn't producing an error, are you sure the username/password that you used was correct? when you executed the query directly in phpmyadmin, did it contain the sha1() password hash or did it directly have the password in it?
    when you make the database connection are you -
    setting the character set to match your database tables? setting the error mode to exceptions setting emulated prepared queries to false setting the default fetch mode to assoc as to the link you posted, don't take a backward step and use the mysqli extension. the PDO extension is the best choice, though you can simplify how you are using it, and whatever is causing the current code to not match a row will still be a problem with a different database extension.
    btw - you should be using php's password_hash() and password_verify(). the simple sha... hashing functions where never intended for security purposes. you should also only store the user id (autoincrement primary index) in the session variable to identify who the logged in user is. you should query on each page request to get any other user information, such as the username or user role/permissions. this insures that any changes made to these values will take affect on the very next page request.
     
  14. mac_gyver's post in Call to undefined function Login_sucess() was marked as the answer   
    you have actually been give the answer -
    don't put function definitions inside of other function definitions.
  15. mac_gyver's post in Calendar paging was marked as the answer   
    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>  
  16. mac_gyver's post in Problems saving to sql after updating to PHP 7.3 was marked as the answer   
    It's possible that some of the data values that are not present for a one-way trip don't have an acceptable default value and/or are not allowed to be a null value in the database table definition, and the database server mode is now set to strict mode, which will cause an error for those columns, rather than truncating data to the nearest min/max value.
    this code doesn't have any (useful) error handling for the database statements that can fail and the one place it does have some, won't work, because the connection variable is missing from the msyqli_error(...) call. the easiest way of adding error handling for all the database statements, without adding logic at each statement, is to use exceptions for database statement 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 (database statement errors will get displayed/logged the same as php errors.) to use exceptions for errors for the mysqli extension, add the following line of code before the point where you make the one/single/first connection -
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); i hope that this code is just part of an assignment and is not on a live/public server, because it has no protection against sql special characters in the data values from breaking the sql query syntax, which is how sql injection is accomplished. you should be using prepared queries when supplying external, unknown, dynamic values to a query when it gets executed.
     
  17. mac_gyver's post in Give Image to HTML through PHP-doesn't work was marked as the answer   
    that opens the file through the file system, not the web server, so, any links in the html will also be read through the file system. you must use a url to the html file, such as http://localhost/phptest.html. this will cause the src="phptest.php?id=1" attribute to be read through http://localhost/phptest.php?id=1
  18. mac_gyver's post in Call to a member function query() on null was marked as the answer   
    https://www.php.net/manual/en/language.oop5.visibility.php
  19. mac_gyver's post in Inserting csv records into a mysql table was marked as the answer   
    check is a reserved work and should not be used as a column name. either use a different name for that column or you must enclose the column name in back-ticks to cause it to be treated as an identifier.
  20. mac_gyver's post in Session variables are not being read was marked as the answer   
    are you using full <?php opening tags, per the problem in one of your previous threads? https://forums.phpfreaks.com/topic/311034-includes-not-being-displayed-on-page  how about the other improvements made in that thread? you seem to have gone backwards.
     
  21. mac_gyver's post in look up table was marked as the answer   
    calculate how long it will take for your table to have 5 million rows in it. with today's server hardware, 5 million rows in a properly indexed table is about the point where you need to start worrying about doing things like using partitioning or archiving older data.
  22. mac_gyver's post in Cookie issue was marked as the answer   
    the code at the top of your post has - setcookie('hs_user_sess', $session, time() + (86400*30));, but there is no $session variable present in that code, so it would set the cookie to an empty value.
     
    also, break; only works for loops and switch statements. it has no affect on if() statements, so in the cases where you have used it in the code above, all the logic is still being executed.
     
    if your code testing if the cookie is set is being executed on the same page request where you are setting the cookie, the $_COOKIE variable won't be set until the browser makes a request to the web server after you have set the cookie.
  23. mac_gyver's post in newbee to PHP, help with setting up my php to send to a txt file was marked as the answer   
    the code on your page should be laid out in this general order - initialization, start of database dependent code, determine user state and permissions, post method form processing, get method business logic, end of database dependent code, get method presentation logic, and html docuement/template.
     
    1) initialization - create/define things your code needs - session_start(), require files holding configuration data/function definitions, setup an autoloader for class definitions...
     
    2) start of database dependent code - create a database connection.
     
    3) determine user state and permissions - check if the current user is logged in and retrieve any permissions the user has. the rest of the code on the page would make use of the logged in state and permissions to determine what code can be ran and what content will be produced.
     
    4) post method form processing - the post method form processing code, which causes an action or change in state or change in data values on the server, should come near the start of your file so that you aren't tempted to output anything to the browser before the action/state/or data operation has been performed by the processing code. if your page has multiple sections of form processing code, you would have them all groped together in this section of code.
     
    after successfully (no errors) processing any post data, do a header() redirect to the exact same url that the form submitted to. this will cause a get request for your page. this will cause the browser to forget that a form was just submitted to that url and it won't try to resubmit the form data if you refresh the page or browse back to the same url. this also enforces separation of concerns. post method form processing is a separate concern from displaying data due to a get request for your page. if you want to display a one-time 'success' message after the header() redirect, pass it in a session variable, then clear he session variable after the the message gets displayed.
     
    if there are errors while processing any post data, you would not redirect, stay on the page, let the rest of the code on the page display the errors, (re)display the form, and repopulate the form fields with (some of) the previously submitted values.
     
    5) get method business logic - code that produces/gets data needed for the dynamic content on the page. this code contains any database specific code that knows how to retrieve data from your database tables. the result of this code should be php variables that the code later on the page uses as its input. this code should contain NO html/css/javascript markup.
     
    6) end of database dependent code - you can (or let php do this when the script ends/exits) destroy any query result resources (to free up memory) and the database connection at this point since you won't need them any longer.
     
    7) get method presentation logic - code that knows how to take the data (database data, errors, form data...) from ALL the above code and produce the dynamic output for the page. if the output doesn't require any 'heavy' processing/formatting, just use the data directly in the html page/template code. the result from this code should be php variables that the html page/template uses. this code should contain NO database specific statements. if your page has multiple sections of get method presentation logic, you would have them all groped together in this section of code.
     
    html document/template - this section starts with the <!DOCTYPE ... tag and ends with the </html> tag. it is the actual html document that the dynamic output is put into to make the complete page. if you use php (rather than an actual template system) only simple php conditional logic/loops, function calls (that are responsible for producing output), and echo statements should be present in this section of code. any data you output on the page needs to be passed through htmlentities() in order to prevent any html content in it from being operated on by the browser.
     
    if you organize the code on your page like this, it will separate all the different concerns, making it easier to see what your code is doing, easier to test, and easier to get help with because you can isolate and post just the relevant part.
     
    next, if you put the form processing code and the form on the same page, it will reduce the amount of code you have to produce, since it will eliminate the repetition of the common items. this will also let you re-populate the form field values in the case where there were validation errors with the submitted form data.
     
     
    some specific comments for the code you have posted -
     
    1) the global keyword only has meaning when used inside of a function (which you are not doing) and even then it should be avoided as it breaks the encapsulation and scope. remove any lines of code containing the global keyword.
     
    2) if you use a php array variable to hold validation error messages, it will also serve as an error flag. if the array is empty(), there are no errors. if the array is not empty(), there are errors. after you have validated all the input data, you would use that data if there are not errors. at the point of (re)displaying the form, if there are errors, you would display them, either as a group or display them individually near the form field they go with.
     
    3) you should NOT be using addslashes() at all.
     
    4) whatever your validateInput() function code is, is probably not actually validating anything. if you want help with the validateInput() code, you need to post it.
     
    5) this is a bit tongue in cheek, but a person's age is not a fixed value, unless they are dead, and you should not be storing a person's age. you should be getting and storing the date of birth and then calculating the age when needed.
     
    edit: since you are using a file to hold the data, substitute 'file operations' for any mention of 'database' in the above information.
  24. mac_gyver's post in How can an index be set and undefined at the same time? was marked as the answer   
    the error is because you are concatenating the string 'count: ' with the isset() expression, which will always be true. you need to put () around the trinary statement so that it is evaluated as an expression that then gets concatenated with that string.
  25. mac_gyver's post in Updating Database changes all entries was marked as the answer   
    your code and queries are only as secure as you make them. if you use a prepared query incorrectly, it will won't be secure.
     
    by using a true prepared query (the PDO extension has emulated prepared queries turned on by default for all database types, despite what the documentation states, and you need to turn them off when you make the database connection) to supply data values to the sql query statement, your sql query will be safe against sql special characters in the data from breaking the sql syntax or breaking out of, i.e. escaping from, the sql syntax in the case of intentionally injected sql.
     
    after you choose the php database extension you are going to use, the posted code needs to do or not do a number of things -
     
    1) you are mixing procedural and OOP style for the msyqli statements. you should be constant in your programming. using the PDO extension will fix this since it only has OOP statements.
     
    2) using prepared queries will eliminate all the ...real_escape_string() calls. you are using one in the case of a value being output to the browser. the ...real_escape_string() statements are only used on string data being supplied to a non-prepared sql query statement, not on data being output to the browser.
     
    3) you need to use exceptions to handle database statement errors. your code has error handling on only one of the query statements now. the PDO extension already uses exceptions for connection errors. you need to set the error mode to exceptions, for all the rest of the statements, when you make the connection.
     
    4) all the post method form processing code should be grouped together and come near the top of your code. you should actually test if a post method form was submitted, then if you have multiple possible forms, detect a field name or field value that identifies if the Delete or Update form was submitted.
     
    5) you should validate all the submitted data before using it, then only use it if it is valid. use an array to hold validation errors. you can then test if the array is empty or not to determine if there have been any validation errors. to display the errors, just output the contents of the array.
     
    6) your delete checkbox logic only works for a single/last checkbox. in fact, all the form fields don't work when there is more than one set of data in the form. you need to use array names for all the form fields, with the $row['id'] value as the array index (this is needed to distinguish which row each form field value corresponds to) and you need to remove the hidden field with name='checkbox' (having this causes only the last checkbox in the form to work.) you would also need to add a loop in the Update form processing code to loop over all the submitted sets of data.
     
    7) with prepared queries, when you are looping over data and executing the query inside the loop, you will prepare the query once before the start of the loop. the code inside the loop only gets the correct set of data and calls the ->execute() method.
     
    when you remove the hidden form field with name = 'checkbox' (which was done to prevent php errors when no checkboxes are checked, but because it is being output repeatedly, only allows the last checkbox to work), the logic in the delete form processing code will need to be changed. if there are no checked checkboxes, $_POST['checkbox'] won't be set. you need to add an if(isset($_POST['checkbox'])) test.
     
    9) the code to retrieve the data needed to display the page should be removed from the actual html document/template. this will make it easier to write and test your code, and if you need to change the code to use a different database extension, such as the PDO extension, consolidates the database specific code in one place and makes the html document/template general purpose. just fetch the data from the query into a php variable and use that variable in the html document/template.
     
    10) the html document you are creating is reusing DOM id='...' attribute values. id's must be unique. if the client-side code isn't actually referencing the id's, don't even put them into the markup.
     
    11) you are outputting an empty <tr></tr> after each actual <tr>....</tr> of output. makes no sense and is repeating an id attribute value which is also not valid. only output markup that you need.
     
    12) you are outputting the $row['id'] value in a form field. this is not an editable data value. the $row['id'] specifies which row the data belongs to. you can display the $row['id'] value if you wan't, but it should not be in a visible form field. see item #6 in this list for how the $row['id'] value should be used to associate the submitted values with the $row['id'] value they belong to.
     
    13) when your SELECT query doesn't match any data, your code is correctly skipping over the code to produce the output from that data, but your code is also not doing anything to notify the user that there was no data to display. you should set up and display a message that the reason for the blank section on the page is that there is no data to display.
     
    14) all data values being output to the browser should be passed through htmlentities(), with an appropriate 2nd parameter value, to prevent any html entities in the data from breaking the html on the page and to help prevent cross site scripting.
     
    15) you are repeating the <tbody>...</tbody> tags for each set of data being output. while this is valid markup, unless you are going to style each table body section separately, there's no point in doing this and it is just adding clutter to the result and would prevent a large table body section from being able to be scrolled on the page.
×
×
  • 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.