CodeIgniter3表单提交后:存库+发邮件需求及代码求助
First, let's fix the flow to ensure we're working with the API-transformed values (not raw POST data) throughout the process, then handle DB insertion and email sending reliably. Here's a step-by-step implementation tailored to your needs:
1. Refactor Your Code into CodeIgniter's MVC Structure
First, move all logic out of the view file (your current HTML/PHP mix) into a Controller. Views should only handle presentation, not business logic.
Step 1: Controller Setup (e.g., TransactionController.php)
This is where we'll handle API transformation, DB insertion, and email sending. We'll ensure we only use the transformed values for both DB and emails.
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class TransactionController extends CI_Controller { public function __construct() { parent::__construct(); // Load required libraries/models $this->load->model('Transaction_model'); $this->load->library('email'); // Configure email settings (you can also set this in config/email.php) $this->email->set_mailtype('html'); $this->email->set_newline("\r\n"); } public function process_transaction() { // 1. Get raw POST data using CI's input class (safer than direct $_POST) $raw_post = $this->input->post(); // 2. Perform API transformation HERE to get your final values // Replace this with your actual API conversion logic $transformed_data = $this->transform_values_via_api($raw_post); // 3. Generate transaction reference $transformed_data['txn_ref'] = strtoupper($this->generate_random_string(26)); $transformed_data['txn_status'] = "Pending"; // 4. Save transformed data to DB first (use transactions for atomicity) $save_success = $this->Transaction_model->save_transaction($transformed_data); if ($save_success) { // 5. Only send emails if DB save succeeds $this->send_transaction_emails($transformed_data); // 6. Pass transformed data to the view for display $data['transaction'] = $transformed_data; $data['ouraccount'] = "Your Platform's Account Details"; // Replace with actual value $this->load->view('transaction_success', $data); } else { // Handle DB save failure $this->session->set_flashdata('error', 'Failed to process your transaction. Please try again.'); redirect('transaction/form'); } } // Helper: API transformation logic (replace with your actual code) private function transform_values_via_api($raw_data) { // Example: Call your external API here to convert amounts/currencies return [ 'user_id' => $raw_data['user_id'], 'email' => $raw_data['email'], 'username' => $raw_data['username'], 'exc_from' => $raw_data['exc_from'], 'exc_to' => $raw_data['exc_to'], 'from_amount' => $raw_data['from_amount'], // Replace with API-converted value 'to_amount' => $raw_data['to_amount'], // Replace with API-converted value 'account' => $raw_data['account'] ]; } // Helper: Generate random transaction reference private function generate_random_string($length = 26) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } // Helper: Send emails to user and admin private function send_transaction_emails($transaction) { // Send confirmation to user $this->email->clear(); $this->email->to($transaction['email']); $this->email->from('support@yourplatform.com', 'Your Platform Name'); $this->email->subject('Your Transaction Confirmation'); $this->email->message($this->get_user_email_template($transaction)); $this->email->send(); // Send notification to admin $this->email->clear(); $this->email->to('admin@yourplatform.com'); $this->email->from('support@yourplatform.com', 'Your Platform Name'); $this->email->subject('New Transaction Received'); $this->email->message($this->get_admin_email_template($transaction)); $this->email->send(); } // Helper: User-facing email template private function get_user_email_template($transaction) { ob_start(); ?> <h3>Your <?php echo $transaction['exc_from']; ?> to <?php echo $transaction['exc_to']; ?> Transaction</h3> <table style="border-collapse: collapse; width: 100%; margin: 10px 0;"> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Payment ID</th> <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $transaction['txn_ref']; ?></td> </tr> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Email</th> <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $transaction['email']; ?></td> </tr> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">You Give</th> <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $transaction['from_amount']; ?> <?php echo $transaction['exc_from']; ?></td> </tr> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">You Get</th> <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $transaction['to_amount']; ?> <?php echo $transaction['exc_to']; ?></td> </tr> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Status</th> <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $transaction['txn_status']; ?></td> </tr> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">View Transaction</th> <td style="border: 1px solid #ddd; padding: 8px;"><a href="<?php echo base_url('transaction/' . $transaction['txn_ref']); ?>">Click here</a></td> </tr> </table> <?php return ob_get_clean(); } // Helper: Admin-facing email template private function get_admin_email_template($transaction) { ob_start(); ?> <h3>New Transaction Alert</h3> <p>Transaction details:</p> <table style="border-collapse: collapse; width: 100%; margin: 10px 0;"> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Payment ID</th> <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $transaction['txn_ref']; ?></td> </tr> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">User Email</th> <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $transaction['email']; ?></td> </tr> <tr> <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Currency Pair</th> <td style="border: 1px solid #ddd; padding: 8px;"><?php echo $transaction['exc_from']; ?> → <?php echo $transaction['exc_to']; ?></td> </tr> </table> <?php return ob_get_clean(); } }
Step 2: Model Setup (application/models/Transaction_model.php)
This model handles saving only the transformed data to the database, no raw POST data is used here.
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Transaction_model extends CI_Model { public function save_transaction($data) { // Use database transactions to ensure atomicity $this->db->trans_start(); // Insert transformed data into your transactions table $this->db->insert('transactions', [ 'user_id' => $data['user_id'], 'email' => $data['email'], 'username' => $data['username'], 'txn_ref' => $data['txn_ref'], 'txn_status' => $data['txn_status'], 'exc_from' => $data['exc_from'], 'exc_to' => $data['exc_to'], 'from_amount' => $data['from_amount'], 'to_amount' => $data['to_amount'], 'account' => $data['account'], 'created_at' => date('Y-m-d H:i:s') ]); $this->db->trans_complete(); // Return true if transaction succeeded, false otherwise return $this->db->trans_status(); } }
Step 3: View File (application/views/transaction_success.php)
This view only displays the transformed data passed from the controller:
<div class="row"> <h3>Your <?php echo $transaction['exc_from']; ?> to <?php echo $transaction['exc_to']; ?> Transaction Details</h3> <div class="table-responsive"> <table class="table table-striped"> <tbody> <tr> <th>Payment ID</th> <td><?php echo $transaction['txn_ref']; ?></td> </tr> <tr> <th>Email</th> <td><?php echo $transaction['email']; ?></td> </tr> <tr> <th>Username</th> <td><?php echo $transaction['username']; ?></td> </tr> <tr> <th>You Give</th> <td><?php echo $transaction['from_amount']; ?> <?php echo $transaction['exc_from']; ?></td> </tr> <tr> <th>You Get</th> <td><?php echo $transaction['to_amount']; ?> <?php echo $transaction['exc_to']; ?></td> </tr> <tr> <th>Your <?php echo $transaction['exc_to']; ?> Wallet</th> <td><?php echo $transaction['account']; ?></td> </tr> <tr> <th>Transaction Status</th> <td><?php echo $transaction['txn_status']; ?></td> </tr> <tr> <th>Make Payment to</th> <td><?php echo $ouraccount; ?></td> </tr> <tr> <th>View in Dashboard</th> <td><a href="<?=base_url()?>transaction/<?php echo $transaction['txn_ref']; ?>">View Transaction</a><br></td> </tr> </tbody> </table> </div> </div>
2. Key Solutions to Your Problems
a. Ensure We Save Transformed Values
By running the API transformation before passing data to the model, we guarantee that only converted values are stored in the database. No raw POST data touches the model layer.
b. Execution Order & Reliability
- We use database transactions to ensure the DB insert is atomic (either fully succeeds or fails).
- Emails are only sent after confirming the DB save was successful—this prevents sending emails for transactions that weren't actually saved.
- For extreme reliability (e.g., emails should send even if the app crashes post-DB save), you could add a queue system (like using CodeIgniter hooks or a library like
php-resque), but the above flow works for most use cases.
c. Secure Input Handling
We use CodeIgniter's $this->input->post() instead of direct $_POST for built-in XSS filtering and better security.
3. Additional Tips
- Move the
generate_random_stringfunction to a custom helper file (application/helpers/transaction_helper.php) and autoload it inconfig/autoload.phpfor reusability. - Configure SMTP settings in
config/email.phpinstead of using PHP'smail()function for better email deliverability. - Add form validation in the controller using CodeIgniter's Form Validation library to ensure valid input before processing.
内容的提问来源于stack exchange,提问作者ibmgeniuz

