Yii2 - How to upload & store Images in Database - php

I am using yii2. I am trying to select a file and then want to save it to my database table. I am using core PHP for it. Below is my code
<form action = <?=\yii\helpers\Url::toRoute(['meteracceptanceheader/import'])?> method ="post"
enctype="multipart/form-data">
.
.
.
.
.
.
.
<div class="row">
<div class="col-md-2">
Upload-Image
<input type="file" name="file"/>
<br />
<input type="submit" class="btn btn-primary pull-left" />
</div>
</div>
</form>
Controller
public function actionImport()
{
.
.
. // my other code
$file = $_FILES['file'];
$fileName = $_FILES['file']['name'];
$fileExt = explode('.',$fileName);
print_r($file);
die();
.
.
.
.
return $this->render('excel_finish', ['records_saved' => $ok_count,'status_arr'=>$status_arr]);
}
Database Table
In the above table, id is auto-increment accpt_id is the model id which I already have and file_path is the name of the file which should be saved like 123.jpg.
The file should be saved into a folder uploads/meter_acceptance/ and append with the file name.
Note:
I have already know how to upload images via the active form but here I want to do it in a traditional way.
Any help would be highly appreciated.

your controller should be like this
public function actionUpload(){
$model = new Images();
$uploadPath = Yii::getAlias('#root') .'/uploads/';
if (isset($_FILES['image'])) {
$file = \yii\web\UploadedFile::getInstanceByName('image');
$original_name = $file->baseName;
$newFileName = \Yii::$app->security
->generateRandomString().'.'.$file->extension;
// you can write save code here before uploading.
if ($file->saveAs($uploadPath . '/' . $newFileName)) {
$model->image = $newFileName;
$model->original_name = $original_name;
if($model->save(false)){
echo \yii\helpers\Json::encode($file);
}
else{
echo \yii\helpers\Json::encode($model->getErrors());
}
}
}
else {
return $this->render('upload', [
'model' => $model,
]);
}
return false;
}

Related

Either _POST or _FILES is empty when submitting form

