Jump to content

mac_gyver

Staff Alumni
  • Content Count

    4,235
  • Joined

  • Last visited

  • Days Won

    106

mac_gyver last won the day on December 31 2018

mac_gyver had the most liked content!

Community Reputation

440 Excellent

1 Follower

About mac_gyver

  • Rank
    Staff Alumni

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

146,397 profile views
  1. mac_gyver

    display data in two columns bootstrap

    before the start of your html document, query for and retrieve the data you want in the order that you want it, storing the two rows of data in an appropriately named php array variable. loop over the data at the point in your html document where you want to display the content and output the dynamic parts using php code.
  2. mac_gyver

    Help with checking 'balance' after 'wallet'

    you have been given working logic (here and phpbuilder, which i just verified that both work) to test the amount, wallet, and wallet2/balance/earnings (you keep changing what it is called) and to calculate new wallet and wallet2/balance/earnings amounts, yet the code you continue to 'try' is using neither method. are you even reading the replies you are getting? next, in the code i reviewed and added comments to here, there's no logic to get the starting wallet2/balance/earnings value. wouldn't that be a necessary step to get the code to work? btw - your existing code has an UPDATE query at the correct point within the transaction/rollback logic. you would want to use the new wallet and wallet2/balance/earnings amounts in that existing single query, per the comment i added at that point, rather than to start adding more queries before the start of where the transaction/rollback logic starts.
  3. mac_gyver

    Strange query behavior

    your code is probably executing the connection code again, which is recreating the table. it's generally not a good idea to have table deletion/creation queries being unconditionally executed.
  4. mac_gyver

    Help with checking 'balance' after 'wallet'

    no. the u_paid_videos table holds the information about the items(videos) in the order, but it contains redundant data. it has nothing to do with the accounts table i mentioned. everything i stated has to do with database normalization (you can research what that means) and is about properly organizing the data, so that you are only storing the data you need and are not repeating values in multiple places. you are keeping track of two different type of things, 1) information about items/videos that are being purchased (as already stated needs an orders and an order_items table), and 2) user's money/credits. the orders table should have at a minimum, columns for - an id (auto-increment, produces an order_id), user_id (who placed the order), date_time (when the order was placed), and a status column (indicates what state the order is in.) i'm not sure what the session key is, but if it needs to be stored per order it would go in the orders table. the order_items table should have at a minimum, columns for - an id (auto-increment), order_id (what order the item is part of), item_id (the id of the item/video), quantity (this code is just a cart script and in general should support any quantity of an item), purchase_price (the price at the time of purchase), and a status column (indicates the status for each item in the order.) the account table should have at a minimum, columns for - an id (auto-increment), user_id (who the account belongs to), amount (the + or -- amount), transaction_type (wallet, balance), and date_time (when the transaction was made.)
  5. mac_gyver

    PHP Login Logs in but only correct on a refresh

    if you fix what's causing the first error message, the second one will go away. why do you have two session_start() statements?
  6. mac_gyver

    Help with checking 'balance' after 'wallet'

    this code contains no useful comments, making it difficult to determine what it is trying to do, which makes it impossible to make changes to it. the original author, and you as you are making changes to it, should put useful comments in the code that describe what it is doing and why. this is what i think it is trying to do - <?php if(true) // whatever the actual conditional logic is { // get cost video // get the default video price, to use if there is no per video play price $db->where('name', 'video_play_price'); $db_cost = $db->getOne('config'); $video_cost = (float)$db_cost->value; // the number of submitted videos - used to determine if all records were inserted $count_video = count($id_array); $user_id = $user->id; // copy the user id for some reason // values shouldn't have thousands separators stored with them. formatting a number should only be done when it is displayed $wallet = (float)str_replace(',', '', $user->wallet); // add up the video prices $amout = 0; foreach ($id_array as $id) { // assuming this pt_secure function is actual secure, any $id in the following code should use $video_id instead $video_id = (int)PT_Secure($id); // get video data $video = $db->where('id', $id)->getOne(T_VIDEOS); // add the video play price if any, or the default price $amout += $video->video_play_price?$video->video_play_price:$video_cost; } // determine if the user has enough credits // it is here that you would include the balance amount if ($wallet >= $amout) { // you would calculate new wallet and balance amounts $wallet = (string)($wallet - $amout); // insert/update all the following queries as a group $db->startTransaction(); $inserted_records = 0; foreach ($id_array as $id) { // again, all the rest of the code should use $video_id, not $id $video_id = (int)PT_Secure($id); // get video data $video = $db->where('id', $id)->getOne(T_VIDEOS); // use the video play price if any, or the default price $video_cost_new = $video->video_play_price?$video->video_play_price:$video_cost; // add data to paid table $insert_buy = $db->insert('u_paid_videos', [ 'id_user' => $user_id, 'id_video' => $video_id, 'session_key' => $_SESSION['session_key'], 'video_play_price' => (string)$video_cost, // the cost at the time of purchase // this is the default video cost not the $video_cost_new 'video_title' => $video->title, // storing the title is redundant since you can retrieve it from the source video information 'user_id_uploaded' => $video->user_id, // the user who uploaded the video. this is also redundant // this should include the datetime of the purchase - actually there should be a purchase/order table and a purchase/order_items table ]); // count successful inserted records if ($insert_buy) { $inserted_records++; } //update the 'balance' of the user who uploaded the video // get the user's record $userwallet = $db->where('id', $video->user_id)->getOne(T_USERS); // credit the user 50% of the video cost $uploader_amount = $video_cost_new *0.50; // add to the balance $videouserwallet = $userwallet->balance+$uploader_amount; // update the record $db->where('id', $video->user_id); $update_balance = $db->update(T_USERS, [ 'balance' => number_format($videouserwallet, 1, '.', ''), // this is formatting with one decimal point only ]); } // update the current user's wallet (and balance) amounts $db->where('id', $user_id); $update_wallet = $db->update(T_USERS, [ 'wallet' => $wallet, // you would include the new 'balance' too ]); // if all the video records were inserted and the current user's wallet was updated, commit the changes if (($inserted_records == $count_video) && $update_wallet) { $db->commit(); echo json_encode([ 'status' => 200 ]); exit(); } else { $db->rollback(); echo json_encode([ 'status' => 400, 'error' => 'Buy process error' ]); exit(); } } else { echo json_encode([ 'status' => 400, 'error_num' => 1, 'error' => 'Not enough money' ]); exit(); } } else { echo json_encode([ 'status' => 400, 'error' => 'Bad Request, Invalid or missing parameter' ]); exit(); } if i have incorrectly deduced what any of these things are doing, make corrections to the comments before proceeding. if this code had useful comments, so that the meaning of the line of code producing the $video_cost_new value would be in recent memory, there probably wouldn't be a mistake in the pricing value used in the insert query. the following line should use $video_cost_new - 'video_play_price' => (string)$video_cost, // the cost at the time of purchase // this is the default video cost not the $video_cost_new next, the data design has one serious flaw and one that should be corrected - 1) the wallet and balance amounts should NOT be just columns in the user's row that get updated to change the value. by having just a value, you don't have any 'audit trail' should a programming mistake, duplicate form submission, or nefarious access alter a value incorrectly. you should instead have a separate 'account' table that gets a new row inserted for each transaction that affects the amount. this table would have all the who, what, when, where, and why information about each transaction ('wallet' or 'balance' would just be transaction types.) to get the total at any point in time for a user, you would just SUM() the +/- amounts for any particular user id. to get the either or both of the current 'wallet' or 'balance' amounts, you would group by the transaction type for any particular user id. 2) you should actually have two tables to hold the video purchase information. the first table should hold the unique/one-time information about the purchase. this will assign a purchase order id. the second table would hold the unique/one-time information about the items that were purchased, related back to the first table through the order_id. lastly, i put comments in the code where it would need to be modified to do what you are asking. two are near the if ($wallet >= $amout) { conditional test (LOL amount is misspelled in the code.) the last one is in the update query (which should instead be one or two insert queries for the account table) for the current user's wallet (and balance) amounts.
  7. mac_gyver

    PHP Create Not Inserting Into Db And Check If Exists

    here's code (partially tested only) that uses the suggestions above and from the previous thread - <?php //mySQL database config require "config.php"; // Define all variables and initialize them as 'empty' $errors = []; // an array to hold error messages and serves as an error flag $post = []; // an array to hold the trimmed input data // Process data when the form is submitted. if($_SERVER["REQUEST_METHOD"] == "POST") { // assuming the $_POST field names in the original code are accurate, the inputs to this code are - // name, username, password, and password2 $post = array_map('trim',$_POST); // get a trimmed copy of the $_POST data (if any of the form fields are arrays, you need a recursive trim call-back function in this line instead of php's trim() function) //Name check if(empty($post["name"])) { $errors['name'] = "Please enter a name."; } // Validate 'Username' if(empty($post["username"])) { $errors['username'] = "Please enter a Username."; } // Validate Password if(empty($post["password"])) { $errors['password'] = "Please enter a password."; } else { if(strlen($post["password"]) < 6) { $errors['password'] = "Password must have at least 6 characters."; } } // Validate Confirm Password. if(empty($post["password2"])) { $errors['password2'] = "Please confirm your password"; } // check password and confirm password if(empty($errors['password']) && empty($errors['password2']) && $post['password'] != $post['password2']) { $errors['password_confirm'] = "Password and confirmed password do not match."; } // if no validation errors, use the submitted data if(empty($errors)) { $sql = "INSERT INTO users (name, username, password) VALUES (:name, :username, :password)"; $stmt = $pdoConn->prepare($sql); // use a 'local' try/catch to handle errors from this query try { $stmt->execute([ ":name"=>$post['name'], ":username"=>$post['username'], ":password"=>password_hash($post['password'], PASSWORD_DEFAULT) ]); } catch (PDOException $e) { $er=$e->errorInfo(); // get the error information if($er[1] == 1062){ // duplicate key error number $errors['username'] = "The username is already in use."; } else { throw $e; // re-throw the pdoexception if the error is not handled by this logic } } // if no errors, the insert was successful if(empty($errors)) { header("Location: ../index.php"); exit; } } }
  8. mac_gyver

    Php Update Page No Errors Prob Something Small

    the posted form processing code contains a php syntax error, as indicated by the color highlighting stopping. there's no way it is running. only one one of the form field names matches between the php code and the form, so even if the form processing code runs, it is not operating on the correct field names. at a minimum, you need to set php's error_reporting to E_ALL and set it in the php.ini on your system. you can put the setting into your code but since you code never runs when there is a php syntax error, you won't see the error unless the setting is set in the php.ini.
  9. mac_gyver

    PHP Create Not Inserting Into Db And Check If Exists

    to do what you are asking, just make the username column a unique index, forget about the SELECT query, just run the INSERT query, and test if there was a duplicate key error. if there is, it means that the username already exists. this alone will eliminate a 1/4th of the code. in addition to the suggestions already given in a previous thread, this code is filled with unnecessary and repetitive logic, mistyped and non-existent variable names (which is why some of the code isn't running.) you even have a backward logic test that would only run the INSERT query if all the variables are empty. you need to use the simplest and most general purpose code that accomplishes a task. what you are doing now is creating a wall of code which is hiding the mistakes. you have a 'cannot see the forest for the trees' problem. some more suggestions - 1) forget about making discrete variables for every form field and every error. use arrays instead. one for the trimmed input data and one for the errors. 2) trim all the input values at one time. if i/someone has time they will post an example that takes only one line of code. 3) when you validate the inputs, store any error messages in an array. this array is also an error flag. if the array is empty, there are no validation errors. if the array is not empty, there are errors. after all the validation tests, if the array is empty, you can use the submitted data. in your html document, if the array is not empty, display the errors by displaying the contents of the error array. 4) stop creating variables for nothing. in this thread and your other current thread, you have variables that don't exist and typo mistakes in variable names. by using an array to hold a trimmed copy of the input data, then using just this array in the rest of the code, hopefully it will cut down on these type of mistakes.
  10. mac_gyver

    What PHP should i use? PDO

    using the php PDO extension, using prepared queries when supplying external/unknown data to the sql query statement, using implicate binding by supplying an array of the input data to the execute() method call, and using exceptions to handle database statement errors will result in the least amount of code and the simplest sql query syntax. the issue with the ...escape_string() functions is, if the character set that php is using for them isn't the same as the character set of your database table(s), sql special characters in the data can still break the sql query syntax, which is how sql injection is accomplished. by using a true prepared query (PDO has a mode that emulates prepared queries, which should be turned off in most cases), you are guaranteed that nothing in the data will ever been treated as sql syntax. by using a prepared query, you are also simplifying the code since any ...escape_string() functions you may have can be removed. as to the code you have posted above - 1) any trimming of input data would occur before you validate the data and you would never get to the point of preparing/executing the query if the input data is not valid. 2) you should set the default fetch mode to assoc when you make the database connection so that you don't have to specify it in every fetch statement. 3) the rowCount() method is not universally available for SELECT queries for all database types and should be avoided. 4) if you just fetch the data into an appropriately named php variable, using the fetch() method for a single row, or the fetchAll() method for multiple rows, you can test the variable to determine if any row(s) were matched and if you need to get a count of the number of multiple rows, you can use php's count() function. 5) copying the fetched data into discrete variables is a waste of typing time and memory. the original variable you fetched the data into is perfectly fine to use in the rest of the code. 6) using a ? place-holder is shorter/simpler/less typing. 7) you should list out the columns you are selecting. this helps to document what you are doing and causes only the data you want to be retrieved. using these suggestions, your two examples simply become - $sql = "SELECT id, name, language, date FROM users WHERE id = ?"; $stmt = $pdoConnect->prepare($sql); $stmt->execute([$param_id]); $user_row = $stmt->fetch(); // if $user_row is a boolean true, the query matched a row. if it is a boolean false, the query did not match a row. // access the id, name, language, and date elements in $user_row. $sql = "SELECT id, name, language, date FROM users"; $stmt = $pdoConnect->query($sql); $user_rows = $stmt->fetchAll(); // if $user_rows is a boolean true, the query matched at least one row. if it is a boolean false, the query did not match any row(s). // you can use a foreach(){} loop to loop over $user_rows to reference each row of data
  11. mac_gyver

    [Bao Kim]Saving data from all text boxes in one click

    use an array for the form field name, with the id as the array index - <input type='text' name='utilTextbox[1]'> <input type='text' name='utilTextbox[2]'> ... when the form is submitted, you can loop over the array of data to get the id and the value - foreach($_POST['utilTextbox'] as $id=>$value) { echo "id: $id, value: $value<br>"; }
  12. mac_gyver

    Conversion of text data from $variables issue

    any database, api or web site url/host information and any username/password/key values should be implemented in your code using variables or defined constants that are contained in a separate .php file and required by your main code, so that you don't need to be editing them out of the main code in order to post it for getting help.
  13. mac_gyver

    Conversion of text data from $variables issue

    the first method should work. the second method won't work because php variables contained within a single-quoted string are not parsed/replaced with the variable's contents. for the first method, there could be a number of reasons that it doesn't appear to work - 1) the variables don't exist at the point where you are referencing them. 2) the variables don't actually contain what you think or did but have been cleared by some of your code. 3) the method or place you are using to view the result or otherwise determine that this doesn't work, is at fault. 4) there could be a variable scope problem. edit: 5) you could be seeing the result from double page requests (different browsers/client programs do this for various reasons), where the first request does work, but the second doesn't actually find/retrieve the data. it would take seeing all the relevant code, from the point where you are querying for and retrieving the data through to where you are viewing the incorrect result. do you have php's error_reporting set to E_ALL and display_errors set to ON so that php would help you by reporting and displaying all the errors it detects.
  14. mac_gyver

    How to short hand this

    $values and $periods are already arrays. do the same for $ItemsAnnual and make it an array and populate its values using a loop.
  15. mac_gyver

    upgrade to PHP 5.5, Site Doesn't work

    it would help to know what the old php version was. just an update to 5.5 (which should have or soon will be an update to 7+) doesn't break the mysql_ functions. it's more likely that the code is dependent on register_globals in order to function. if so, it will take rewriting all the code to use the actual php super global variables where the external $_GET, $_POST, $_FILES, $_COOKIE, and some $_SERVER variables are at. you would also want to update the code to use one of the current database extensions, and since query security also went away in php 5.4, in order to keep from having to add a bunch of code, it is better to switch to use prepared queries, with the php PDO extension, and to use exceptions to handle database statement errors. doing this will result in the simplest php code and simplest sql query syntax, which will reduce the amount of things you have to update, i.e. you can just eliminate a bunch of stuff, rather than to spend time on updating it.
×

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.