본문 바로가기
배우고 있습니다/PHP

[laravel] rules max, count와 mb_strlen

by 유헤 2024. 2. 28.

 

 

 

Internal server error SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column ‘coulmn_name’ at row 1 !!

이런 에러가 발생하여 확인해보니 MYSQL 글자수가 넘어가서 발생한 에러였다.

 

어라? Laravel Rules를 등록해놨는데 왜 에러가 났을까?

 

 

EUC-KR은 한글이 2byte

UTF-8은 한글이 3byte 이므로

mb_strlen은 글자수를 나타내므로 인코딩 마다 글자수가 다르게 나옴

utf-8일 경우 euc-kr보다 더 적게 나온다.

 

rules에서 max를 mysql TEXT 값과 동일하게 지정을 했는데, 유효성 검사에서 걸리지 않았다.

 

이유를 찾아보니 max나 count는 모두 mb_strlen을 사용하고 있던 것

https://github.com/laravel/framework/blob/41ea7cc3bb898ff86505d3798d8acbb8992a0aad/src/Illuminate/Validation/Concerns/ValidatesAttributes.php#L1385-L1402

 

protected function getSize($attribute, $value)
    {
        $hasNumeric = $this->hasRule($attribute, $this->numericRules);

        // This method will determine if the attribute is a number, string, or file and
        // return the proper size accordingly. If it is a number, then number itself
        // is the size. If it is a file, we take kilobytes, and for a string the
        // entire length of the string will be considered the attribute size.
        if (is_numeric($value) && $hasNumeric) {
            return $value;
        } elseif (is_array($value)) {
            return count($value);
        } elseif ($value instanceof File) {
            return $value->getSize() / 1024;
        }

        return mb_strlen($value);
    }

 

TEXT 값은 byte로 지정되어있어 해당 65,535 바이트

로 설정해두었으나, 실제 max나 count는 글자수 기준이라 byte보다 더 작게 계산이 된다.

고로, byte수가 65,535를 넘어도 유효성 검사에 걸리지 않게 됨

 

http://trsketch.dothome.co.kr/page_rVsN24

 

byte checker

◈ 500자 제한의 예 한글을 3byte로 계산하는 경우는 1500byte로 제한 한글을 2byte로 계산하는 경우는 1000byte로 제한 ◈ 1000자 제한의 예 한글을 3byte로 계산하는 경우는 3000byte로 제한 한글을 2byte로 계

trsketch.dothome.co.kr

 

https://github.com/laravel/framework/issues/22141

 

Inaccurate validation (string max length) · Issue #22141 · laravel/framework

Laravel Version: 5.5 PHP Version: 7.1 Description: When I validate multi-byte strings using "Max" rule, I get inaccurate result. My guess is that the string length is measured using strlen(), while...

github.com

 

 

https://laracasts.com/discuss/channels/laravel/laravel-validation-minmax-not-working 

 

https://laracasts.com/discuss/channels/laravel/laravel-validation-minmax-not-working

 

laracasts.com

 

 

https://onlinephp.io/mb-strlen/examples

 

mb_strlen - Examples

mb_strlen PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8 mb_strlen - Get string length Example #1 of mb_strlen

onlinephp.io