-
Posts
5,514 -
Joined
-
Days Won
185
Everything posted by mac_gyver
-
your written statement is ambiguous. please post some examples showing what result you want for different input combinations. specifically, what is the 'successful' case, which can then be complemented to produce the error case? what do you want when $p is not Yes? is that an error or does it mean that you don't care about the other three values?
-
Database connection incl. insert, get update, and delete data.
mac_gyver replied to LeonLatex's topic in PHP Coding Help
are you asking this because something you have shown us doesn't work or for a critique of the method? here's a list of points for the posted code - i recommend naming the connection variables more uniquely, such as $db_host, $db_name, $db_user, $db_pass. you are going to require this code into a main file. depending on where it gets required at, you could have other $user and $pass variables that will conflict with this code. there's no good reason to catch and handle a connection exception in your code and re-throwing the exception you just caught with only the message and code looses the file and line information, hindering debugging. the only database exceptions you should catch and handle in your code are for user recoverable errors, such as when inserting/updating duplicate user submitted data. for all other query errors, all other type of queries, and for the connection, you should do noting in your code and let php catch and handle the database exceptions, where php will use its error related settings to control what happens with the raw database error information, via an uncaught exception error (database errors will 'automatically' get displayed/logged the same as php errors.) don't use the global keyword to make your code 'work'. doing this breaks function scope, is not general purpose, and makes it harder if you ever need to use more than one database connection in a script. you should supply inputs to a function as call-time arguments. query builders, like this, usually have a 'raw' query function/method to handle cases beyond what the code itself can handle. i hope you are NOT planning on directly using the submitted form data to supply the column definitions to these functions, as this is not secure. your code must be where the defining array is defined at, so that YOU have control over what happens with the data and what columns and data gets used when dynamically building the queries. having the definition in your code also allows you to define labels, for use in building error messages and dynamically producing form fields and validation rules, for dynamically validating data on the server before using it. because you are dynamically building these queries, you should surround the table and column names with back-ticks so that you don't need to worry about what the actual identifiers are at the point of building the query. because you are using exceptions for errors, the conditional logic you have for the ->execute() call in the insertData() function will never see a false value and should be removed. one of the main points of exceptions is that your main code only 'sees' error free execution, since execution goes elsewhere upon an error. if execution continues past a statement that can throw an exception, you know there was no error without needing to test using conditional logic. as already mentioned, you need the ability to test for a duplicate index error (number) from a query in the exception catch logic to handle the case of inserting/updating duplicate user submitted data. for both an insert and an update query, they produce a PDOStatment rowCount() and a PDO lastInsertId() values (yes you can get a lastInsertId() value from an update query, which can be used to get an arbitrary value from the query, such as the id of the row that was updated or the initial or final value that was updated.) you should return an array with both of these values in it. you need to consistently validate the $table and $data/$conditions inputs before using them. the deleteData function() should return the rowCount() value, not the boolean value from the ->execute() call, which again due to using exceptions will always be a true value. when you get to the point of writing the update function() you need to distinguish between the columns/values used in the SET ... part of the query and the columns/values used in the WHERE ... part of the query. WHERE ... terms often involve more than just = (equal) comparisons and only ANDing multiple terms. there are LIKE, IN(), BETWEEN, greater/less, ... comparisons and combinations using AND/OR between terms. insert, update, delete, and select queries can get prepared once, then executed multiple times with different input values. to handle this you can define the variable holding the PDOStatement object as a static variable inside the function, then only prepare the query if the PDOStatement object doesn't already exist. you need a way of destroying the PDOStatement object when you are done using it. you have set the default fetch mode to assoc when you made the database connection, why are you also putting it in the fetch call? -
is phpmyadmin working? your initial symptom is that the raw php code is being output to the browser. did this change to the file being downloaded? about the only thing that comes to mind (ignoring that you apparently directly created a file on the server and it didn't work) is that when you uploaded (ftp) the files to the web hosting they got changed, possibly due to using a binary transfer mode instead of text transfer mode.
-
MY PHP ( AJAX JSON .JS .CSS ) Scripting bugs and Fixes
mac_gyver replied to ChadMcCabe's topic in PHP Coding Help
The point of programming help forums is for you to post your code and the error or symptom you are getting and someone with the ability (and often without) will attempt to help you with the problem.- 1 reply
-
- 1
-
-
you should use var_dump() on the values for debugging, since it indicates the length of the value. unfortunately, you didn't show us what you saw when you echoed the variables and if you made a change to the sql query statement and it didn't work, showing us what you changed would help someone solve the problem. converting a query that has variables being put directly into it into a prepared query is straight forward - remove, and keep for later, any php variables that are inside the sql query statement. note: any wild-card characters in a LIKE comparison are supplied as part of the data value not as part of the sql query statement. remove any quotes or {} that were around the php variable and any concatenation dots/extra quotes that were used to get the php variable into the sql query statement. put a simple ? prepared query place-holder into the sql query statement for each value. call the PDO prepare() method for the sql query statement. this returns a PDOStatement object. call the PDOStatement execute([...]) method with an array of the variables you removed in step #1. for a query that returns a result set, fetch the data from the query. see the PDOStatement fetch() method when fetching a single row of data. the PDOStatement fetchAll() method when fetching all the rows of data at once. and occasionally the PDOStatement fetchColum() method when fetching a single column from a single row of data. forget about any num rows function/method/property. just fetch then test if/how many rows of data there are. for a query that doesn't return a result set, you can use the PDO lastInsertId() method and the PDOStatement rowCount() method to get the last insert id and the number of affected rows. for the query in this thread, this would look like - // i recommend that you build the sql query statement in a php variable. this makes debugging easier since you can echo the sql $sql = "Select * FROM weekends WHERE Weekend_Number = ? AND Men_Women = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([ $_SESSION['Weekend_Number'], $_SESSION['Men_Women'] ]); // if this query can match a set of data $result = $stmt->fetchAll(); // if this query can match at most one row of data $result = $stmt->fetch(); typical PDO connection code - $DB_HOST = ''; // database host name or ip address $DB_USER = ''; // database username $DB_PASS = ''; // database password $DB_NAME = ''; // database name $DB_ENCODING = 'utf8mb4'; // db character encoding. set to match your database table's character set. note: utf8 is an alias of utf8mb3/utf8mb4 $options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // set the error mode to exceptions - this is the default setting now in php8+ PDO::ATTR_EMULATE_PREPARES => false, // run real prepared queries PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC // set default fetch mode to assoc ]; $pdo = new pdo("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=$DB_ENCODING",$DB_USER,$DB_PASS,$options);
-
i second the use of prepared statements. you MUST protect against sql special characters in a value being able to break the sql query syntax, which is how sql injection is accomplished. a prepared query is the simplest (provided you use the much simpler and better designed PDO extension), fool proof way of accomplishing this for all data types. also, if the 'th' (ordinal indicator) is actually part of the value, it should not be. this is a human convention and should only be displayed, not actually submitted or stored. you should only submit or store the integer value. the code copying session variables to other variables is both unnecessary (just use the original variable that data is in) and indicates that your form and form processing code is on different pages. by separating these, you are nearly doubling the amount of code and since it takes more code to accomplish a task, you are likely leaving out things that provide security or a good User eXperience (UX.) the code for any page should be laid out in this general order - initialization post method form processing get method business logic - get/produce data needed to display the page html document
-
have you done or checked the 3 possible things that were already posted above? are you actually including SecureFunctions.php? also, do you have multiple sets of these files in different paths and there is more than one SecureFunctions.php and the wrong one got updated?
-
if this is the only session variable you are getting an error for (i didn't get an error for this variable, but did for some other ones when i ran your code), here are some possibilities - your actual code has some non-printing characters in or smart/curly-quotes around the index name (that posting code on this forum filtered out). i would delete and retype the entire index name, including the initial and final double-quotes, in each reference to this array index name. is any of the other code that gets executed in the functions being called, referencing or setting that variable and could be unsetting it? are you sure that the latest code got saved/uploaded so that you are actually initializing that variable? most of these session variables exist solely to pass data from the form processing code back to the form. you should instead put the form processing code and the form on the same page. this will greatly simplify all the code. the code for any page should be laid out in this general order - initialization post method form processing get method business logic - get/produce data needed to display the page html document at the completion of the post method form processing code, you should preform a redirect to the exact same URL of the current page to cause a get request for that page. this will prevent the browser from trying to resubmit the form data should that page get browsed back to or reloaded. you should not copy variables to other variables for nothing. just use the original variables that data is in. in the current code, a significant number of lines are there only to copy variables back and forth, yet you have instances of using the original variable that data is in. you should apply htmlentities() to any dynamic value being output in a html context, right before/as it is being output, to prevent any html entity in value from breaking the html syntax.
-
what this would look like using the method i posted above - <input type="text" maxlength="32" size="42" name= "<?=$Comment_Name?>" value="<?=$_SESSION["DE_Retain"] == 1 ? $_SESSION["DE_Comment"] : ''?>"> Max 32 Characters<br><br> likewise for the checkbox logic - Retain comment: <input type="checkbox" maxlength="1" size="1" name="Retain" <?=$_SESSION["DE_Retain"] == 1 ? 'checked' : ''?>> i'm pretty sure that checkboxes don't have maxlength or size attributes. if any of these variable may not exist, to prevent php errors, you need to use the null coalescing operator ?? to set default values. if you want to clear all the session data, you can use session_destroy();. if you only want to clear this 'form' data you are passing around, while keeping the current user logged in, you should store this data in a session array variable, such as $_SESSION['post']. you can then clear this data by just unsetting it - unset($_SESSION['post']);
-
my reply was a possible reason why php would work on your localhost system but not on actual web hosting. you have already checked, by trying, that the files are not being treated as php on the web hosting. you should not have needed to create a .htaccess file or put an addhandler ... line in it. this may in fact be why php isn't working. did you do this as an attempt to get the php to work after you discovered that it didn't or did you do this prior to trying to run any php code? has any php code ever worked on your web hosting? i would use your cpanel file editor to create a new .php file, and put the following in it, then request the URL of the this file in a browser to see if php works - <?php phpinfo();
-
do these files have a .php extension, i.e. you didn't configure your localhost system to treat .htm/.html extensions as being php code?
-
here's a slightly different approach. only write conditional code for the things that are - conditional. the only thing that's different in the output is the value (which actually doesn't make practical sense, since this is a field for a user to enter something into.) this also falls under Don't Repeat Yourself (DRY) coding. your if/else logic, which can then use the simple ternary operator, should only supply the desired 'Des' or 'Dave' value.
-
in case you didn't do a web search for the database server setting that's specifically listed in the error messages - https://dev.mysql.com/doc/refman/8.4/en/group-by-handling.html
-
Unable to pull data from database table
mac_gyver replied to portabletelly's topic in PHP Coding Help
after reviewing the code more, let me introduce you to 'event delegation'. this will let you simplify all the code for attaching events to the buttons. this works by attaching the event to a parent container, such as the div with class='right-content', that all the buttons will exist in, regardless of when they are created. you would then find which button has been clicked by testing an attribute value from the button, such as a class name. the code would look like - document.addEventListener("DOMContentLoaded", function() { console.log("✅ DOM fully loaded and parsed."); // use event delegation for dynamically added elements (buttons) // attach the event to a common parent element - class='right-content' const buttonWrapper = document.querySelector('.right-content'); // add the click event to everything in the common element, now or in the future buttonWrapper.addEventListener('click', function (event) { // examine the className of the clicked element console.log('target class: ',event.target.className); switch(event.target.className) { case 'view-details-btn': view_details(event.target); break; case 'change-status-btn': openStatusModal(event.target); break; case 'update-notes-btn': openNotesModal(event.target); break; case 'delete-btn': deleteRenewal(event.target); break; case 'closeModal': document.getElementById(event.target.getAttribute("data-modal-id")).style.display = "none"; break; case 'confirmChangeStatus': confirmChangeStatus(event.target); break; case 'confirmUpdateNotes': confirmUpdateNotes(event.target); break; } }); }); -
Unable to pull data from database table
mac_gyver replied to portabletelly's topic in PHP Coding Help
the most immediate problem is you are reusing id="updateNotesModal" for two modals. the modal you see is the one defined in get_renewal_details.php, but the javascript code that's running when you click the "update notes" button is what is defined in Renewals.php and this doesn't match the elements in the modal that is displayed. best suggestion is that get_renewal_details.php should only get and display the details. there should only be one id="updateNotesModal" modal defined, so there won't be any confusion about which one gets displayed and operated on. -
the php error you are getting is a follow-on error, because the query is failing, but there is no error handling for the query. the easiest way of adding error handling for all the mysqli statements that can fail - connection, query, exec, prepare, and execute, is to use exceptions for errors (this is the default setting now in php8+). to enabled exceptions for the mysqli extension, add the following line of code before the point where you make the database connection (or upgrade to php8) - mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); you should then be getting an uncaught exception error with the raw database error information in it about a non-groupby/non-aggerate column being referenced. the correct way of fixing this is to a) only select the columns you are using, and b) every column you are selecting needs to be either in the GROUP BY term or used in an aggerate function. there is a database server mode setting that control if this condition produces a query error (the current setting) or if it is just a warning. you may or may not have access to this database mode setting.
-
Using php to display different images based on the date
mac_gyver replied to Ocean_Voyager's topic in PHP Coding Help
the syntax error(s) are due to missing quotes on the end of each string and reusing the same type of quote inside the strings. you are building and echoing literal strings. the initial and final quotes on each string must be the same type and be a matching pair. you are missing the final quote on each string. the > at the end are part the <img ... > tag and belong inside the string, e.g. echo "<img ...>";. any quotes that are within a string must either be the 'opposite' type, single vs double, or they must be escaped so that they don't match the initial quote, which terminates the string. the initial and final quotes around the src="..." attribute should either be changed to single-quotes or escaped with \ characters. i prefer less typing, so i would use single-quotes. next, your conditional logic only needs - if( normal case){ echo normal output } else { echo special output }. lastly, your conditional comparisons need some help. you need to test if the 'm' and 'd' part of the date is greater than or equal a lower value AND less then or equal to a higher value. also, for testing purposes, you need to be able to manually set the value being tested, so this value should be built in a variable, which will be a string, e.g. '0106' for jan 6th. as long as the fields making up a string are the same width, and from left to right, most significant to least significant, you can directly compare strings, e.g. if('0106' <= $some_variable ... i'll let you cogitate on how to create and test the conditional logic needed. -
What am I doing wrong with this 'php include' coding?
mac_gyver replied to Ocean_Voyager's topic in PHP Coding Help
the file system path/filename must be to where the file is located on the disk, either using a relative path (relative to the file with the include/require starting in it) or an absolute path. a leading / refers to the root of the current disk, which is doubtful where that file is located, and which will be producing a php error about a non-existent path/file. you must get php to help you by reporting and displaying all the errors it detects. you can temporarily set php's error_reporting/display_errors in your code (you will want to remove the settings when you are done learning, developing, and debugging). you can add the following immediately after the first opening <?php tag in the main file - ini_set('display_errors', '1'); error_reporting(-1); -
Could use some insight on a database installation issue...
mac_gyver replied to Jim R's topic in MySQL Help
it would be nice to know what you do and what the software does concerning database creation, database user creation, and database user permissions. do you create the database, the database user, and assign permissions, then enter the connection information into the configuration file? are any tables being created in that database? are there any other similarly named databases that if they for example stripped out non-ascii characters could match the desired database name? what i suspect is there is more than one database, that they then get switch somewhere in the process so that at the point where the query in question is executed it's not using the correct database or that the table creation fails due to a permission issue and there's no error handling and/or no reporting of the failed table creation queries. -
What am I doing wrong with this 'php include' coding?
mac_gyver replied to Ocean_Voyager's topic in PHP Coding Help
a bunch of points - three ... in a relative file system path is invalid. you should be learning, developing, and debugging code on a localhost development system, such xampp. do you have php's error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini on your development system, so that php will help you by reporting and displaying all the errors it detects? is the main page a .php page? what does the 'view source' of the resulting web page show in the browser? you should use 'require' for things your code must have. your goal is to produce ONE valid web page. the file that you require is not a complete web page, it is only the code/content that you want to be required at that point in the web page. you need to validate the resulting web pages at validator.w3.org all the navigation links you have shown are all the same. you should be dynamically building the web pages using a Content Management System (CMS), in which case the navigation links would be dynamically built too, based on the defined pages, instead of manually creating and managing a bunch of pages yourself. -
Could use some insight on a database installation issue...
mac_gyver replied to Jim R's topic in MySQL Help
are you sure of the database name and its capitalization? what type of hosting is this? on shared web hosting, the actual database name usually gets some unique part of the account naming prepended to it, so that everyone who creates a database named 'abc' actually gets a separate database that only their account can see and access. -
send checkbox value to email using phpmailer
mac_gyver replied to ianhaney10's topic in PHP Coding Help
only checked checkboxes are set in the submitted form data. for what you are doing, you should only be concerned if they are set or are not set, not what the value is (the default value will be the text 'on'). i recommend that make an array that defines the checkbox field names and labels, then loop over this defining array to dynamically produce the form fields, pre-checking any existing checked boxes, in the case of a user/validation error, then loop over this defining array in the post method form processing code, testing which one(s) are set or are not set in the form data to produce whatever result you want.- 1 reply
-
- 1
-
-
what does the data look like? is there only one row of data or is there a set of rows of data? modern php no longer assumes that unquoted associative array indexes, that are not defined constants, are strings. you must use quotes around associate array indexes. if you tried the above code, did it produce php errors? do you have php's error_reporting set to E_ALL (it should always be this value) and display_errors set to ON, so that php will help you by reporting and displaying all the errors it detects?
-
the attached code displays the menu, but has nothing to do with adding items to an order (cart), entering the customer information, or submitting/saving that information as an order. some points about the posted code, most of which will greatly simplify it (eliminating more than half of the typing) - use 'require' for things your code must have. don't prepare and execute a query that doesn't have any dynamic value being supplied to it. just use the ->query() method. the settings don't need elseif() logic, just if(), because the option_name can only be one value at any time. Don't Repeat Yourself (DRY.) there are only a few small things different between the corresponding if/else code blocks. the conditional logic should only setup the values for the different things in variables, then simply output them in one instance of the code. don't run queries inside of loops. use a single LEFT JOIN query to get the menu categories and menu items all at once. when you fetch the data, index/pivot it using the category id as the main array index. you can then simply loop over the data using two nested foreach(){} loops to produce the output. don't create unused variables/code. when embedding a php echo statement in html markup, use php's short-open-echo tag <?= and you can leave out the closing ; right before a closing ?> tag, for example - <?=$source?> SELECT queries that can return more than one row need an ORDER BY ... term to insure that the rows are in an expected order.
-
here's an example for the fields you have shown in this thread - <?php // define the fields // you would add other things to this definition, such as validation rules and processing rules $fields["it_c"] = ['label'=>'Whatever it_c is','type'=>'numeric']; $fields["it_h"] = ['label'=>'Whatever it_h is','type'=>'numeric']; $fields["ot_c"] = ['label'=>'Whatever ot_c is','type'=>'numeric']; $fields["ot_h"] = ['label'=>'Whatever ot_h is','type'=>'numeric']; // add entires for all the form fields... // examine the submitted data echo '<pre>'; print_r($_POST); echo '</pre>'; ?> <?php // produce the form ?> <form method='post'> <input type='submit'><br> <?php foreach($fields as $field=>$arr) { switch($arr['type']) { case 'numeric': echo "<label>{$arr['label']}: <input name='$field' type='text' class='numeric'></label><br>"; break; // code for other types... } } ?> <input type='submit'> </form>