백에서는 항상 프론트에서 밸리데이션을 검증한다고 하더라도 다시 한번 검증이 필요합니다. SpringBoot, Laravel에서는 자체적으로 Validation이 가능하지만 CI에서는 Validation 검증 기능이 많이 부족하여 회사에서 사용하는 방식대로 커스텀 하였습니다.
trait 파일이나 CI_Controller를 상속받는 클래스에 다음과 같이 작성합니다.
protected function validate_fields(array $fields)
{
$this->load->library('form_validation');
$error_messages = array();
// 필드 데이터 설정
$data = array();
foreach ($fields as $field_name => $field_data) {
$data[$field_name] = $field_data['value'];
}
$this->form_validation->set_data($data);
// 검증 규칙 및 오류 메시지 설정
foreach ($fields as $field_name => $field_data) {
$field_values = is_array($field_data['value']) ? $field_data['value'] : array($field_data['value']);
foreach ($field_values as $index => $value) {
// 키 값을 기반으로 새 필드 이름을 생성
$new_field_name = is_array($field_data['value']) ? $field_name . "[" . $index . "]" : $field_name;
// 각 배열 항목에 대한 유효성 검사 규칙 설정
$this->form_validation->set_rules($new_field_name, $field_data['label'], $field_data['rules']);
// 각 규칙에 대한 오류 메시지 설정
foreach ($field_data['error_messages'] as $rule => $message) {
$this->form_validation->set_message($rule, $message);
}
// 검증 실행
if (!$this->form_validation->run()) {
$error_messages[] = strip_tags(form_error($new_field_name));
break 2; // 첫 번째 오류 발생 시 루프를 빠져나온다
}
}
}
return $error_messages;
}
컨트롤러에서는 다음과 같이 사용 할 수 있습니다.
Request로 전달된 파라미터를 통해서 Map형태로 만든후 form_validation을 통해 검증후 첫번째 에러를 Response 합니다.
$fields = [
'rank_idx' => [
'value' => $params['rank_idx'],
'label' => 'rank_idx',
'rules' => 'required|is_natural',
'error_messages' => [
'required' => '등급 idx 값이 전달 되지 않았습니다.',
'is_natural' => '등급 idx 값이 숫자가 아닙니다.'
]
],
'user_idx' => [
'value' => $params['user_idx'],
'label' => 'user_idx',
'rules' => 'required|is_natural',
'error_messages' => [
'required' => '사용자 idx 값이 전달 되지 않았습니다.',
'is_natural' => '사용자 idx 값이 숫자가 아닙니다.'
]
],
];
$validation_errors = $this->validate_fields($fields);
if (!empty($validation_errors)) {
$this->api_error($validation_errors);
}
추가로 프론트에서 전달받는 파라미터중 NaN 값으로 전달될때가 있습니다. 이때 get_params를 통해서 필터링을 한뒤 가지고 오는것도 나쁘지 않은 방법입니다.
$params = $this->get_params(['idx'], 'post');
protected function get_params($params = array(), $method = 'get')
{
$result = array();
foreach ($params as $param) {
$value = $this->input->{$method}($param, true);
if ($value === 'NaN') {
$value = '';
}
$result[$param] = $value;
}
return $result;
}