0

我的 PHP 脚本从 HTML 输入接收数据作为数组:

<input type="checkbox" name="value[]" value="1" />  
<input type="checkbox" name="value[]" value="2" />  
<input type="checkbox" name="value[]" value="3" />
...

我目前的序列化方法是这样的:

<?php
class DataClass {
private $separator = ",";
private function sanitize($input){
    $patterns = array(
        '/^'.$this->separator.'/',
        '/'.$this->separator.$this->separator.'/',
        '/'.$this->separator.'$/'
        );
    $replacements = array(
        '',
        $this->separator,
        ''
        );
    return preg_replace($patterns, $replacements, $input);
}
public function deserialize($input){
    return explode($this->separator, $this->sanitize($input));
}
private function serialize($input){
    $bucket = array();
    if(is_array($input)):
        foreach($input as $value){
            if(!empty($value)):
                array_push($bucket, $value);
            endif;
        }
        return $this->sanitize(implode($this->separator, $bucket));
    else:
        return "";
    endif;
}

public function store($formdata) {
    $formdata['value'] = empty($formdata['value']) ? '' : $this->serialize($formdata['value']);
    // save $formdata to database
}

}
?>

所以,读完这篇文章后,我的问题是:

  1. 优化现有代码效率的最佳方法是什么?
  2. 使用不同的方法将简单的索引数组转换为可以存储在数据库中的东西会有任何性能优势吗?
    1. 使用 BLOB 列类型与我目前使用的 varchar(255) 相比如何?
    2. 由于它不是关联数组,json_encode甚至是正确的方法,还是只是矫枉过正?
4

2 回答 2

1

一般来说,首选的原因serialize()是因为它们的配套功能,使用andjson_encode()可以很容易地恢复数据,就像你一开始一样。unserialize()json_decode()

也就是说,对于您正在处理的简单数组,一个简单的逗号分隔列表就可以了。但是,您可以进行一些改进。但是让我明确一点:您要完成的工作非常简单,以至于处理效率并不是真正关心的问题。需要关注的是清晰度和可维护性,这就是我们将获得收益的地方。

  1. 如果您所有的复选框都有非空值(例如,它们都不是这样设置的:)<input type="checkbox" name="value[]" value="" />,那么您可能不需要从列表中删除空值。我知道的所有现代浏览器都不会为未选中的复选框发送任何数据。那就是说...
  2. 这样做仍然是一种很好的形式。但是你要重复两次,在你内爆之前和之后。你根本不需要sanitize()。但不仅如此...
  3. 我们还可以进行更多改进,既可以扩展简单序列化的功能,又可以使其交互更简单。同时利用 PHP 提供的所有速度......

<?php
private function serialize($input) {
    // I've changed this, generally speaking you probably
    // don't actually want "serialize" to turn a non-array
    // variable into an empty string
    if (is_scalar($input)) return $input;

    // we still test for an array, because it could potentially
    // be something else...
    elseif (is_array($input)) {
        $bucket = array();
        foreach ($input as $value) {
            // empty() will match 0, so that's probably not
            // what we want... if we test for length, then
            // it'll match anything we might reasonably want
            // to record
            if (strlen($value)) $bucket[] = $value;
        }
        return implode($this->separator, $bucket);
    }

    // if we've got an object, we just serialize with our
    // chosen method: serialize() or json_encode()
    elseif (is_object($input)) return serialize($input);

    // otherwise, we have no reasonable way to serialize
    else return ''; // we might also return NULL
 }
 ?>

...如果我们知道有关数据的某些事情,我们可以使它变得更加简单。例如,如果我们知道所有值都将是唯一的,我们可以非常直接地了解我们正在寻找的内容:

<?php
elseif (is_array($input)) {
    $input = array_unique($input);
    if (in_array('', $input)) array_splice($input, array_search('', $input), 1);
    return implode($input);
}
?>
于 2013-05-24T02:58:15.460 回答
1

首先要解决丢失数据元素和规范化输入的问题,我总是使用 array_merge 来设置默认值。例如。

$defaults = array("checkbox1"=>false, "checkbox2"=>0);
$data = array_merge($defaults, $_POST);

我会说切换到 JSON 作为一种序列化形式,原因如下:

  1. JSON 的编码速度很快,我执行的测试json_encode比序列化简单的数组结构具有 35% 的速度优势。

  2. 与平面文本文件不同,JSON 支持嵌套数据结构,因此它会更具未来性。

  3. JSON 至少允许一个命名标签,它至少是正在发生的事情的线索。并转换为关联数组...如果您正在处理具有大量键的数据集,这很有帮助...两个月后 $a["profile"]["header_font"]就更有意义了$a[12][4]

  4. JSON 序列化数据小于序​​列化结果。(但不仅仅是一个可比较的平面文件)

  5. JSON 是可移植的……只有 PHP 可以读取序列化的结果……该死的几乎所有东西都可以读取 json。允许使用其他语言或工具来利用数据。

至于保存到数据库,我一直只使用 TEXT mysql 数据类型。它允许 2^16 个字符,并且我在这些列中存储的内容比我应该存储的要多,并且没有遇到任何问题。

那是我的两分钱。

于 2013-05-24T03:15:59.857 回答