-
Posts
5,450 -
Joined
-
Days Won
175
Everything posted by mac_gyver
-
prepared queries provide fool-proof protection against sql special characters in a data value breaking the sql query syntax, which is how sql injection is accomplished. you are already using prepared queries with the mysqli extension. however, as stated, the PDO extension is much simpler and more consistent. for the SELECT query that's getting the current user's row of data, this what it looks like using mysqli (with the if(){} and ->close() removed) - $stmt = $con->prepare("SELECT userbalance, totaleventjoined, totalpifcoingained, totaldonationdc, userlevel, userexperience FROM accounts WHERE id = ?"); $stmt->bind_param('i', $_SESSION['id']); $stmt->execute(); $stmt->bind_result($userbalance, $totaleventjoined, $totalpifcoingained, $totaldonationdc, $userlevel, $userexperience); $stmt->fetch(); and here's what that looks like using PDO - $stmt = $pdo->prepare("SELECT userbalance, totaleventjoined, totalpifcoingained, totaldonationdc, userlevel, userexperience FROM accounts WHERE id = ?"); $stmt->execute([ $_SESSION['id'] ]); $user_data = $stmt->fetch(); there's no need for explicit binding of inputs or for the result. you can directly fetch data from a prepared PDO query exactly the same as for a non-prepared query.
-
i suspect you are asking this because your code and variables aren't behaving the way you expect? the reason most of your conditional tests are not working and variables are being changed, is because one = is an assignment operator and two == is a comparison operator. when you have a statement like - if($donationclash = false), this assigns false to the variable, then tests the result, which will be a false value. all these conditional tests against variables should use two ==. if($donationclash == false), this tests if the variable is equal to a false value and leaves the value in the variable as is. a comment about the use of the $donationclash variable throughout this code. since your program logic is halting execution if the $DONATIONCLASHTIME is false, there's no point in the $donationclash variable at all. all the rest of the code on the page after the $DONATIONCLASHTIME test and its message won't be executed. here's a list of issues with the current code - there are no helpful comments in the code describing what the goal of each section is. this makes it almost impossible for anyone to help with your code. switch to the much simpler and more consistent PDO database extension. it treats the result of a non-prepared and a prepared query identically. this alone will eliminate about half of the code dealing with database queries. don't copy variables to other variables for nothing. just use the original variables. this accounts for close to half of the existing lines of code. this is just a waste of typing and is making more work for you in keeping track of everything and makes it almost impossible for anyone to help. don't use multiple names for the same thing. this requires you to keep track of which name you are using and makes it next to impossible for someone to help. use under scores _ to separate the words making up names of things. make the database connection in an initialization section at the top of your code and don't repeatedly require (once) the connection file. only store the user's id in session variable, named user_id or similar, to indicate who the logged in user is. this will either be set or it won't. query on each page request to get any other user information, such as the username, permissions, ... you have mistakes in most of the if() comparisons. one = is an assignment operator. two == is a comparison operator. there are other logic mistakes with what the else and else if logic is doing, that would be easier to see if you consistently indent your code. use 'require' for things that your code must have for it to work. include/require are not functions. the () around the value does nothing but clutter up your code with unnecessary typing. be consistent. you are using include/require_once and echo/print at different points. don't use a loop to fetch data from a query that will match at most one row of data. just fetch the single row of data. why do you have an if() around the prepare() calls? you don't do anything if they fail and since the execute() calls can fail, why don't you have conditional tests for them too? instead of writing out conditional logic for each database statement that can fail, use exceptions for errors and in most cases simply let php catch and handle any database exception, simplifying the code. the only time your code should catch and handle a database statement error/exception is for user recoverable errors, such as when inserting/updating duplicate or out of range user submitted data. in all other cases, don't put any logic in your code and simply let php catch and handle the error/exception. build sql query statements in php variables. this will make testing easier and help to eliminate typo mistakes by separating the sql query syntax as much as possible from the php syntax. you should always fetch all the data that a query returns, which is why you went to the trouble of executing a query in the first place, so there should not be any case where you need to close a prepared query. don't store redundant data in multiple locations. you are storing the user's id in the donationclashdetails. that's all the user information you need. you can get any other user information via the user's id. any one conditional test can either be true or false. you don't need test for the false case after you have tested for the true case. if a test is not true, it must be false. the $stmt->store_result() and $stmt->bind_result() after the INSERT query don't belong there and may be producing errors. do you have php's error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini on your system, so that php will help you by reporting and displaying all the errors it detects? the SELECT ... FROM donationclashdetails WHERE participationid = ? query, right after the INSERT query, and the associated repetitive logic, is unnecessary. the php 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 post method form processing should - detect if a post method form was submitted, which you are doing. however, all the form processing code goes inside this conditional block of code. yours isn't. keep the form data as a set, in an array variable, then operate on elements in this array throughout the rest of the code trim all the inputs at once validate all inputs, storing validation errors in an array using the field name as the array index after the end of the validation logic, if there are no errors (the array holding the errors will be empty), use the submitted form data after the end of the form processing logic, if there are no errors, perform a redirect to the exact same url of the current page to cause a get request. this will prevent the browser from trying to resubmit the form data to display a one-time success message, store it in a session variable, then test, display, and clear the variable at the appropriate location in the html document. if there are errors at step #5, the code will continue on to (re)display the html document. you would test/display any errors and redisplay the form, populating the field value(s) with any existing data. apply htmlentities() to any dynamic value when you output it in a html context
-
there are countless examples of forms and php form to database scripts on the web for you to find and examine to see how others have accomplished this. however, seeing something and reproducing it with your data isn't teaching you the meaning of what you are doing, which will leave you unable to find and fix problems or write original code that does something new. you must actually learn enough of the fundamentals of the languages you are using so that you can write (and read) the words and syntax, before you are able to write a complete application. most people have a first and a last name and unless they are dead, their age changes once a year on their birthday. you would actually need three columns - first name, last name, and date of birth (calculate the age when needed.) web based applications must - be secure, in all contexts. in a database context, use prepared queries. in a html context, apply htmlentities() to values when they are being output. provide a good User eXperience (UX.) provide clear prompts and instructions and tell the user specifically what is wrong with each data value that they submitted. use simple, maintainable code. you will find a lot of code examples on the web are filled with copying of variables to other variables for nothing and a lot of other unnecessary typing of things that don't actually contribute to the goal of producing an application. if it seems like you are doing a lot of repetitive typing and not getting anywhere, there's probably a simpler way of accomplishing the same task. have enough validation and error handling so that they will either work or will tell you why they don't. a lot of the code examples you will find are missing needed features, may work under perfect conditions, but will fail and won't tell you why when anything unexpected occurs. be prepared to do a lot of work making the minimal examples found into complete web based applications and doing comprehensive testing to insure that your code/query(ies) behave in an expected way for all possible inputs.
-
a general-purpose data-driven design doesn't use a separate discreate variable for each field. it keeps the data as a set, in an array, then dynamically operates on the elements in the array using general-purpose code.
-
if you are writing functions that contain application specific values/variables, such that you are constantly editing existing or creating new functions, this is a sign that your function code is not general-purpose, has the wrong responsibility, is actually part of your main code, and should not be inside of a function. you shouldn't be writing out bespoke lists of variables for each different form you are processing. you should be using a data-driven design, where you have a data structure (database table, array) that defines the expected fields, validation rules, and processing for each form. you would then loop over the correct definition that matches the submitted form and use general-purpose logic to validate and process the form data.
-
Php cookies and session data expiring at different times
mac_gyver replied to oz11's topic in PHP Coding Help
do not store any user information in cookies. anyone can set cookies to any value and can impersonate a user. to do what you are asking, generate a unique token, store the token in a cookie and store it in a row in a 'remember me' database table, along with the user's id and things like when the remember me was set and when you want it to expire if not regenerated. if you receive a cookie containing a token, query to get the user's id and the expire datetime to determine if the token is valid. if it is, set the normal session user_id variable to indicate who the logged in user is. you should only store the user id in a session variable, then query on each page request to get any other user information, such as the username, permissions,... this will insure that an change/edit in this user information will take effect on the very next page request. -
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.
-
the search box is part of the jquery datatables. is the jquery datatable js code loading? are there errors in the browser's developer console? why are you trying to load the jquery datatable js code three times on the page that doesn't work? i'll restate this more directly, if you have coded a web page properly, to change the styling of that web page, you should only need to change the css that gets used. if you are editing the rest of the code on the page, you are doing something wrong.
-
Updated Data Not Shown on PHP Page But the MySQL DB Is Updated
mac_gyver replied to Alans's topic in MySQL Help
is your code even using session variables? at this point, you are the only person here who knows specifically what your code requires for it to produce the correct output. we could offer a dozen different guesses, but your code could be doing a 13th or 14th... thing that no one thought to mention because they could not see what your code is dependent upon for it to work. the only thing i can recommend based on the non-specific information provided is you need to put your form and form processing code on the same page so that the code is easier to secure, provides a good user experience, is simple, and has a better chance of working or telling you why it doesn't. the only redirect you should have is upon successful completion of the post method form processing code and it should be to the exact same url of the current page to cause a get request for that page, so that the browser won't attempt to resubmit the form data. -
Updated Data Not Shown on PHP Page But the MySQL DB Is Updated
mac_gyver replied to Alans's topic in MySQL Help
cannot possibly help you without having all the code needed to reproduce the problem. i'm going to guess session data is involved and you are switching between http and https requests, which will result in two separate sessions. -
do you have an actual example you are trying to make work? well written functions accept all input data as call-time parameters and return the result they produce to the calling code.
-
continuation from above, after you have determined that there is data in $_FILES, you must test the ['error'] element. a zero (UPLOAD_ERR_OK) means that the file was successfully upload and the data in the other elements can be used. a 4 (UPLOAD_ERR_NO_FILE) means that no file was selected. for the other possible errors, which are listed in the php documentation, some are under the control of the user and some are not. for those that the user can affect, you need to setup a specific message telling the user what is wrong. for the other errors, setup a general failure message and log all the information about the actual error that occurred, so that you can find and fix what's causing the problem.
-
you actually need to find out why it is not defined, why that conditional code is not being executed, not just attempt to make the undefined error go-away. your logic requires $_POST to be not empty and the file extension to pass the in_array() call. for debugging use print_r(), before the existing !empty($_POST) conditional statement, on one or both $_POST/$_FILES to see what they are. if the total size of the form data exceeds the post_max_size setting, both the $_POST and $_FILES arrays will be empty. your form processing code MUST first detect if a post method form was submitted, then detect if there is or is not $_POST/$_FILES data, before using any of the uploaded file information. if there is not, you need to setup a message for the user that the total size of the form data is too large and could not be processed. another server-side reason why uploads can fail, of any size, is if uploads are not enabled on the server.
-
just to summarize the operational problem - you are using code that is trying * to do datetime comparisons, with the file value only having a date part, and is ending up with the current time as the time part. * - when comparing the datetime objects directly, the d/m/Y formatted values won't be properly compared by magnitude. if you want to just do a date comparison, you must operate on values that all only contain date parts. if you want to do a datetime comparison, you must also have the time of the uploaded file.
-
if you store the dates using a DATE or DATETIME datatype, you can do this all in the query. the only looping would be to produce the output from the records that the query matches. what you are currently doing will take longer and longer as more files get uploaded, because you are fetching all the data and looping over it to find the matching entries.
-
put all this code on one page. you are creating more work for yourself creating multiple pages, when one page is all you need. the following is an outline of the code that would do this for you - <?php // initialization $connect =odbc_connect("removed"); if(!$connect) { exit("Connection Failed: " . $connect); } // note: don't tell hackers or other visitors to your site that a connection error occurred // also, $connect is a false value in this case and outputting it won't show anything // when learning, developing, and debugging, you should display database statement errors // when on a live/public server, you should log database statement errors // regardless of which database server type you are using, switching to the more modern PDO extension will allow you to easily do this, by using exceptions for errors and in most cases simply let php catch and handle the exception for you // post method form processing - none // get method business logic - get/produce data needed to display the page // get job data, for producing search checkboxes $sql=" select jmpjobid,jmpPartID,jmpProductionQuantity from M1_KF.dbo.jobs where jmpProductionComplete!=-1 order by jmpPartID "; $job_result = odbc_exec($connect,$sql); if(!$job_result){ exit("Error in SQL"); } // same comments as above about displaying/logging database statement errors // i recommend that you pre-fetch the data from any select query into an appropriately named php variable, // then test/use that variable in the html document // this moves the database specific code out of the html document // apparently the main data retrieval query 'requires' a job id search input? // if so, it needs to be conditionally executed based on a non-empty search if(isset($_GET['job'])) { // at least one checkbox is checked - assuming no programming mistake or nefarious activity $ph = implode(',',array_fill(0,count($_GET['job']),'?')); $sql = "SELECT ... WHERE jmmjobid IN ($ph)"; // put the full query here... $data_result = odbc_prepare($connect, $sql); odbc_execute($data_result, $_GET['job']); // you can use odbc_fetch_row/odbc_result to loop/fetch the result from this query // wondering if odbc_fetch_array is present for the database server type // also, switching the more modern PDO extension will make fetching data easier } // html document ?> <?php // output the search form if(empty($job_result)) { echo "<p>No Job data to search amongst</p>"; } else { ?> <form> <table> <tr> <th>Job</th> <th> </th> <th>Part</th> <th> </th> <th>Qty</th> </tr> <?php while(odbc_fetch_row($job_result)) { $job=odbc_result($job_result,"jmpjobid"); $Item=odbc_result($job_result,"jmpPartID"); $Qty=odbc_result($job_result,"jmpProductionQuantity"); $rQty=round($Qty, 0); // pre-check any existing choices $chk = isset($_GET['job']) && in_array($job,$_GET['job']) ? 'checked' : ''; echo"<tr>"; echo"<td><input type='checkbox' name='job[]' value='$job' $chk>$job</td>"; echo"<td> ◃</td>"; echo "<td>$Item</td>"; echo "<td> ▹ </td>"; echo "<td>$rQty</td></tr>"; } ?> </table> <input type='submit' value='Submit the form'> <form> <?php } ?> <?php // output the search result if(!isset($_GET['job'])) { echo "<p>Please select Job Id(s)</p>"; } else { if(empty($data_result)) { echo "<p>Search did not match any data</p>"; } else { ?> <?php while(odbc_fetch_row($data_result)) { } ?> <?php } } ?>
-
for an arbitrary string, you should use a prepared query. what's the actual database server type, in case it has an easy to use function that would allow a prepared query with a single input parameter instead of a separate one for each parameter? this is a search function, the form should be a get method form, it should be 'sticky' and remember any previous choices, and it should be on the same page as the form processing code.
-
Different behavior between hosting, and local
mac_gyver replied to KillGorack's topic in PHP Coding Help
i played with this some, and the session_name should only contain alphanumeric characters. for the value shown, no session was started. i suspect that on the host where this 'doesn't fail', a session has already been started, the posted code actually does nothing, but php's error related settings are not setup to display/log errors that would be alerting you to the problem. -
Different behavior between hosting, and local
mac_gyver replied to KillGorack's topic in PHP Coding Help
-
Different behavior between hosting, and local
mac_gyver replied to KillGorack's topic in PHP Coding Help
are you making a https request on your localhost system? -
there are existing javascript data-table 'widgets' that will let you click on a heading and sort the rows in a html table for you. if you want to do this yourself, by getting the data from the server-side code, you will need to use ajax. you would have a clickable element in the markup. when clicked it will trigger some javascript code that will make an ajax request to the server-side code, get the data in the order that you want it, build the markup for the tbody part of the table, then replace the existing markup with the new.
-
Couple separated images insert and displaying them in table
mac_gyver replied to idan's topic in PHP Coding Help
your code is displaying the same image, the last one, for all the images, because you are saving each image using only the file extension as the file name, so, assuming they are something.jpg, somethingelse.jpg, ... all the saved files are named jpg, they are overwriting each one when they are saved. you need to save the files with a unique filename.ext that doesn't repeat (and overwrite) any existing file. a simple way of doing this is to insert the row of data, get the last insert id from the query, and use the last insert id as part of the filenames - id.pcontract.jpg, id.passport.jpg the id column you are inserting, from the $_POST['id'] value, what is that? in database designs, you should have autoincrement primary index columns that generate ids that are used for relational data storage and when referencing specific rows of data. -
if you are dynamically adding form fields, you should probably be using an array name for the fields, so that you will get an array of submitted data from the set of fields.
-
you are appending the dynamically created field to the document body, not to the form. i recommend that you do two things - instead of building the markup, line by line, attribute by attribute, put the desired markup inside a <div id='template'>...</div>. you can then just copy the innerHTML from this template element to crate each new element. put another <div id='target'></div> inside the form where you want to append the dynamically created elements. the javascript would them look like this - // create an empty div element var divx = document.createElement('div'); // get the template html and put it into the empty div divx.innerHTML = document.getElementById('template').innerHTML; // append the new div to the target area on the page document.getElementById('target').appendChild(divx);