| 제목 | 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
추상클래스로 이용하는 이유가 잇나요?
|