I am trying to upload a simple image file to my project using php and html but when I submit the form, either the _FILE method is empty or the _POST method is empty. My code never makes it passed the if statement checking that all fields are not empty, as I get the error: "All fields are mandatory, please fill all the fields."
Here is my CRUD.php file up until the error message:
// Include and initialize database class
require_once(ROOT_DIR . '/Classes/database.class.php');
$imageDB = new DB();
$tblName = 'image';
// The folder where the images will be stored
$uploadDir = CONTENT_PATH . '/';
// Allow file formats
$allowTypes = array('jpg', 'png', 'jpeg', 'gif');
// Set default redirect url
$redirectURL = PUBLIC_PATH . '/manageUploads.php';
$statusMsg = '';
$sessData = array();
$statusType = 'danger';
// Check if user has uploaded new image
if (isset($_POST['imgSubmit'])) {
//Set redirect url
$redirectURL = PUBLIC_PATH . '/addEdit.php';
//Get submitted data and clean it from injections
$id = $_POST['id'];
$image = $_FILES['image'];
echo $image['name'];
//Store title variable without any html or php tags and trims whitespace from beginning and end
$title = strip_tags(trim($_POST['title']));
// Validate user tags are separated by comma or space and contain only alphanumeric or space/comma input
$regex = '/^[ ,]*[a-zA-Z0-9]+(?:[ ,]+[a-zA-Z0-9]+){0,5}[ ,]*$/';
if (preg_match($regex, $_POST['tags']) == 0) {
exit('Tags are not valid!');
}
// Makes all tags lower case
$tag_input = strtolower($_POST['tags']);
// Clean up multiple commas or whitespaces
$clean_tag_input = preg_replace('/[\s,]+/', ' ', $tag_input);
// Replaces spaces with commas
$comma_tags = str_replace(' ', ',', $clean_tag_input);
// Submitted user data
$imgData = array('title' => $title,'tags' => $comma_tags);
// Store submitted data into session
$sessData['postData'] = $imgData;
$sessData['postData']['id'] = $id;
// ID query string
$idStr = !empty($id)?'?id='.$id:'';
// If the data is not empty
if ((!empty($image['name']) && !empty($title) && !empty($comma_tags)) || (!empty($id) && !empty($title) && !empty($comma_tags))) {
echo $title;
if(!empty($image)) {
$filename = basename($image['name']);
// Get file extension in lower case
$fileType = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
echo $fileType;
// Generate a unique name for the image to prevent throwing exists error
$unique_image_name = rand(10000, 990000) . '_' . time() . '.' . $fileType;
// The path of the new uploaded image
$targetFilePath = $uploadDir . $unique_image_name;
echo $targetFilePath;
if (in_array($fileType, $allowTypes)) {
// Check to make sure the image is valid
if (!empty($image['tmp_name']) && getimagesize($image['tmp_name'])) {
if (file_exists($unique_image_name)) {
$statusMsg = 'Image already exists, please choose another or rename that image.';
} else if ($image['size'] > 500000) {
$statusMsg = 'Image file size too large, please choose an image less than 500kb.';
} else {
// Everything checks out now we can move the uploaded image
if (move_uploaded_file($image['tmp_name'], $targetFilePath)){
$imgData['filename'] = $unique_image_name;
$imgData['username'] = $_SESSION['username'];
} else {
$statusMsg = 'Sorry, there was an error uploading your file.';
}
}
}
} else {
$statusMsg = 'Image file is empty or corrupt.';
}
} else {
$statusMsg = 'Sorry, only JPG, JPEG, PNG && GIF files are allowed to be uploaded.';
}
} else {
$statusMsg = 'Sorry something went wrong.';
}
if (!empty($id)) {
// Previous filename
$conditions['where'] = array('id' => $_GET['imageID'],);
$conditions['return_type'] = 'single';
$prevData = $imageDB->getRows('image', $conditions);
// Update data
$condition = array('id' => $id);
$update = $imageDB->update($tblName, $imgData, $condition);
if($update) {
//Remove old file from server
if (!empty($imgData['filename'])) {
#unlink($uploadDir . $prevData['filename']);
}
$statusType = 'success';
$statusMsg = 'Image data has been updated successfully.';
$sessData['postData'] = '';
$redirectURL = PUBLIC_PATH . '/manageUploads.php';
} else {
$statusMsg = 'Some problem occurred, please try again.';
//Set redirect url
$redirectURL .= $idStr;
}
} elseif (!empty($imgData['filename'])) {
// Insert data
$insert = $imageDB->insert($tblName, $imgData);
if ($insert) {
$statusType = 'success';
$statusMsg = 'Image has been uploaded successfully.';
$sessData['postData'] = '';
$redirectURL = PUBLIC_PATH . '/manageUploads.php';
} else {
$statusMsg = 'Some problem occurred, please try again.';
}
} else {
$statusMsg = 'All fields are mandatory, please fill all the fields.';
}
And here is my addEdit.php file with the form:
require_once(ROOT_DIR . '/Templates/header.php');
$postData = $imgData = array();
$newViewkey = uniqid();
// Get image data
if (!empty($_GET['imageID'])) {
//include and initialize DB class
require_once(ROOT_DIR . '/Classes/database.class.php');
$addEditDB = new DB();
$conditions['where'] = array('id' => $_GET['imageID'],);
$conditions['return_type'] = 'single';
$imgData = $addEditDB->getRows('image', $conditions);
}
// Pre-filled data
$imgData = !empty($postData)?$postData:$imgData;
// Define action
$actionLabel = !empty($_GET['imageID'])?'Edit':'Add';
head('Upload Image', $_SESSION['username'])
?>
<!-- Display status message -->
<?php if(!empty($statusMsg)){ ?>
<div class="message">
<?php echo $statusMsg; ?>
</div>
<?php } ?>
<div class="upload-form">
<h1>Upload Image</h1>
<form action="<?php echo IMAGE_UTIL_PATH;?>/crud.php" method="POST" enctype="multipart/form-data">
<label for="title">Title</label>
<input
type="text" name="title" id="title"
placeholder="Type image title here."
value="<?php echo !empty($imgData['title'])?$imgData['title']:''; ?>" required>
<?php if (!empty($imgData['tags'])) {
$tagsSpaces = preg_replace('/,/', ', ', trim($imgData['tags']));
} ?>
<label for="tags">Tags</label>
<textarea name="tags" id="tags" placeholder="Enter at least 1 tag describing the image separated by a space ' ' or a ','." required><?php echo !empty($imgData['tags'])?$tagsSpaces:''; ?></textarea>
<input type="file" name="image" id="image" value="<?php echo !empty($imgData['filename'])?$imgData['filename']:''; ?>" required>
<input type="hidden" name="id" value="<?php echo !empty($imgData['id'])?$imgData['id']:''; ?>">
<input type="hidden" name="modified" value="<?php echo !empty($imgData['id'])?date('Y/m/d h:m:s'):''; ?>">
<input type="hidden" name="viewkey" value="<?php echo !empty($imgData['viewkey'])?$imgData['viewkey']:$newViewkey;?>">
<?php if (!empty($imgData['filename'])) { ?>
<div>
<img src="<?php echo !empty($imgData['filename'])?$imgData['filename']:'';?>" height=75 width=auto >
</div>
<?php } ?>
<input type="submit" value="Upload" name="imgSubmit">
</form>
<div class="message">
Back to Manage Uploads
</div>
</div>
<?php require_once(ROOT_DIR . '/Templates/footer.php')?>
And finally here is my config.php file with all the path definitions:
/*
Set include path to include files outside root directory
*/
set_include_path(get_include_path() . PATH_SEPARATOR . 'C:\xampp\htdocs\Shape_Search\resources');
/*
Error reporting
*/
ini_set("display_errors", "true");
error_reporting(E_ALL|E_STRICT);
/*
Create constants for heavily used paths relative to config file location
*/
defined('ROOT_DIR')
or define('ROOT_DIR', dirname(__FILE__));
defined('SRC_DIR')
or define('SRC_DIR', dirname(dirname(__FILE__)) . '\src');
defined('PUBLIC_PATH')
or define('PUBLIC_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/public_html');
defined('CONTENT_PATH')
or define('CONTENT_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/public_html/img/content');
defined('LAYOUT_PATH')
or define('LAYOUT_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/public_html/img/layout');
defined('CSS_PATH')
or define('CSS_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/public_html/css');
defined('JS_PATH')
or define('JS_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/public_html/js');
defined('LIBRARY_PATH')
or define('LIBRARY_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/resources/Library');
defined('CLASSES_PATH')
or define('CLASSES_PATH', realpath(dirname(__FILE__)) . '/Classes');
defined('TEMPLATES_PATH')
or define('TEMPLATES_PATH', realpath(dirname(__FILE__)) . "\Templates");
defined('IMAGE_UTIL_PATH')
or define('IMAGE_UTIL_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/src/ImageUtilities');
defined('RATING_UTIL_PATH')
or define('RATING_UTIL_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/src/RatingUtilities');
defined('USER_UTIL_PATH')
or define('USER_UTIL_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/src/UserUtilities');
?>
And here is my php error log:
[10-Feb-2022 13:52:06 Europe/Berlin] PHP Warning: move_uploaded_file(/Shape_Search/public_html/img/content/973439_1644497526.jpg): Failed to open stream: No such file or directory in C:\xampp\htdocs\Shape_Search\src\ImageUtilities\crud.php on line 116
[10-Feb-2022 13:52:06 Europe/Berlin] PHP Warning: move_uploaded_file(): Unable to move "C:\xampp\tmp\phpCCA.tmp" to "/Shape_Search/public_html/img/content/973439_1644497526.jpg" in C:\xampp\htdocs\Shape_Search\src\ImageUtilities\crud.php on line 116
It was an issue of directory vs. path.
// The folder where the images will be stored
$uploadDir = CONTENT_PATH . '/';
Should be corrected to:
// The folder where the images will be stored
$uploadDir = CONTENT_DIR . '/';
Where the global variables CONTENT_PATH and CONTENT_DIR are:
defined('CONTENT_PATH')
or define('CONTENT_PATH', realpath($_SERVER['HTTP_HOST']) . '/Shape_Search/public_html/img/content');
defined('CONTENT_DIR')
or define('CONTENT_DIR', dirname(dirname(__FILE__)) . '/public_html/img/content');

Image source not readable with Laravel Image Intervention

So this has been a problem for me for a while now and it just doesn't seem to work, I have a form where users can submit a new profile picure:
<form enctype="multipart/form-data" action="/profile" method="POST">
<input type="file" name="avatar">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" class="pull-right btn btn-sm btn-primary">
</form>
When the button is clicked they are being redirected to the controller which activates the following function:
public function update_avatar(Request $request)
{
$avatar = $request->avatar;
$extension = File::extension($avatar);
$filename = time() . '.' . $extension;
Image::make($avatar)->resize(350, 350)->save( public_path('/uploads/avatars/' . $filename ) );
$user = Sentinel::getUser();
$user->profile->avatar = $filename;
$user->save();
}
But whatever I do the controller always returns the message
(1/1) NotReadableException
Image source not readable
Does anyone know how I can fix this?
EDIT: I've changed my Image::make line to the following:
$image = Image::make($avatar->getRealPath())->resize(350, 350)->save( public_path('/uploads/avatars/' . $filename ) );
But now I am encountering a new error:
(1/1) FatalErrorException
Call to a member function getRealPath() on string
Try this instead :
Image::make($avatar->getRealPath())->resize(350, 350)->save( public_path('/uploads/avatars/' . $filename ) );
Edit:
use this, to retrieve your UploadedFile
$avatar = $request->file('avatar');
Edit #2:
For the extension use this instead :
$extension = $avatar->getClientOriginalExtension();
Note: Do not forget to authorize only images files in your validation rules.
Intead, you can "hardcode" the extension, Intervention is able to save & convert into the specified image format (jpg, png ..)

hasFile function not working in laravel 5.4

i am trying to upload a photo using Image Intervention Package
i tried dd($request->hasFile('avator') ) and it return false
i returned "error" in my if statment just to make sure that i have an error
thanks in advance
public function update_photo(Request $request){
if($request->hasFile('avator') ){
$avator = $request->file('avator');
$filename = time() . '.' . $pic->getClientOriginalExtension();
Image::make($avator)->resize(300 , 300)->save(public_path('/uploads/avators' . $filename));
$user = Auth::user();
$user->avator = $filename ;
$user->save();
echo "hello world !";
}else {
echo " Error"; // just to make sure that i have an error
}
return view("profile" , array("user" => Auth::user() ));
}
first edit this line of code
$filename = time() . '.' . $avator->getClientOriginalExtension();
add to this slash also
Image::make($avator)->resize(300 , 300)->save(public_path('/uploads/avators/' . $filename));
*in your blade template make sure of spelling you are writing avator not avatar *
<input type="file" name="avator"/>
In your blade put this in your form tag:
enctype="multipart/form-data
and in your controller:
use File;

Uploading Multiple Files To Server From Form

I have a form from which I gather quite a bit of information and am then required to upload Multiple Files.
All other aspects of the form are now working perfectly thanks to Devi on this forum. And to try and focus on only the one problem I now have I have decided to start the new thread: The previous / old thread can be viewed Insert into one Table, while updating another & File Upload
My problem now is to actually get the files to upload. My form is working in two parts. Part one is the basic HTML layout which then has the method pointing to the PHP file which handles the writing of info to the database tables.
The form has the following code for each file upload (There are 4 uploads, each for a different file reference, ie. License Document, Renewal Document, Identity Document, Other Documents):
<div class="form-group">
<label>Permit Renewal :</label>
<div class="input-group">
<label>
<input type="radio" class="minimal" value="0" <?php echo ($permit_renewal=='No')?'checked':'' ?> name="permit_renewal">
No
</label>
<label>
<input type="radio" class="minimal" value="1" <?php echo ($permit_renewal=='Yes')?'checked':'' ?> name="permit_renewal">
Yes
</label>
</div>
</div>
<div class="box-body">
<div class="form-group">
<div class="form-group">
<label for="scanned_permit_renewal">Attach File</label>
<input type="file" id="scanned_permit_renewal" name="scanned_permit_renewal">
<p class="help-block">Select a file to link to this outlet, the file name must be prefixed with the Outlet. E.g. 102987 - License 2016</p>
</div>
</div><!-- /.form-group -->
And the relevant processing part is
if (isset($_FILES["file"]["name"])) {
foreach($_FILES['file']['tmp_name'] as $key => $tmp_name){
$file_name = $key.$_FILES['file']['name'][$key];
$file_size =$_FILES['file']['size'][$key];
$file_tmp =$_FILES['file']['tmp_name'][$key];
$file_type=$_FILES['file']['type'][$key];
$new_file = $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . date("Ymd_his") . "_" . $file_name;
//echo $new_file;
move_uploaded_file($file_tmp,$new_file);
}
}
if($res1){
echo "Records added / updated successfully.";
}
header("refresh:2;url=../outlet_capture.php");
// close connection
$link->close();
I have also confirmed my rot directory and ensured that there is an /uploads/ folder present.
If don't see the definition, but it MUST have the enctype like
The $_FILES variable works with the name of the field in the form.
On your example it should be scanned_permit_renewal. And for access it from the PHP when the form was sent you should use $_FILES['scanned_permit_renewal'].
You uses on the foreach
foreach($_FILES['file']['tmp_name'] as $key => $tmp_name)
Which seems to be the problem.
IMHO you should use this:
foreach($_FILES as $fieldNameInTheForm => $file)
{
$file_name = $fieldNameInTheForm .$file['name'];
$file_size =$file['size'];
$file_tmp =$file['tmp_name'];
$file_type=$file['type'];
$new_file = $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . date("Ymd_his") . "_" . $file_name;
//echo $new_file;
move_uploaded_file($file_tmp,$new_file);
}
You have done everything right, you are simply not pointing to the right input names...
$_FILES['file'] does not exist. You should use $_FILES['scanned_permit_renewal'] instead just like when you access $_POST, the key is the name of the form field.
Actually, you are looping through the $_FILES['file'] as if you had put many inputs with the name file[*something*]. If you question is complete, you should simply be using
if (isset($_FILES["scanned_permit_renewal"])) {
$file_name = $_FILES['scanned_permit_renewal']['name'];
$file_size =$_FILES['scanned_permit_renewal']['size'];
$file_tmp =$_FILES['scanned_permit_renewal']['tmp_name'];
$file_type=$_FILES['scanned_permit_renewal']['type'];
$new_file = $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . date("Ymd_his") . "_" . $file_name;
//echo $new_file;
move_uploaded_file($file_tmp,$new_file);
}
To answer your comment, an efficient way of doing it could be 2 ways. First, which will require no PHP changes, rename your input fields to file[scanned_permit_renewal] this will let you use the foreach as you seem to intend.
Another way could be to use an array of possible inputs:
$file_inputs = array('scanned_permit_renewal','my','other','documents');
foreach($file_inputs as $input_name){
if (isset($_FILES[$input_name])) {
$file_name = $input_name.$_FILES[$input_name]['name'];
$file_size =$_FILES[$input_name]['size'];
$file_tmp =$_FILES[$input_name]['tmp_name'];
$file_type=$_FILES[$input_name]['type'];
$new_file = $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . date("Ymd_his") . "_" . $file_name;
//echo $new_file;
move_uploaded_file($file_tmp,$new_file);
}
}
A third way could be to just loop through the $_FILES array. But I wouldn't do that, as there could be anything there. You'll prefer to filter on your wanted files.
For uploading multiple files, input field should be:
<input type="file" id="scanned_permit_renewal" name="scanned_permit_renewal[]" multiple="multiple">
processing part:
if (count($_FILES["scanned_permit_renewal"]["name"]) > 0) {
foreach($_FILES['scanned_permit_renewal']['tmp_name'] as $key => $tmp_name)
{
$file_name = $key.$_FILES['scanned_permit_renewal']['name'][$key];
$file_size =$_FILES['scanned_permit_renewal']['size'][$key];
$file_tmp =$_FILES['scanned_permit_renewal']['tmp_name'][$key];
$file_type=$_FILES['scanned_permit_renewal']['type'][$key];
$file_to_save = date("Ymd_his") . "_" . $file_name;
$new_file = $_SERVER['DOCUMENT_ROOT'] . "/uploads/" .$file_to_save;
//echo $new_file;
if(move_uploaded_file($file_tmp,$new_file)){
// update database
$query = "UPDATE `table` SET `field_name` = '".$file_to_save."' WHERE ..... ";
}
}
}

$_FILES returning nothing

So, I recently looked up how to upload files onto a database using Blob. This is the tutorial I found http://www.php-mysql-tutorial.com/wikis/mysql-tutorials/uploading-files-to-mysql-database.aspx
I followed this tutorial and came up with this code -
HTML FORM -
<form action='memberPage.php' method='post' enctype='multipart/form-data'>
<input type='text' name='programName' placeholder='Program Name'></input>
<input type='text' name='programPrice' placeholder='Price'></input>
<div id='uploadFiles'>
<input name='userfile1' type='file' onchange='addAnother()'>
</div>
<input type='submit' value='Create program' style='cursor:pointer;'></input>
</form>
PHP UPLOAD ($programName is specified outside code it looks something like $programName=$_POST["programName"];)
for($i = 1; $i < 999;$i++){
if(isset($_POST["userfile" . $i]) && $_FILES["userfile" . $i]['size'] > 0){
$Filename = $_FILES["userfile" . $i]['name'];
$finfo = new finfo();
$Filetype = $finfo->file($_FILES["userfile" . $i]['tmp_name'], FILEINFO_MIME);
$Filesize = $_FILES["userfile" . $i]['size'];
$Filetmpname = $_FILES["userfile" . $i]['tmp_name'];
$Fileerror = $_FILES["userfile" . $i]['error'];
$fp = fopen($Filetmpname, 'r');
$content = fread($fp, filesize($Filetmpname));
$content = addslashes($content);
fclose($fp);
if(!get_magic_quotes_gpc())
{
$Filename = addslashes($Filename);
}
mysqli_query($conn, "INSERT INTO upload(name,type,size,content,program) VALUES('
'" . $Filename. "','" . $Filetype. "','" . $Filesize . "','" . $content . "','" . $programName . "')");
}else{
$i=999;
header("location:memberPage.php");
}
}
But when I submit the forum, the files return with nothing in them, no name, and the size is zero.
I have also checked out the other question things on here and did not find the answer, so my guess is that it is in my code.
Let me also specify that the onchange='addAnother()' adds another input, but has the next end number on it (Example - userfile1, it would then add userfile2)
you are using input name "programName" and try to get "Programname" the same with $_POST.
PHP is case sensitive you should use same case in PHP "$_POST['programName']"
We need to check file element istead of post element.
Try changing this
if(isset($_POST["userfile" . $i]) && $_FILES["userfile" . $i]['size'] > 0){
to this
if(isset($_FILES["userfile" . $i]) && $_FILES["userfile" . $i]['size'] > 0){
It would be better to create the input names as arrays.
<input name='userfile[]' type='file' onchange='addAnother()'>
and iterate through it in php like:
if (isset($_FILES["userfile"]) && is_array($_FILES["userfile"])) {
for ($i=0;$i<count($_FILES["userfile"]);$i++) {
echo $_FILES["userfile"]["name"][$i];
}
}

Categories