Подделка метода формы в CodeIgniter

#codeigniter #codeigniter-3

#codeigniter #codeigniter-3

Вопрос:

Поэтому я хочу использовать HTTP DELETE на своем маршруте при удалении данных.

Можно ли использовать подделку метода в CodeIgniter?

Может быть, как это делает Laravel, используя скрытый ввод «_method»?

 <input type="hidden" name="_method" value="DELETE">
  

Есть ли какие-либо предложения, как это сделать в CodeIgniter?

Приветствия.

Ответ №1:

Я только что заметил эту функцию в документах Laravel, погуглил и нашел этот вопрос. Я поделюсь своей реализацией в CI 3.0 (возможно, 2.0 ).

Файл: application/helpers/MY_form_helper.php

 <?php defined('BASEPATH') OR exit('No direct script access allowed');

if ( ! function_exists('method_field')) {
    function method_field($method)
    {
        return '<input type="hidden" name="__method" value="'.$method.'">';
    }
}
  

Файл: application/config/routes.php

 <?php defined('BASEPATH') OR exit('No direct script access allowed');

$route['default_controller'] = 'home';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;

// seperate controllers in HTTP VERB sub-folders
$route['(. )']['GET'] = 'get/$1';
$route['(. )']['POST'] = 'post/$1';
$route['(. )']['PUT'] = 'put/$1';
$route['(. )']['PATCH'] = 'patch/$1';
$route['(. )']['DELETE'] = 'delete/$1';
  

Файл: application/core/MY_Router.php

 <?php defined('BASEPATH') OR exit('No direct script access allowed');

protected function _parse_routes()
{
    // Turn the segment array into a URI string
    $uri = implode('/', $this->uri->segments);

    // Get HTTP verb
    $http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli';

    // ::: START EDIT (Form Method Spoofing) :::
    $_request_method = strtolower(isset($_POST['__method']) ? $_POST['__method'] : isset($_GET['__method']) ? $_GET['__method'] : NULL);
    if ( ! empty($_request_method) amp;amp; in_array($_request_method, ['get', 'post', 'put', 'patch', 'delete'])) {
        $http_verb = $_request_method;
    }
    // ::: END EDIT (Form Method Spoofing) :::

    // Loop through the route array looking for wildcards
    foreach ($this->routes as $key => $val)
    {
        // Check if route format is using HTTP verbs
        if (is_array($val))
        {
            $val = array_change_key_case($val, CASE_LOWER);
            if (isset($val[$http_verb]))
            {
                $val = $val[$http_verb];
            }
            else
            {
                continue;
            }
        }

        // Convert wildcards to RegEx
        $key = str_replace(array(':any', ':num'), array('[^/] ', '[0-9] '), $key);

        // Does the RegEx match?
        if (preg_match('#^'.$key.'$#', $uri, $matches))
        {
            // Are we using callbacks to process back-references?
            if ( ! is_string($val) amp;amp; is_callable($val))
            {
                // Remove the original string from the matches array.
                array_shift($matches);

                // Execute the callback using the values in matches as its parameters.
                $val = call_user_func_array($val, $matches);
            }
            // Are we using the default routing method for back-references?
            elseif (strpos($val, '$') !== FALSE amp;amp; strpos($key, '(') !== FALSE)
            {
                $val = preg_replace('#^'.$key.'$#', $val, $uri);
            }

            $this->_set_request(explode('/', $val));
            return;
        }
    }

    // If we got this far it means we didn't encounter a
    // matching route so we'll set the site default route
    $this->_set_request(array_values($this->uri->segments));
}
  

Примечание:

  • С включенной структурой маршрутизации у application/config/routes.php вас могут быть одинаковые имена контроллеров для всех HTTP-глаголов!
  • Просто загрузите помощник формы $this->load->helper('form') , чтобы использовать <?= method_field('PUT') ?> в своих представлениях или использовать <input type="hidden" name="__method" value="PUT"> .
  • Я использовал имя поля скрытой формы __method вместо Laravel _method , потому что можно использовать такое имя поля ( двойное подчеркивание — это так для CodeIgniter).
  • Это РЕДАКТИРОВАНИЕ также может подделывать запросы GET. НАПРИМЕР: http://project-name/controller/action?__method=PATCH вместо этого будет запущен контроллер ИСПРАВЛЕНИЙ!