首页 > 解决方案 > 如何使用 php 在 mysql 中存储多语言文本字段?

问题描述

我正在尝试按语言保存多个文本字段,如果存在任何语言的空文本字段,则在保存时忽略它,但对于某些错误,我的代码无法正常工作,当我单击提交时,仅保存第一个文本字段

数据库

+----------+------------+---------------+
| 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';

?>

预期成绩

+----------+------------+-----------------+
| email_id | email_lang |  email_content  |
+----------+------------+-----------------+
|        1 | en         | english content |
|        1 | fr         | french content  |
+----------+------------+-----------------+

标签: phpmysqlpdo

解决方案


HTML 部分

HTML 表单中的输入字段需要有名称,以便您识别语言。在 HTML 中,您可以使用方括号创建字段名称。当 PHP 接收到这些值时,它会将它们视为一个数组。你可以<textarea>这样定义:

<textarea name="email_content[fr]">

然后在 PHP 中,您可以使用以下语法访问该值:

$french = $_POST['email_content']['fr'];

笔记:

  • HTML<textarea>没有也type没有value属性。
  • 无需向元素添加hidden属性<input>,只需指定type="hidden".
  • 在 HTML 中输出任何动态内容时,您应该注意XSS 保护
  • 而不是<?php echo $var ?>你可以使用更短的语法<?=$var ?>

您的完整 HTML 表单可能如下所示:

<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>

在 PHP 中收到表单后,您$_POST应该包含以下内容:

array (
  'email_id' => '12',
  'email_content' => 
  array (
    'en' => '',
    'fr' => 'French text',
    'ru' => '',
  ),
  'save' => '',
)

PHP部分

要使用 PDO 在 PHP 中保存多个值,您需要使用循环。在循环之前,您应该准备语句和绑定参数。PDO_stmt::bind_param()很少使用,但在这种情况下,它可以使您的代码更干净。您还应该在事务内执行所有插入。

$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();

如果您希望使用更简单的语法,您可以使用它PDO_stmt::execute()来传递参数而无需事先绑定。

$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();

以下行检查是否提供了内容以及语言是否在您指定的语言数组中。

if ($contents && in_array($lang, $languages, true)) {

推荐阅读