CodeIgniter 4: Как загрузить файл с помощью cURL в CodeIgniter 4
cURL широко используется для выполнения HTTP-запросов. С его помощью вы можете отправлять запросы к API для получения или манипулирования данными, отправки формы, загрузки файлов и т.д.
CodeIgniter 4 уже предоставляет класс CURLRequest для отправки cURL-запросов.
В этом уроке я покажу, как можно загрузить файл с помощью cURL из проекта CodeIgniter 4 в другой проект.
1. Создание API для загрузки файлов
Я создам простой API для загрузки файлов в другом PHP проекте.
Если переменная $_FILES установлена, то считываем имя файла и проверяем расширение файла. Если оно действительно, то загружаем файл в папку /upload/ и присваиваем 1 переменной $status и сообщение об успехе переменной $msg, в противном случае присваиваем 0 переменной $status и сообщение об ошибке переменной $msg.
Вернем $response в формате JSON. Он содержит значения status, msg и username (имя пользователя).
Здесь username - это дополнительный параметр, который передается вместе с файлом.
<?php
$status = 0; $msg = "";
if(isset($_FILES['file']['name'])){
// file name
$filename = $_FILES['file']['name'];
// Location
$location = 'upload/'.$filename;
// file extension
$file_extension = pathinfo($location, PATHINFO_EXTENSION);
$file_extension = strtolower($file_extension);
// Valid extensions
$valid_ext = array("pdf","doc","docx","jpg","png","jpeg");
$status = 0;
if(in_array($file_extension,$valid_ext)){
// Upload file
if(move_uploaded_file($_FILES['file']['tmp_name'],$location)){
$status = 1;
$msg = "Загрузка прошла успешно";
}
}else{
$status = 0;
$msg = "Недопустимое расширение файла";
}
}
$response = array(
'status' => $status,
'msg' => $msg,
'username' => $_POST['username']
);
echo json_encode($response);
die;
2. Включим CSRF
Теперь перейдите в проект CodeIgniter 4 и откройте файл .env.
Удалите # из начала строк security.tokenName, security.headerName, security.cookieName, security.expires и security.regenerate.
Я обновляю значение security.tokenName на 'csrf_hash_name'. С этим именем считывается CSRF-хэш. Вы можете изменить его на любое другое значение.
Если вы не хотите перегенерировать CSRF-хэш после каждого запроса, установите security.regenerate = false.
security.tokenName = 'csrf_hash_name' security.headerName = 'X-CSRF-TOKEN' security.cookieName = 'csrf_cookie_name' security.expires = 7200 security.regenerate = true
Откройте файл app/Config/Filters.php.
Раскомментируйте 'csrf' в 'before', если он закомментирован.
// Always applied before every request
public $globals = [
'before' => [
// 'honeypot',
'csrf',
// 'invalidchars',
],
'after' => [
'toolbar',
// 'honeypot',
// 'secureheaders',
],
];
3. Контроллер
Создайте контроллер PagesController
php spark make:controller PagesController
Создайте 2 метода
- index() - Загрузка представления индекса.
- submitform() - Этот метод вызывается на <form> submit.
Проверим файл на валидность. Если файл не валиден, вернемся на страницу с ошибкой, иначе отправьте cURL POST запрос на 'http://localhost/apis/api.php';.
Чтение tempname файла, его оригинальное имя и тип mime для создания объекта CURLFile. Используя его, передайте файл через cURL.
Создадим массив $postData для хранения файла и имени пользователя. Здесь имя пользователя является дополнительным параметром.
Отправьте cURL-запрос и передайте $postData, используя опцию multipart.
Если код состояния cURL равен 200, прочитаем ответ.
Готовый код
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
class PagesController extends BaseController
{
public function index(){
return view('index');
}
// cURL file upload
public function submitform(){
$request = service('request');
## Validation
$validation = \Config\Services::validation();
$input = $validation->setRules([
'username' => 'required',
'file' => 'uploaded[file]|max_size[file,2048]|ext_in[file,jpeg,jpg,png,pdf,doc,docx],'
]);
if ($validation->withRequest($this->request)->run() == FALSE){
$data['validation'] = $this->validator;
return redirect()->back()->withInput()->with('validation', $this->validator);
}else{
$apiURL = 'http://localhost/apis/api.php?request=2';
$client = \Config\Services::curlrequest();
if($file = $this->request->getFile('file')) {
$tempfile = $file->getTempName();
$filename = $file->getName();
$type = $file->getClientMimeType();
// Create a CURLFile object
$cfile = curl_file_create($tempfile,$type,$filename);
$postData = array(
'file' => $cfile,
'username' => $request->getPost()['username']
);
// Send request
$response = $client->post($apiURL,['debug' => true,'multipart' => $postData]);
// Read response
$code = $response->getStatusCode();
$reason = $response->getReason();
if($code == 200){ // Success
// Read data
$body = json_decode($response->getBody());
echo "<pre>";
print_r($body);die;
$status = $body->status;
$msg = $body->msg;
$username = $body->username;
echo "status : ".$status."<br>";
echo "msg : ".$msg."<br>";
echo "username : ".$username."<br>";
}else{
echo "failed";
die;
}
}
}
return redirect()->route('/');
}
}
4. Маршруты (Routes)
Откройте файл app/Config/Routes.php.
Определите 2 маршрута
- / - Отображение представления индекса.
- page/submitform - Обработка отправки формы.
$routes->get('/', 'PagesController::index');
$routes->post('page/submitform', 'PagesController::submitForm');
5. Просмотр (View)
Создайте файл index.php в папке app/Views/.
Создайте <form> для загрузки файла и введите имя пользователя. Установите значение атрибута action - <?=site_url('page/postrequest')?>.
Готовый код
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Как загрузить файл с помощью cURL в CodeIgniter 4</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" >
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 mt-5" style="margin: 0 auto;">
<?php $validation = \Config\Services::validation(); ?>
<form method="post" action="<?=site_url('page/submitform')?>" enctype="multipart/form-data">
<?= csrf_field(); ?>
<div class="form-group mb-4">
<label class="control-label col-sm-2" for="name">User name:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="username" placeholder="Enter username" name="username" value="<?= old('username') ?>">
</div>
<!-- Error -->
<?php if( $validation->getError('username') ) {?>
<div class='text-danger mt-2'>
* <?= $validation->getError('username'); ?>
</div>
<?php }?>
</div>
<div class="form-group mb-4">
<label class="control-label col-sm-2" for="file">File:</label>
<div class="col-sm-10">
<input type="file" class="form-control" id="file" name="file" >
</div>
<!-- Error -->
<?php if( $validation->getError('file') ) {?>
<div class='text-danger mt-2'>
* <?= $validation->getError('file'); ?>
</div>
<?php }?>
</div>
<div class="form-group ">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-info">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Вывод
Вы можете передавать больше параметров с данными файла. В примере я передал имя пользователя, а в API-файле прочитал его с помощью POST. Используйте опцию multipart для передачи данных.
Установите заголовок, если ваш API требует авторизации.
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.