제목 | rest api 만들때 폼검증부분 관련.. | ||
---|---|---|---|
글쓴이 | 닉 | 작성시각 | 2016/11/02 10:26:14 |
|
|||
https://github.com/chriskacerguis/codeigniter-restserver 를 적용하다 보니 rest api에서 맞지 않는 부분이 있었습니다. 뭐냐하면 c - post, r - get, u - put, d - delete 메소드를 타야 하는데 ci3의 폼검증은 post만 되더라고요. 그래서 모든 메소드에 한해서 폼검증이 되도록 해야 맞는 설계라 생각했습니다. 요즘 api 서버 만들때 ci보다는 node로 만드는 추세인거 같더라고요 왜나하면 좀 더 로직이 복잡하지 않도록 하기 위해서 인거같습니다. 하지만 저는 관리자에서 api컨트롤러를 통해 crud를 구현할 계획이었습니다. 왜냐하면 기존 db 처리한 model을 가져다 쓰기 쉽기 때문이었습니다. 그래서 위 rest서버의 코드를 확장하기로 마음먹었습니다. APPPATH . '/libraries/Api_Controller.php'; <?php defined('BASEPATH') OR exit('No direct script access allowed'); require APPPATH . '/libraries/REST_Controller.php'; abstract class Api_Controller extends REST_Controller { function __construct() { parent::__construct(); } //검증 public function valid (array $valid_config, $successFn=FALSE, $failFn=FALSE) { $this->load->library('form_validation'); $this->form_validation->api_set_rules($valid_config); //폼검증. if ($this->form_validation->api_run() == FALSE) { if ($failFn) $failFn(); } else { if ($successFn) $successFn(); } } public function get_method () { return $this->_detect_method(); } } MY_Form_validation.php public function api_set_rules($field, $label = '', $rules = array(), $errors = array()) { // If an array was passed via the first parameter instead of individual string // values we cycle through it and recursively call this function. if (is_array($field)) { foreach ($field as $row) { // Houston, we have a problem... if ( ! isset($row['field'], $row['rules'])) { continue; } // If the field label wasn't passed we use the field name $label = isset($row['label']) ? $row['label'] : $row['field']; // Add the custom error message array $errors = (isset($row['errors']) && is_array($row['errors'])) ? $row['errors'] : array(); // Here we go! $this->api_set_rules($row['field'], $label, $row['rules'], $errors); } return $this; } // No fields or no rules? Nothing to do... if ( ! is_string($field) OR $field === '' OR empty($rules)) { return $this; } elseif ( ! is_array($rules)) { // BC: Convert pipe-separated rules string to an array if ( ! is_string($rules)) { return $this; } $rules = preg_split('/\|(?![^\[]*\])/', $rules); } // If the field label wasn't passed we use the field name $label = ($label === '') ? $field : $label; $indexes = array(); // Is the field name an array? If it is an array, we break it apart // into its components so that we can fetch the corresponding POST data later if (($is_array = (bool) preg_match_all('/\[(.*?)\]/', $field, $matches)) === TRUE) { sscanf($field, '%[^[][', $indexes[0]); for ($i = 0, $c = count($matches[0]); $i < $c; $i++) { if ($matches[1][$i] !== '') { $indexes[] = $matches[1][$i]; } } } // Build our master array $this->_field_data[$field] = array( 'field' => $field, 'label' => $label, 'rules' => $rules, 'errors' => $errors, 'is_array' => $is_array, 'keys' => $indexes, 'postdata' => NULL, 'error' => '' ); return $this; } public function api_run($group = '') { $method = $this->CI->get_method(); $validation_array = $this->CI->$method(); // Does the _field_data array containing the validation rules exist? // If not, we look to see if they were assigned via a config file if (count($this->_field_data) === 0) { // No validation rules? We're done... if (count($this->_config_rules) === 0) { return FALSE; } if (empty($group)) { // Is there a validation rule for the particular URI being accessed? $group = trim($this->CI->uri->ruri_string(), '/'); isset($this->_config_rules[$group]) OR $group = $this->CI->router->class.'/'.$this->CI->router->method; } $this->set_rules(isset($this->_config_rules[$group]) ? $this->_config_rules[$group] : $this->_config_rules); // Were we able to set the rules correctly? if (count($this->_field_data) === 0) { log_message('debug', 'Unable to find validation rules'); return FALSE; } } // Load the language file containing error messages $this->CI->lang->load('form_validation'); // Cycle through the rules for each field and match the corresponding $validation_data item foreach ($this->_field_data as $field => $row) { // Fetch the data from the validation_data array item and cache it in the _field_data array. // Depending on whether the field name is an array or a string will determine where we get it from. if ($row['is_array'] === TRUE) { $this->_field_data[$field]['postdata'] = $this->_reduce_array($validation_array, $row['keys']); } elseif (isset($validation_array[$field])) { $this->_field_data[$field]['postdata'] = $validation_array[$field]; } } // Execute validation rules // Note: A second foreach (for now) is required in order to avoid false-positives // for rules like 'matches', which correlate to other validation fields. foreach ($this->_field_data as $field => $row) { // Don't try to validate if we have no rules set if (empty($row['rules'])) { continue; } $this->_execute($row, $row['rules'], $this->_field_data[$field]['postdata']); } // Did we end up with any errors? $total_errors = count($this->_error_array); if ($total_errors > 0) { $this->_safe_form_data = TRUE; } // Now we need to re-set the POST data with the new, processed data $this->_reset_post_array(); return ($total_errors === 0); }
rest api 만들때는 <?php defined('BASEPATH') OR exit('No direct script access allowed'); require APPPATH . '/libraries/Api_Controller.php'; class Auth extends Api_Controller { function __construct() { parent::__construct(); $this->load->model(HM_F.'/auth_model'); $this->load->model(MG_F.'/company_model'); } //중복확인 public function overlap_get() { $config = array( array('field'=>'name', 'label'=>'이름', 'rules'=>'required|trim|max_length[10]|korean_alpha_dash'), array('field'=>'id', 'label'=>'아이디', 'rules'=>'required|trim|alpha_dash|max_length[20]'), array('field'=>'hp', 'label'=>'휴대폰', 'rules'=>'required|trim|max_length[13]'), array('field'=>'email', 'label'=>'이메일', 'rules'=>'required|trim|valid_email|max_length[50]'), ); $this->valid($config,function(){ $this->response(array("msg"=>"성공"), REST_Controller::HTTP_OK); },function(){ $this->response(array("msg"=>strip_tags(validation_errors())), REST_Controller::HTTP_BAD_REQUEST); }); } } 이런식으로 get post put delete 등 메소드별로 폼 검증할 수 있습니다. |
|||
다음글 | 기본 퍼미션 라이브러리 (3) | ||
이전글 | pg object 프로젝트 [inicis 웹표준, ... (5) | ||
kaido
/
2016/11/02 11:15:35 /
추천
0
수고하셨습니다~ ^^
|
한대승(불의회상)
/
2016/11/02 11:18:47 /
추천
0
확장된 폼검증 라이브러리 감사 합니다. 깔끔하게 잘 정리 하셨습니다. 참고로 CI3.0 부터는 _POST로 들어온 데이터 이외의 데이터를 검색 할 수 있도록 폼검증 라이브러리가 개선 되었습니다. post 방식이 아닌 다른 메소드(get,delete,put) 방식으로 전달된 데이터를 배열에 저장하고 아래 처럼 하시면 됩니다. $data = array( 'username' => 'johndoe', 'password' => 'mypassword', 'passconf' => 'mypassword' ); $this->form_validation->set_data($data); 더 자세한 내용은 메뉴얼 폼검증 라이브러리 참고 하세요. |
닉
/
2016/11/02 15:04:20 /
추천
0
@불의회상 앗 이런방법이.. 구지 확장 안해도 해결 할 수 있는것 같아요? |
닉
/
2016/11/02 15:16:05 /
추천
1
불의회상님이 알려주신 내용을 바탕으로 재 작성해 봤습니다. 기존 소스에서 MY_Form_validation.php의 내용은 추가 안해도 되고, Api_Controller.php에서 //검증 public function valid (array $valid_config, $successFn=FALSE, $failFn=FALSE) { $this->load->library('form_validation'); $method = $this->get_method(); $this->form_validation->set_data($this->$method()); $this->form_validation->set_rules($valid_config); //폼검증. if ($this->form_validation->run() == FALSE) { if ($failFn) $failFn(); } else { if ($successFn) $successFn(); } } valid부분만 수정하면 조금 더 소스가 간결해 집니다. |
엘제이
/
2017/08/09 11:12:49 /
추천
0
추상클래스로 이용하는 이유가 잇나요?
|