-
Posts
5,450 -
Joined
-
Days Won
175
Everything posted by mac_gyver
-
works correctly for me. if your posted code didn't create the constants, either - that's not the actual code that was executed, e.g. that exact code didn't get saved to and executed on the web server. there's more code involved, such as function definition(s), so that the scope of the $db array and the foreach(){} loop are different so that the foreach code failed (there would be a bunch of php notice/warning errors.)
-
for the set of values that you want to optionally include, you should use a html array for the form field name, with the item id as the array index, then you can test and loop over that array of values to dynamically add them to the email body. you would use the item id values to query for the information about the items to include them in the email so that it will have helpful context for whoever must deal with the order information. if you have more than 2-3 form fields, you should use a data-driven design, where you have a data structure (array or database table) that defines the expected fields, which fields are required, and which fields have specific formats that must be met, e.g. an email... you would then loop over this defining structure and use general-purpose code to validate and process the data. your form processing code should - detect if a post method form has been submitted before using any of the form data. your current logic, because it doesn't stop code execution, actually runs everything even if a form has not been submitted. don't copy variables to other variables for nothing. this is just a waste of typing time. instead, keep the set of form data as an array and operate on elements in this array throughout the rest of the code. trim all input data before using it so that you can detect if all white-space characters were entered. this can be done using one singe statement, provided you have done item #2 in this list. validate all the trimmed data before using it, storing validation error messages in an array using the field name as the array index. if there are no validation errors, the array holding the error messages will be empty, use the summitted form data. any external, unknown, dynamic value you put into the mail body need to have htmlentities() applied to it in order to prevent any html, css, or javascript in it from being rendered when you read the email in a browser. any value you put into a mail header, such as the visitor's email address as a Reply-to: field, must be validated that it is exactly and only one properly formatted email address in order to prevent mail header injection.
-
given the number of mistakes in the first posted code, post your current php code. also, for debugging, add the following immediately before the if($_SERVER["REQUEST_METHOD"] == "POST") { line of code - echo '<pre>'; print_r($_POST); echo '</pre>'; after you submit the form, what output do you get on the page? i'm thinking you have something like a header redirect in your code, that you are not showing us, and any output from your code is being discarded and you are seeing the original page being output to the browser. requiring the user to know and enter id values is error prone. you should provide some method of selecting from existing records. lastly, depending on how the data originally got inserted into the table, you could have white-space characters as part of the data, so nothing you enter in a form field will ever match the values. how did the data get inserted?
-
are you requesting this page using a URL, so that the php code will get executed, or a file system path, which would show the raw php code in the 'view source' in your browser? what do you see when you look at the 'view source' in your browser? is the html markup for the page valid, so that you don't have something like nested forms going on? to get the browser to submit to the same page and get any existing get parameters in the url to automatically be propagated between pages, just leave the entire action attribute out of the form tag. you need to validate all inputs before using them, and set up a user error message for required inputs that don't exist. the return value from the mysqli_query() call for a delete query doesn't tell you if the row was deleted or not. it just tells you if the query executed with or without an error. however, since you are also using an or die() for error handling (which shouldn't be used at all, you should use exceptions for error handling for database statements), you will never see the else {} "Error deleting record" message. to actually detect if a row was delete, you need test the number of affected rows. a prepared query has nothing to do with where or how a value is entered. they are about protecting against sql special characters in external, unknown, dynamic values from breaking the sql query syntax, which is how sql injection is accomplished.
-
the main issue is due to local variable scope within functions (the $errors array you are returning is being created anew inside each function call) and wrong-responsibility of function code. user written functions should do useful things (building blocks) that help you to create applications (they should not contain your application specific code), they should accept all input data as call-time parameters, and they should return the result to the calling code. in short, breaking up and wrapping your main code inside of function definitions, then needing to make everything global to get it to work, is just adding a lot of typing that doesn't add any value to what you are doing. also, buried within this wall of code is a logic mistake (the looks like it came from w3schools) - if(!$username){ $errors[] = "A username is mandatory"; echo "A username is mandatory <br>"; } else { $username = clean_names($username); } that code is first testing if the raw value is false or not, then it is using whatever the clean_names() function does to the value throughout the rest of the code. based on what w3schools code has done in the past, this will let a value consisting of all white-space characters pass the raw test, but will use an empty string in the rest of the code. the only modification you should make to user submitted data is to trim it, first, then use that trimmed value throughout all the rest of the code. as to testing if a username (or any other unique value) already exists, define the column as a unique index, just attempt to insert the data, then detect if a duplicate index error occurred. by first trying to select the data, there's a time gap where dozens of queries can be executed which could then take the value that you think is not in use. you should also be using a prepared query when supplying external, unknown, dynamic values to a query when it gets executed.
-
General questions on PHP security and Object Oriented Programming
mac_gyver replied to Fishcakes's topic in PHP Coding Help
define: Are hackers able to see ... anything in your server-side code? if someone gains direct access to your server-side files or gets their server-side code to run on your server (which typically includes a file-manager/control-panel), they can see everything in all the files. for the simplest case of someone just getting their server-side code running on your server to grab and output all main program (global) variables and defined constants, yes, database connection credentials defined within the main program scope are accessible. for this simple case only, using the local variable scope within a user written function/class-method or non-public visibility for properties/constants within a user written class would prevent access to these values. if someone makes a http(s) request to your server-side files, as long as the server-side programming language is functioning, they can only see what your server-side code outputs in response to the request. for the extremely rare case where the web server is functioning but the server-side language is not, i.e. the raw php code would be output in response to a request, putting the server-side files containing things like database connection credentials either in a folder outside of the document root folder or if that option is not available inside a folder inside the document root folder but which has had http requests disabled for that folder will prevent http requests to those files. -
Upload file doesn't arrive into uploads/ folder
mac_gyver replied to Chrisj's topic in PHP Coding Help
see the following link on how you can log what the $_FILES array actually contains and what your post method form processing code should do - https://forums.phpfreaks.com/topic/312874-cant-access-_files-after-form-submission/?do=findComment&comment=1587078 -
Comparing whether files are identical
mac_gyver replied to NotionCommotion's topic in PHP Coding Help
i would compare the size, then the hash. if the size/hash for existing files is in a db table, you can just query to find any potential matches, then compare the contents only for files with a size/hash match. some code i did long ago, with some new comments related to including a newly uploaded file in the data - <?php // dupless (a file compare utility) using php // read all the files and file size, store using the size as main array key, path/file as the data // all sizes with only one file are unique - remove // loop though each size array and get the md5 of the file, store using the md5 as a key, path/file as the data // all sizes/md5 with only one file are unique - remove // remaining with same size/md5 are likely the same, you would need to actually compare contents at this point $path = './keep/'; // get list of existing files $files = glob($path.'*.*'); // because the $files data contains the path/file, you can array_merge() other files here to // include them in the comparison, such as a newly uploaded file. if the path/file is in the results, // there's an existing file with the same size/hash as the uploaded file $files = array_merge($files, glob('*.*')); $data = array(); // get data by size foreach($files as $file){ $data[filesize($file)][] = $file; } foreach($data as $size=>$arr){ // remove unique size if(count($arr)==1){ unset($data[$size]); } else { // more than one for this size foreach($arr as $pos=>$file){ // remove existing element unset($data[$size][$pos]); // replace with md5 of the file $data[$size][md5_file($file)][] = $file; } // for the current size array, remove unique md5 entries foreach($data[$size] as $key2=>$arr2){ if(count($arr2)== 1){ unset($data[$size][$key2]); } } // if the current size is now empty, remove if(count($data[$size])==0){ unset($data[$size]); } } } echo '<pre>',print_r($data,true),'</pre>'; -
https://www.php.net/manual/en/language.oop5.visibility.php
-
php creates class properties (variables) without having to define them. the only thing defining them does is enforce the stated visibility.
-
Can't access $_FILES after form submission
mac_gyver replied to viktor122's topic in PHP Coding Help
i tried your client-side code and it works for me. however, the things i bypassed or added to make it work, which you didn't include, may have altered the operation of the code. it is always helpful if you post complete, working, code. you may want to log the $_FILES information on the server so that you can see what it actually is. add something like the following to the php code in the file that's the target of the ajax call - file_put_contents('log.txt',print_r($_FILES,true),FILE_APPEND); your post method form processing code should have always been in the target file of the ajax call. your form processing code should - detect if a post method form was submitted, i.e. you need the if($_SERVER['REQUEST_METHOD'] === 'POST'){...} logic. next, if you exceed the post_max_size setting, which is what i think is probably occurring, both the $_POST and $_FILES arrays will be empty. you must test for this condition after item #1 above, and setup a message for the user telling them that the total size of the form data was too large. you would also want to log this information, including the actual size of the post data, so that you, the developer/programmer, will know that it is occurring as the result of user actions on your site. if the $_FILES array is not empty, you can then use elements in that array. you must next test if the ['error'] element is zero (no errors) or some other value (see the upload handling section in the php.net documentation for all the possible error values.) for errors that the user has control over, you need to setup a unique and helpful error message telling the user what was wrong with what they did. for the errors that the user has no control over, you should log the actual error information and setup a general failure message for the user. only after you have done the above three things, will you have actual uploaded file information that you can use. -
You can and should put configuration files outside of the document root folder. The variable $_SERVER['DOCUMENT_ROOT'] contains the path to the current document root folder, which you can then concatenate the desired path to the configuration file to, to arrive at the actual path.
-
^^^ this is the upfront information that should have been included in the first post in the thread, i.e. what top level thing you are actually trying to accomplish. your reactive, after the fact, attempted solution to use DOMDocument, in the php code on the web server, WON'T work because the web server doesn't have direct access to the user modified DOM that only exists in the user's browser. your attempt at opening and reading the index.php FILE, was both misleading and would read the raw content of that file. even if you used a http wrapper and requested the index.php page from your own web server, you would only get the initial DOM, that the web server sends out to the user's browser. repeating now what @requinix has stated, the only way of getting anything from the browser to the web server requires that you make a http(s) request to the web server that contains the information that you want. you will need to pick some point in the code in the browser where the value(s) have been changed, then get those value(s) and include them in a http(s) request to the web server.
-
PHP Version 5.6.40, internal error for connect mysql
mac_gyver replied to nitiphone2021's topic in PHP Coding Help
why have you thrown away the code at that start of this thread, using the mysqli extension, and are now trying to use the mysql extension? what is the overall goal/end point of doing this? -
PHP Version 5.6.40, internal error for connect mysql
mac_gyver replied to nitiphone2021's topic in PHP Coding Help
http 500 errors are due to either php parse errors or fatal runtime errors. according the phpinfo output, you need to edit your php.ini and set error_reporting to E_ALL and set display_errors to ON so that php will help you by reporting and displaying all the errors it detects. stop and start your web server to get any changes made to the php.ini to take effect and then check in the phpinfo output to make sure the settings were actually changed. note: since you are using the procedural mysqli_connect(), you cannot use $conn->connect_error to test for a connation error. you will just get a php notice about trying to get property 'connect_error' of non-object ... and the code will continue to run as though the connection was successful, which may be the cause of the http 500 error later in code that's trying to use the connection. don't mix procedural and OOP mysqli statements. or even better yet, switch to use the simpler and more consistent PDO extension. it doesn't have all the problems that the mysqli extension has. -
in what php version does that not produce a syntax error? is that your EXACT code? if that was in fact, like this - $result = $mysqli -> query("SELECT * FROM mytable"); { // do something } php allows extra {} to exist that are not part of any actual statement, but they have no significance. the code inside of them is always executed. so, for the case of a successful query() statement, it would appear to you that doing this and using an if(){} are the same. however, as @Barand has posted, using an if(){} conditional around the query() code insures that the // do something code is only executed if the query() was successful. the problem with this is that nothing is done for the case where the query failed and in most cases a failed query is a fatal problem, due to a programming mistake. in this case, when learning, developing, and debugging, you would like the raw database error information to be displayed, so that you have immediate feedback as to if and why the query statement failed (when running this code on a live/public server, you would like this information to be logged instead.) the simple way of accomplishing this, without adding even more code at each database statement that can fail or editing/removing code when moving between development and a live server, 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 'automatically' get displayed/logged the same as php errors.) you can then remove any existing error handling logic for database statements as it will no longer get executed upon an error (execution transfers to the nearest correct type of exception handling upon an error.) your main code only has to deal with error free database statement execution, simplifying the code. if you want to do this, someone can post the statement that will set the mysqli error mode to use exceptions.
-
Splitting multidimensional array based on values
mac_gyver replied to 684425's topic in PHP Coding Help
example - <?php // index/pivot the data // note: if you are using the PDO extension, there's a fetch mode that will do this for you $data = []; while($row = whatever_fetch_statement_you_are_using) { $data[ $row['status_id'] ][] = $row; } // define output heading information $headings = []; $headings[1] = ['label'=>'Heading for status id 1 section']; $headings[2] = ['label'=>'Heading for status id 2 section']; // produce the output foreach($headings as $key=>$arr) { // start a new section echo "<h3>{$arr['label']}</h3>"; if(!isset($data[$key])) { echo "<p>NO DATA</p>"; } else { foreach($data[$key] as $row) { // reference elements in $row to produce the output... echo '<pre>'; print_r($row); echo '</pre>'; } } // any code needed to finish a section goes here... } -
Splitting multidimensional array based on values
mac_gyver replied to 684425's topic in PHP Coding Help
you would need to post the offending code to get the most direct help with what is wrong with it. however, you can probably solve this by indexing/pivoting the data, using the status_id value as the index, when you retrieve it. this will give you zero, one, or two sub-arrays of rows of matching data, depending on if there was no data at all, data for one or the other status_id value, or for both status_id values. you can then test/loop over the indexed/pivoted data to produce the output for none, one, the other, or both status_id values. -
apparently the INSERT part of the query is failing for these new rows. do you have any error handling for the database statements so that you would know if and why they are failing? temporarily add the following to your code to get php to report and display all errors, including database statement errors - // report all php errors error_reporting(-1); // display any reported errors ini_set('display_errors', '1'); // use exceptions for mysqli errors, which php will then report and display via an uncaught exception mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
-
PHP session randomly dying (Nginx)
mac_gyver replied to tonyfriz's topic in PHP Installation and Configuration
are there any ajax requests being made to a page that is also using session variables? what if any is the 'logout' code? can the logout code be reached by any other code not die'ing after a redirect? the quickest way of eliminating a lot of guessing is to just post the code, so that the problem can be narrowed down to just a few things that can be investigated further. -
you are either getting a fatal php syntax/parse error or a fatal run-time error. for both of these, get php to help you by finding the php.ini that php is using and set error_reporting to E_ALL and display_errors to ON, so that php will report and display all the errors it detects. stop and start your web server to insure any changes made to the php.ini take effect and use a phpinfo() statement in a .php script file to confirm that the settings took effect.
-
we don't know what your standard is for working or not working. you must tell or show what result you did get that leads you to believe that something didn't work.
-
is this code doing anything else with the submitted values beyond building the hidden fields in the form? btw - the sqTotal field being repeatedly output is pointless. it should just be output once, after the end of the looping, and i would even venture to guess that it is not needed anyways.
-
the code is blindly looping over 100 possible values, without testing if they exist before referencing them. this error was always occurring, but was probably not being reported or displayed. you should use an array for the form field, with the array index being the 0-99 value. this will eliminate the need for the logic to take the $_POST[sqNum_xx] value and put it into $SQarray[xx]. you will already have an array of data from the form that the if ( isset($SQarray[$i]) ) { can test and use.