Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,450
  • Joined

  • Days Won

    175

Everything posted by mac_gyver

  1. the limitation is probably in the get or set session methods or in the code displaying or processing the cart. this code is overly complicated. the only data that should be stored in the cart is the quantity and the item id (itemCode) should be used as the cart's array index. once you index the data using the id, you can directly find, test, or reference the data. no looping required. the following is the only code needed to add an item to the cart once you do this - // add to cart code if(!isset($cartItems[$_POST['ItemCode']])) { // if an item isn't in the cart, add it with zero quantity $cartItems[$_POST['ItemCode']] = 0; } // add the submitted quaitity to the cart $cartItems[$_POST['ItemCode']] += $_POST["ItemQty"];
  2. i also recommend the much simpler and more modern PDO extension. you can directly fetch data from a prepared query, the same as how you would fetch it for a non-prepared query. if you are going to use the mysqli extension, forget about mysqli_int/mysqli_stmt_prepare. just use mysqli_prepare(). also, forget about the num_rows property. just fetch the data and test if there was any fetched data. if you are querying to find a row of data matching an (active) user, you would not include the password comparison in the WHERE ... term. also, you should be using php's password_hash() and password_verify() for password hashing. php finally realized the it should use exceptions for errors for things like database statement errors. as of php8, the mysqli (and PDO) connection, query, exec, prepare, and execute calls throw exceptions for errors. this means that any conditional error handling logic you have for these statements can be removed since they won't ever get executed upon an error, simplifying the code. there's also generally no need to close prepared query handles, free up result sets, or close database connections in your code, since php destroys all resources when your script ends, simplifying the code. pdo version - $sql="SELECT * FROM users WHERE username=? AND active=1"; $stmt = $pdo->prepare($sql); $stmt->execute([ $uname ]); if($user_data = $stmt->fetch()) { // a row was found // you can reference elements in $user_data, such as $user_data['id'], $user_data['added'], ... } else { // no row was found }
  3. you would explode the search term on the space characters, then dynamically build an expression for each word, that get ORed together to build the WHERE ... term. you need to use a prepared query, so that nothing in a value can break the sql query syntax, which is how sql injection is accomplished.
  4. forget the word sanitize when dealing with data. also forget about using stripslashes(). when it was needed, it was conditionally applied. the need to do this was removed from php long ago. other than trimming user submitted data, mainly so that you can detect if a value is all white-space characters, you should NOT modify data. you should validate the data to make sure that it meets the business needs of your application. is a required value not empty. is a value that must have a specific format, character range, length, or magnitude valid? if it's valid, use it. if it isn't valid, let the user know what was wrong with it, let them fix it, and resubmit it. security is accomplished by using the data correctly in whatever context it is being used in, e.g. sql, html, mail header, ... in a html context (web page, email body), apply htmlentities/htmlspecialchars to a value right before outputting it, to help prevent cross site scripting.
  5. 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? are you using php8+, where exceptions are the default setting for database statement errors, or if using < php8, have you enabled exceptions for errors for the database extension you are using? when your code/data doesn't work, you need to find at what point they are doing what you expect and at what point they are not. the problem lies between those two points. if all you have done is run your code and notice that it doesn't insert the expected data, you haven't narrowed down the problem to a single line of code. you need to use debugging techniques, such as using var_dump() on data, to both determine which exaction path your code is taking and what data values it is using, to find out exactly where your code/data stops doing what you expect. well written code, with sufficient error handling and validation logic, should either work or it should tell you (display/log) why it doesn't work. every data validation error should get handled. your if (Token::check(Input::get('token'))) validation doesn't do anything if the token check is a false value, indicating either a programming mistake or someone/something hasn't visited/requested the form to generate a token. you need to add an else conditional branch to display (during development) or log (when on a live server) relevant information when this occurs. finally, you have some problems in the posted form/form processing - your user ->create() method is using a surname field, that doesn't exist in the form your form has a status field, that isn't being used if you want the user to be required to make a specific choice for the status field, the first <option ...> needs to be a prompt to make a choice, with an empty value attribute the email field is not being validated both the username and email fields must be defined as unique indexes in the database table. you must then have exception error handling for the insert query that tests for a duplicate index error (number), determines which or both of the submitted values where duplicates, and sets up user error(s) for the duplicate values. the foreach() loop displaying the validation errors, is concatenating each error onto the existing $response. when there is more than one error, the $response will get echoed multiple times, with a growing number of errors in it. i recommend that you just implode() the array of errors using a '<br>' tag and output the result. the form is submitting to insert/user.php. that doesn't correspond to the filename of the posted code.
  6. when using named prepared query place-holders, the name must match between what you use in the sql query and the binding. in your code, they don't. e.g. :LogID is not the same as :LOGIN_ID. ... i recommend that you use simple positional ? place-holders. there's less to type and keep track of. regardless of the place-holder type, you can simply supply an array of the input values to the ->execute([...]) call, saving more typing. you should not manage the id value yourself in code. this is not concurrent safe. instead, use an autoincrement primary index. the database engine will perform the necessary table locking to insure that concurrent queries will generate unique values. your database must enforce uniqueness, it is the last step in the process. the username column must be defined as a unique index. you would then attempt to insert a row of data, and test in the exception handling catch block for that query if an duplicate index error (number) occurred. if it did, setup a message for the user letting them know that the username is already in use. for all other error numbers, rethrow the exception and let php handle it. there's also nothing to fetch from an insert query. why are you doing that?
  7. what does the 'view source' of the page in the browser show? do any other .php pages work? either the code starts with a short-opening php tag <? or php isn't working on the web server.
  8. let's start at the beginning. why was your account moved to a different server? next, you need to create a .php script file with a phpinfo(); statement in it, e.g. <?php phpinfo(); ?> , in your document root folder, and browse to the URL of this file, e.g. https//your_domain.com/the_file_you_just_created.php in the resulting web page, you/we need to know what is shown for the Loaded Configuration File setting and the session.save_path setting (both the local and master values.)
  9. the session.save_path setting in the php.ini is pointing to a now non-existent/non-accessible folder. you need to see of there is already an appropriate folder within your account's directory tree /home/rgxb6tc5wk5q/... for session data files and set the session.save_path setting to point to it, and if a folder doesn't exist, create it and set the session.save_path setting to point to it. when your account was created/moved they should have had templates setup to do this automatically.
  10. i recommend that you make a new file with the code necessary to load the phpmailer script and with your sendEmailNotification() function in it, setup some test data, and call the sendEmailNotification() function and get the email to work. once you get the email to work on its own, then make sure that your full code is actually calling the sendEmailNotification() function, by echoing/logging a value at the completion of the email code. you are performing a redirect right after the INSERT query. it's possible that the sms code will take enough time to make the curl request that the browser can abort the current request and halt code execution before your code gets to the email code. it's also possible that the curl code is throwing an error and your code never gets to the email code. any such redirect needs to be at the end of the post method form processing code, it should only occur if there are no user/validation errors, and it should be to the exact same URL of the current page to cause a get request for that page. here's a list of things that will simplify the code, making it easier to see what the code is trying to do - you should only catch and handle database exceptions for user recoverable errors, such as when inserting/updating duplicate user submitted data. for all other insert/update query error numbers, just rethrow the exception and let php handle it and for all other type of queries, let php catch and handle any database exception. for the INSERT query you should be catching and testing for a duplicate index error number. if an applicant can only register once, the applicant_id column should be defined as a unique index, so that only one record per applicant_id can be inserted. if an applicant can only register for a single exam_date_id, the combined applicant_id and exam_date_id columns need to be defined as a composite unique index. if you set the default fetch mode to assoc when you make the database connection, you won't have to specify it in each fetch statement. don't copy variables to other variables for nothing. just use the original variables that data is in.
  11. if you use this, you must specifically set the request header, between the .open() and .send() calls - xhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); If the only POST method request made to the page will be via an ajax request, then simply testing for a post method request will work. all data submitted to your site can come from anywhere, not just your form, links, cookies, ajax requests, ..., can be set to anything, and cannot be trusted. you must validate all input data to make sure it meets the business needs of your application and use all data securely in whatever context it is being used in.
  12. provided the code for the page is 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 end of item #2, if the request was an AJAX request, you would build and output the response to the ajax request, then exit/die, so that the rest of the code on the page isn't executed. here's a snippet of code to detect an AJAX request - define('IS_AJAX_REQUEST', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); you can then conditionally run AJAX request only code using - if(IS_AJAX_REQUEST) { // build and output the response to the AJAX request // typeically json_encode([some meaningful error or success data]); // stop php code execution die; }
  13. where are you getting $value from and how are you building the SELECT ... list in the data query? if they are in the same order, you don't need to do anything else, the rows of fetched data will match the csv columns/headings in $value.
  14. you likely have a single ...fetch() statement somewhere between where you have executed the sql query and the code you did post. btw - the mysql_ extension has been removed from php for a very long time. you should both update your php version to 8+ and switch to the PDO extension.
  15. except, that's only the last field definition, not all of them, because you are reassigning $fieldSelection each pass through the loop. you want to add a new array entry to $fieldSelection each pass through the loop. you have a typo/spelling mistake in the :fieldSection place-holder in the sql vs :fieldSelection in the execute() call.
  16. if you name the sets of fields differently, with the same root name, an incrementing numerical index, then the element name, the submitted data will already be in a format that you can json_encode(). assuming these are all text fields, the markup would look like - <input type='text' name='fieldSelection[0][field]'> <input type='text' name='fieldSelection[0][fieldName]'> <input type='text' name='fieldSelection[0][fieldLabel]'> <input type='text' name='fieldSelection[0][fieldType]'> <input type='text' name='fieldSelection[0][fieldWidth]'> <input type='text' name='fieldSelection[1][field]'> <input type='text' name='fieldSelection[1][fieldName]'> <input type='text' name='fieldSelection[1][fieldLabel]'> <input type='text' name='fieldSelection[1][fieldType]'> <input type='text' name='fieldSelection[1][fieldWidth]'> you can then simply loop over $_POST['fieldSelection'] and use each set of values - foreach($_POST['fieldSelection'] as $row) { echo '<pre>'; print_r($row); echo '</pre>'; echo json_encode($row); echo '<br>'; }
  17. OR you can use the complement - select count(*) as CustomerActual, Month from sbms.customerdata WHERE EmpID='83201858' AND (VisitType = 'No Due' OR VisitDate !='') group by Month
  18. yes, for any dynamic value that is output in a html context (web page, email), if it could contain html entities (html, css, javascript.) here's a story about SMF (Simple Machines Forum) software. their programmers didn't apply htmlentities() to some user profile data when it was output on a web page. when administrators viewed the profiles of user's who had their posts reported in the 'administrator' area on the site, javascript in the data was executed, performing any action that the administrator is capable of, and was promoting the bad users to be administrators. SMF sent out an emergency email to everyone who had ever registered on their site to immediately update the SMF software to close this security hole. no. didn't you just ask that in a thread? where is your $data array coming from? arrays are for sets of data, where you will operate on every member in the set in the same/similar way. by keeping data as an array, you can operate on the data using php array functions - https://www.php.net/manual/en/ref.array.php the submitted form data is a set, originally in the $_POST array. you should trim the data in it, mainly so that you can detect if any value is all white-space characters, before validating it. since the trimmed data has a different meaning from the original and since you should leave the original data as is, in case you need it, you should put the trimmed data in a different array variable, such as $data. because it is a set, you can operate on it using php array functions. to trim all the data at once: $data = array_map('trim',$_POST). the existing data you are going to edit is also a set. when you fetch it, keep it in an array variable, such as $data, which is what everyone reading this thread assumed you are doing with the $data array you have shown in this code. user/validation errors are also a set of data. your validation logic should add user/validation errors to an array using the form field name as the array index. you can then test if there are or are not any errors, simply by testing if the array holding the errors is !empty(...) or is empty(...). you can output the error messages all at once, either by imploding the array or looping over it. you can output the error messages individually, such as placing them next to the correspond form field, by referencing the array index, which is the form field name. keeping these sets of data as arrays will allow you to use a data-driven design to dynamically validate and process the data, and dynamically produce the form. the example i showed is functionally what template engines do. you have an array of data and a template with tags in it corresponding to the array indexes. when you tell the template engine to render the template, it replaces the tags with the same name elements from the array of data, applying htmlentities() to each value (there's a special tag syntax to override this if you must use the raw data.)
  19. you also need to repopulate the value (selected options, checked checkbox/radio fields) in the case of adding/creating/inserting new data when there are user/validation errors, so that the user doesn't need to keep reentering data over and over. you also need to apply htmlentities() to the value to help prevent cross site scripting. if you switch from echoing mostly static html to just echoing the dynamic value, you would end up with something that looks like this - <div class='col-12'> <label>Form Name <input type='text' class='form-control' name='formName' value='<?=htmlentities($data['formName']??'',ENT_QUOTES)?>'></label> </div> also, stop copying variables to other variables (just use the original variable that data is in) and you can eliminate the for='' and corresponding id='' attributes if you put the closing </label> tag after the field it corresponds with.
  20. not really. you are doing the same operation, only the name/meaning of the data is different. you should have a booking/reservation/order table, that holds the unique/one-time booking data. a single row is inserted into this table when someone submits an order. this row produces a booking id (the autoincrement primary index.) you would use this booking id to store the related booking item data, one row per item, which in this case is the seat id, screening id, ...
  21. to get php to cause a http 500 status for fatal syntax/runtime errors, php's display_errors setting needs to be set to OFF. you would then want the log_errors setting to be set to ON, so that you have a record of what errors are occurring. also, php's error_reporting needs to always be set to E_ALL or a -1.
  22. what is your overall goal here? OOP is not about wrapping your main code in class(es), adding $var-> in front of everything, and making a wall of code that takes 10x the number of lines of code to accomplish a task.
  23. are you doing this as a learning exercise? what is your goal? some pointers - the code for any page should be laid out in this general order - 1) initialization, 2) post method form processing, 3) get method business logic - get/produce data needed to display the page, 4) html document. the post method form processing should not attempt to detect if the submit button is set, there are cases where it won't be. instead, detect if a post method form was submitted before referencing any of the form data. keep all the form data as a set, in a php array variable, then operate on elements in this array variable throughout the rest of the code. trim all the input data before validating it, mainly so that you can detect if all white-space characters were entered. validate all the trimmed input data at once, storing user/validation errors in an array, using the field name as the main array index. after the end of the validation logic, if there are no errors (the array holding the user/validation errors is empty), use the input data. since all you are doing is comparing an input value with the correct answer, you can do this as part of the validation logic. if you were storing data in a database, authenticating a user, sending an email, ... you would put the code needed to perform these actions here. after using the input data, if there are no errors, perform a redirect to the exact same URL of the current page to cause a get request for the page. this will prevent the browser from trying to resubmit the form data should the page get reloaded or browsed back to. to display a one-time success message, store it in a session variable, then test, display, and clear that session variable at the appropriate location in the html document. if there are user/validation errors, the code will continue on to display the html document, display any errors, redisplay the form, populating the field values with any existing data, so that the user doesn't need to keep reentering values over and over. any dynamic value you output in a html context needs to have htmlentities() applied to it to help prevent cross site scripting. there's a programming issue with the division operator and computers. this operation can result in a fractional part that cannot be represented exactly in a computer and then cannot be easily compared. you may want to test the answer produced is this case and limit the question/answer to those which only have whole integer answers, i.e. keep something like 9/3, but not 7/6, and also don't allow division by 0. if you do all of that, except for handling the division cases, you would end up with code that looks like this - <?php // initialization // the error related settings should be in the php.ini on your system error_reporting(E_ALL); ini_set('display_errors', '1'); session_start(); $post = []; // array to hold a trimmed working copy of the form data $errors = []; // array to hold user/validation errors // post method form processing if($_SERVER['REQUEST_METHOD'] === 'POST') { // inputs: number_entered, $_SESSION['answer'] // trim all the post data at once $post = array_map('trim',$_POST); // if any input is a array, use a recursive trim call-back function here instead of php's trim // validate inputs if($post['number_entered'] === '') { $errors['number_entered'] = 'You must enter a number'; } // note: this assumes that only integer answers are permitted (in the case of the division operator) else if((int)$post['number_entered'] !== (int)$_SESSION['answer']) { $errors['number_entered'] = "Incorrect guess<br>The correct<br>number was <b>{$_SESSION['answer']}</b> <br><img src='sorry-tryagain.png'><br>"; // since you are displaying the correct answer, you would want to generated a new question in this case? //unset($_SESSION['question']); } // if no errors, success if(empty($errors)) { $_SESSION['success_message'] = "<img src='you-win.png'><br><b>{$_SESSION['answer']}</b> IS THE<br>CORRECT GUESS!</b><br>"; // to continue, you would generated a new question //unset($_SESSION['question']); // redirect to the exact same url of the current page to cause a get request - PRG Post, Redirect, Get. die(header("Refresh:0")); } } // get method business logic - get/produce data needed to display the page // if there's no question/answer, generate one if(!isset($_SESSION['question'])) { $rand1 = rand(0, 9); $rand2 = rand(0, 9); $operator = array('*', '/', '+', '-'); $randoperator = $operator[rand(0, 3)]; switch ($randoperator) { case "+": $finaalvalue = $rand1 + $rand2; break; case "-": $finaalvalue = $rand1 - $rand2; break; case "*": $finaalvalue = $rand1 * $rand2; break; case "/": // note: this can produce a fractional number, which you must take care with when performing comparisons. // also division by zero. $finaalvalue = $rand1 / $rand2; break; } $_SESSION['question'] = "$rand1 $randoperator $rand2 = "; $_SESSION['answer'] = $finaalvalue; } // html document - this is an incomplete document. it only shows the necessary parts for the demonstration. ?> <?php // display any success message if(isset($_SESSION['success_message'])) { echo $_SESSION['success_message']; unset($_SESSION['success_message']); } ?> <?php // display any errors if(!empty($errors)) { echo "<p>".implode('<br>',$errors)."</p>"; } ?> <?php // display the form if(!empty($_SESSION['question'])) { ?> <form method="POST"> <br><b>Level 1<br>Do The Math</b><br><br> <?=$_SESSION['question']?> <input type="text" name="number_entered" value="<?=htmlentities($post['number_entered']??'',ENT_QUOTES)?>" autocomplete="off"><br><br> <input class="button" type="submit" value="Enter Guess"><br><br> </form> <?php }
  24. web servers are stateless. they don't know or care what has happened outside of the current request. each time your code runs, it generates new random values. if you want to remember these values, from one request to the next, you need to store them in session variables, and only generate new ones if the session variables are empty/not-set.
  25. lol. all the javascript posted for this problem is unnecessary. upon the DOM being loaded/rendered, it's getting data that's known at the time of the request for the map2.php page (the value being sent to getBookedSeats.php is coming from a js variable that's being set to a php value echoed on the page.) this is just a roundabout wall of code and data churn. here's a list of why this is not working - 1. you are making a POST request to getBookedSeats.php. the value won't be in any $_GET variable and adding an isset() won't make it work. all that did is hide the problem and caused the php code to be skipped over. 2. you are sending JSON encoded data to getBookedSeats.php. you would need to use the following to read and decode the data - $json = file_get_contents('php://input'); $data = json_decode($json,true); 3. the value will then be in $data['screeningId'], because that's the name of the javascript variable holding the value that you are sending in the ajax fetch request, which is a value that is coming from php in the first place.
×
×
  • 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.