验证表单中的字符串大小

While setting up a doctrine entity to be used alongside a Symfony form, I want to validate that the given string size is not going to exceed the column size of the database. Notice I use the word size and not length.

Symfony ships with a number of validation constraints, in particular the Length Constraint. However, looking at it's documentation

The charset to be used when computing value's length. The grapheme_strlen PHP function is used if available. If not, the mb_strlen PHP function is used if available. If neither are available, the strlen PHP function is used.

It uses grapheme_strlen or mb_strlen which return the visual length of the string and NOT the actual size. When dealing with non ASCII strings, the actual size is a factor. For example most Asian languages use 3 bytes for each character.

The doctrine documentation states nothing about the @Column(length) annotation which leads me to believe it's a byte count. So, If I declare a column of length 64 and a constraint of max-size 64, there is going to be a problem.

Now, I could use a Callback Constraint or even create a custom constraint. But, is there a better way? How should strings received from form fields have their size validated before being persisted to the database?

Yes, the documentation does mention the order of function that will be chosen between.

However, that got me thinking and I went to see it for myself in a source code. There's no trace of such thing. I would tend to believe that they wanted to say that these functions will be used to determine the charset, however, no such thing exists in the source code either. I think it's some kind of typo, copy/paste error.

Here, take a look:

$stringValue = (string) $value;
if ('UTF8' === $charset = strtoupper($constraint->charset)) {
    $charset = 'UTF-8'; // iconv on Windows requires "UTF-8" instead of "UTF8"
}

$length = @iconv_strlen($stringValue, $charset);
$invalidCharset = false === $length;

In fact, they use iconv_strlen to determine the right length. I think it's safe to assume your validation will do just fine.

As for the @Column length parameter, that one is not intended for validation, but to schema creation/migration processes. As such, it should not be regarded as a safeguard for a validation processes.

Hope this helps a bit.