I am trying to save multiple textfield by language, and when saving if there is an empty textfield of any language, ignore it but for some error my code does not work correctly and when i click submit only save the first textfield
Database
+----------+------------+---------------+ | email_id | email_lang | email_content | +----------+------------+---------------+ | | | | +----------+------------+---------------+
Html
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post"> <input type="text" value="<?php echo $_GET['id']; ?>" name="email_id" hidden> <?php foreach ($languages as $lang): ?> <input type="text" value="<?php echo $lang ?>" name="email_lang"> <textarea type="text" value="1" name="email_content"></textarea> <?php endforeach ?> <button type="submit" name="save">Save</button> </form>
Php
<?php if ($_SERVER['REQUEST_METHOD'] == 'POST'){ $sentence = $connect->prepare("INSERT INTO emailtemplates (email_id,email_lang,email_content) VALUES (:email_id, :email_lang, :email_content)"); $email_id = $_POST['email_id']; $email_lang = $_POST['email_lang']; $email_content = $_POST['email_content']; $sentence->execute(array( ':email_id' => $email_id, ':email_lang' => $email_lang, ':email_content' => $email_content )); } $languages = ['en', 'fr', 'ru']; require '../views/new.email.view.php'; ?>
Expected results
+----------+------------+-----------------+ | email_id | email_lang | email_content | +----------+------------+-----------------+ | 1 | en | english content | | 1 | fr | french content | +----------+------------+-----------------+
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
HTML part
Your input fields in the HTML form need to have names which will allow you to identify the language. In HTML you can create field names with square brackets. When PHP receives these values it will treat them as an array. You can define a <textarea>
like this:
<textarea name="email_content[fr]">
Then in PHP you can access the value using the following syntax:
$french = $_POST['email_content']['fr'];
Notes:
- HTML
<textarea>
doesn’t havetype
norvalue
attributes. - Instead of adding
hidden
attribute to the<input>
elements, just specify thetype="hidden"
. - When outputting any dynamic content within HTML you should take care of XSS protection.
- Instead of
<?php echo $var ?>
you can use the shorter syntax<?=$var ?>
Your complete HTML form might then look something like this:
<form action="<?=htmlspecialchars($_SERVER['PHP_SELF'])?>" method="post"> <input type="hidden" value="<?=$id?>" name="email_id"> <?php foreach ($languages as $lang) : ?> <textarea value="1" name="email_content[<?=htmlspecialchars($lang)?>]" placeholder="<?=htmlspecialchars($lang)?>" value="<?=htmlspecialchars($lang)?>"></textarea> <?php endforeach ?> <button type="submit" name="save">Save</button> </form>
Once the form is received in PHP your $_POST
should contain something like this:
array ( 'email_id' => '12', 'email_content' => array ( 'en' => '', 'fr' => 'French text', 'ru' => '', ), 'save' => '', )
PHP part
To save multiple values in PHP using PDO you need to use a loop. Before the loop, you should prepare the statement and bind parameters. PDO_stmt::bind_param()
is rarely used, but in this situation it can make your code cleaner. You should also perform all inserts inside of a transaction.
$pdo->beginTransaction(); $stmt = $pdo->prepare("INSERT INTO emailtemplates (email_id,email_lang,email_content) VALUES (:email_id, :email_lang, :email_content)"); $stmt->bindParam('email_id', $_POST['email_id']); $stmt->bindParam('email_lang', $lang); $stmt->bindParam('email_content', $contents); foreach ($_POST['email_content'] as $lang => $contents) { if ($contents && in_array($lang, $languages, true)) { $stmt->execute(); } } $pdo->commit();
If you wish to use the simpler syntax you can use PDO_stmt::execute()
to pass the parameters without prior binding.
$pdo->beginTransaction(); $stmt = $pdo->prepare("INSERT INTO emailtemplates (email_id,email_lang,email_content) VALUES (:email_id, :email_lang, :email_content)"); foreach ($_POST['email_content'] as $lang => $contents) { if ($contents && in_array($lang, $languages, true)) { $stmt->execute([ 'email_id' => $_POST['email_id'], 'email_lang' => $lang, 'email_content' => $contents, ]); } } $pdo->commit();
The following line checks if contents were provided and language is in the array of languages you specified.
if ($contents && in_array($lang, $languages, true)) {
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0