将发布的多个数组转置为 codeigniter 的 insert_batch 样式

发布于 2025-01-05 08:31:25 字数 2825 浏览 3 评论 0原文

我正在尝试使用 Codeigniter 创建多语言表单。

我有一个 POST 数组:

Array
(
  [title] => Array
    (
        [en] => English Title
        [de] => German Title
    )

  [url] => Array
    (
        [en] => English URL
        [de] => German URL
    )
)

我想将其转换为 codeigniter insert_batch('tablename',$data) 格式:

Array
(
  [0] => Array
    (
        [lang] => en
        [title] => English Title
        [url] => English URL
    )

  [1] => Array
    (
       [lang] => de  // Assuming user didn't fill `_de` labeled input fields.
       [title] => 
       [url] =>
    )
) 

要存储在数据库中的数据为:

|id|lang|    title      |    url      |
|--|----|---------------|-------------|
|  | en | English Title | English URL |
---------------------------------------

我怎样才能实现这一点?我需要将 post 数组转置为 insert_batch 的数据数组样式。上面,array[1] 仅包含预定义的 lang 作为 de。所以 array[1] 对我来说实际上是空的。所以我还需要从最终的$data 中删除空数组。

下面,您将找到视图文件。

<div id="tabs">
  <?php echo form_open('controller/post_target',array('name'=>'add_page')); ?>
  <ul>
    <?php foreach($lang_data as $r):?>
    <li><a href="#tab_<?=$r->lang;?>"><?=$r->name;?></a></li>
    <?php endforeach; ?>        
  </ul>

  <?php foreach($query_lang as $r):?>
  <div id="tab_<?=$r->lang;?>">
    <?php echo form_label('Page Title','title'); ?>
    <?php 
      $attr1 = array('name' => 'title[' . $r->lang . ']');
      echo form_input($attr1); 

      $attr2 = array(name' => 'url[' . $r->lang . ']');
      echo form_input($attr2); 
    ?>
  </div>
  <?php endforeach; ?>
    <?php echo form_submit('submit','Save'); ?>
  <?php echo form_close(); ?>
</div>

仅供参考,我划了几行作为控制器,但我想要一个关于此的干净编码的控制器。如果数组为空,我的版本也无法检查它。 :( 欢迎任何更专业的建议。

if($this->input->post('submit'))
{
  $data = $this->input->post();
  unset($data['submit']); // SELF NOTE : IT should be easier way to do this   

  foreach ($data as $key => $value)
  {
    $counter = 0;
    foreach ($value as $key_inner => $value_inner)
    {
      if( ! isset($db_array[$counter])) $db_array[$counter] = array();
      //Above line enable us to use '+=' operand below in foreach loop

      $db_array[$counter] += array(
          'lang' => $key_inner,
          $key => $value_inner
      );          
      $counter ++;
    }
  }

  //echo '<pre>'; print_r($db_array); echo '</pre>' . '<br />';

  if($this->db->insert_batch('test',$db_array)) echo 'record saved';
}

I am trying to create multi-lingual form with Codeigniter.

I have an POST array as:

Array
(
  [title] => Array
    (
        [en] => English Title
        [de] => German Title
    )

  [url] => Array
    (
        [en] => English URL
        [de] => German URL
    )
)

I want to convert this into codeigniter insert_batch('tablename',$data) format like:

Array
(
  [0] => Array
    (
        [lang] => en
        [title] => English Title
        [url] => English URL
    )

  [1] => Array
    (
       [lang] => de  // Assuming user didn't fill `_de` labeled input fields.
       [title] => 
       [url] =>
    )
) 

Data to be stored in db as:

|id|lang|    title      |    url      |
|--|----|---------------|-------------|
|  | en | English Title | English URL |
---------------------------------------

How can i achieve this? I need to transpose post array to insert_batch's data array style. Above, array[1] contains only prefined lang as de. So array[1] is empty for me literally. So i also need to remove empty arrays from final $data.

Below, you will find view file.

<div id="tabs">
  <?php echo form_open('controller/post_target',array('name'=>'add_page')); ?>
  <ul>
    <?php foreach($lang_data as $r):?>
    <li><a href="#tab_<?=$r->lang;?>"><?=$r->name;?></a></li>
    <?php endforeach; ?>        
  </ul>

  <?php foreach($query_lang as $r):?>
  <div id="tab_<?=$r->lang;?>">
    <?php echo form_label('Page Title','title'); ?>
    <?php 
      $attr1 = array('name' => 'title[' . $r->lang . ']');
      echo form_input($attr1); 

      $attr2 = array(name' => 'url[' . $r->lang . ']');
      echo form_input($attr2); 
    ?>
  </div>
  <?php endforeach; ?>
    <?php echo form_submit('submit','Save'); ?>
  <?php echo form_close(); ?>
</div>

Just for info, I scratched a few line as controller but I want to have a clean-coded controller about this. Also my version can't check it if array empty. :( Any advise for more professional way is welcomed.

if($this->input->post('submit'))
{
  $data = $this->input->post();
  unset($data['submit']); // SELF NOTE : IT should be easier way to do this   

  foreach ($data as $key => $value)
  {
    $counter = 0;
    foreach ($value as $key_inner => $value_inner)
    {
      if( ! isset($db_array[$counter])) $db_array[$counter] = array();
      //Above line enable us to use '+=' operand below in foreach loop

      $db_array[$counter] += array(
          'lang' => $key_inner,
          $key => $value_inner
      );          
      $counter ++;
    }
  }

  //echo '<pre>'; print_r($db_array); echo '</pre>' . '<br />';

  if($this->db->insert_batch('test',$db_array)) echo 'record saved';
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一直在等你来 2025-01-12 08:31:26

我认为,你可以做类似的事情:

$langs = array_keys($post["title"]);
$batch = array();
foreach ($langs as $lang) {
      $tmp = array();
      $tmp["title"] = $post["title"][$lang];
      $tmp["url"] = $post["url"][$lang];
      $batch[] = $tmp;
}

未经测试,也不检查后结构中的任何错误。

I think, you can do similar:

$langs = array_keys($post["title"]);
$batch = array();
foreach ($langs as $lang) {
      $tmp = array();
      $tmp["title"] = $post["title"][$lang];
      $tmp["url"] = $post["url"][$lang];
      $batch[] = $tmp;
}

Not tested and doesn't check any errors in post-structure.

心是晴朗的。 2025-01-12 08:31:25

您可以创建一些函数来做到这一点。由于 lang 属性具有特殊行为(与标题或 url 不同),我认为最好在数组中定义语言。

我在下面创建两个函数,第一个函数将输入数据转换为批量插入所需的格式,第二个函数删除空行(应忽略 lang ,因为它将始终被设置)。

我建议使用要翻译的字段手动设置 $data,而不是传递整个 $_POST 值。您将来可能会添加其他未翻译的输入,我建议使用白名单机制,其中所有输入均已翻译,而不是黑名单(取消设置提交按钮)。

更新
添加 $fields 参数作为翻译的字段列表

$data = prepare_data_for_insert($data, array('title', 'url'), array('en', 'de'));
var_dump($data);
$data = remove_empty_rows($data, array('lang'));
var_dump($data);

function prepare_data_for_insert($data, $fields, $langs) {
    $result = array();

    $i = 0;
    // foreach language defined
    foreach ($langs as $lang) {
        // set the languge
        $result[$i]['lang'] = $lang;
        // foreach field that we want to translate
        foreach ($fields as $field) {
            // set the value for the current language
            $result[$i][$field] = $data[$field][$lang];
        }
        $i++;
    }

    return $result;
}

function remove_empty_rows($data, $ignore_fields = array()) {
    $result = array();

    // result
    foreach ($data as $item) {
        $has_values = false;
        foreach ($item as $key => $value) {
            // check if the key is ignored
            if (in_array($key, $ignore_fields)) {
                continue;
            }

            // if a value was set
            if ($value != '') {
                // the array has values
                $has_values = true;
                // don't search for other values
                break;
            }
        }

        // if the array has values
        if ($has_values) {
            // save the row in the result
            $result[] = $item;
        }
    }

    return $result;
}

You could create some functions to do that. Since the lang property has a special behavior (not the same as title or url), I think it would be best to define the languages in an array.

I create two functions below, the first one converts the input data to the format you need for batch insert and the second removes empty rows (lang should be ignored since it will be always set).

I would suggest to set $data manually with the fields you want to translate and not pass the entire $_POST values. You might add in the future other inputs which are not translated and I would suggest a white list mechanism with all inputs translated instead of blacklist (unset the submit button).

UPDATE
added $fields parameter as the list of fields which are translated

$data = prepare_data_for_insert($data, array('title', 'url'), array('en', 'de'));
var_dump($data);
$data = remove_empty_rows($data, array('lang'));
var_dump($data);

function prepare_data_for_insert($data, $fields, $langs) {
    $result = array();

    $i = 0;
    // foreach language defined
    foreach ($langs as $lang) {
        // set the languge
        $result[$i]['lang'] = $lang;
        // foreach field that we want to translate
        foreach ($fields as $field) {
            // set the value for the current language
            $result[$i][$field] = $data[$field][$lang];
        }
        $i++;
    }

    return $result;
}

function remove_empty_rows($data, $ignore_fields = array()) {
    $result = array();

    // result
    foreach ($data as $item) {
        $has_values = false;
        foreach ($item as $key => $value) {
            // check if the key is ignored
            if (in_array($key, $ignore_fields)) {
                continue;
            }

            // if a value was set
            if ($value != '') {
                // the array has values
                $has_values = true;
                // don't search for other values
                break;
            }
        }

        // if the array has values
        if ($has_values) {
            // save the row in the result
            $result[] = $item;
        }
    }

    return $result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文