laravel multiple upload getClientOriginalName on array - php

hello im trying to upload multiple file on laravel. im following my others single upload file laravel. but when im trying to submit, it says an error
Call to a member function getClientOriginalName() on array
i know the problem, but i dont know how to solved it.
here's my blade view
<div class="row pb-3">
<div class="col-sm-4"><label>Akta Lain Lain </label></div>
<div class="col-sm-8">
<div class="custom-file" style="width: 500px; height: 40px; cursor: pointer;">
<input type="file" class="custom-file-input" name="ALL[]" multiple>
<label class="custom-file-label">Choose file</label>
</div>
</div>
</div>
and here's my controller
$deb = new Debitur_Badan_Usaha();
if ($request->hasFile('ALL')) {
$files = [];
foreach ($request->file('ALL') as $items) {
if ($items->isValid()) {
$name_all = time().'_'.rand(1,9999).'_'.$request->ALL->getClientOriginalName();
$items->move('data_debitur/', $name_all);
$files [] = $name_all;
}
}
$deb->AKTE_LAIN_LAIN = $files;
$deb->save();
}
i think the problem bcs on the name blade file is ALL[] but the getclientoriginalname doesnt accept an array? does anyone know how to solved it so it can be uploading multiple image? thank u
updated controller
$deb = new Debitur_Badan_Usaha();
if ($request->hasFile('ALL')) {
$files = [];
foreach ($request->ALL as $file) {
if ($file->isValid()) {
$name_all = time().'_'.rand(1,9999).'_'.$file->getClientOriginalName();
$file->move('data_debitur/', $name_all);
array_push($files, $name_all);
}
}
$deb->AKTE_LAIN_LAIN = $files;
$deb->save();
}

You were close, you already have a foreach loop to deal with the array of files, all you need to do is to now utilize it and use it, here is how:
Note: I changed items -> file, then for getting the original name, you can call that directly on the file.
if ($request->hasFile('ALL')) {
//foreach file request
foreach($request->ALL as $file) {
if ($file->isValid()) {
//here we will call the file originalname
$name_all = time().'_'.rand(1,9999).'_'.$file->getClientOriginalName();
//moving the file
$file->move('data_debitur/', $name_all);
//we add the file to the field and save it
$deb->AKTE_LAIN_LAIN = $name_all;
$deb->save();
}
}
}
Extra: you can also get the extension like $file->getClientOriginalExtension();

Try this one:
$deb = new Debitur_Badan_Usaha();
$files = [];
foreach ($request->file('ALL') as $item) {
if ($item->isValid()) {
$name = time().'_'.rand(1,9999).'_'.$item->getClientOriginalName();
$item->move('data_debitur/', $name);
$files [] = $name;
}
}
$deb->AKTE_LAIN_LAIN = $files;
$deb->save();

Related

Laravel: Upload form data with images in a foreach loop using Intervention

I'm using Laravel 5.1 and would like to have a form with a few rows of text fields with their corresponding image uploads.
Form:
<div id="row">
<input name="description[]" type="text">
<input name="image[]" type="file">
</div>
<div id="row">
<input name="description[]" type="text">
<input name="image[]" type="file">
</div>
Controller:
foreach($request->description as $key => $val){
if($val != null){
$data = new Finding;
$data->description = $val; //save description for each loop
$file = array('image' => Input::file('image'));
if (Input::file('image')->isValid()) {
$destinationPath = 'uploads';
$extension = Input::file('image')->getClientOriginalExtension();
$fileName = rand(1000,1000).'.'.$extension;
Input::file('image')->move($destinationPath, $fileName);
$path = Input::file('image')->getRealPath();
$data->image_location = $fileName[$key]; //save filename location to db
$data->save();
flash('success', 'Uploaded Successful');
return Redirect::to('/upload');
} else {
flash('error', 'Uploaded File Is Not Valid');
return Redirect::to('/upload');
}
}
My question is, how do I use intervention with the $key value to save a new row in the table with the associated text description with the image upload and still use all the intervention classes? Is my code close?
I can easily do all this with just one form input with one image upload but my goal is to have a page with multiple rows with inputs. Thanks!
I'm unsure of how you're managing the multiple fields, whether it's set in stone or can dynamically change. I have previously done dynamic approaches with javascript and kept track of how many dynamic fields I required with a hidden text field as a count.
Using this approach your html might look something like this:
<input name="imageAndDescriptionCount" type="hidden" value="2">
<div id="row">
<input name="description[]" type="text">
<input name="image[]" type="file">
</div>
<div id="row">
<input name="description[]" type="text">
<input name="image[]" type="file">
</div>
So here we have two image and description fields each and the counter is set at 2.
If we were to submit the form and checkout the request via dd() it would look something like this:
"imageAndDescriptionCount" => "2"
"description" => array:2 [▼
0 => "description"
1 => "description"
]
"image" => array:2 [▼
0 => UploadedFile {#154 ▶}
1 => UploadedFile {#155 ▶}
]
This then sets you up nicely for a for loop in your controller:
$count = $request->get('imageAndDescriptionCount');
$description = $request->get('description'); // assign array of descriptions
$image = $request->file('image'); // assign array of images
// set upload path using https://laravel.com/docs/5.1/helpers#method-storage-path
// make sure 'storage/uploads' exists first
$destinationPath = storage_path . '/uploads';
for($i = 0; $i < $count; $i++) {
$data = new Finding;
$data->description = [$i];
$file = $image[$i];
if ($file->isValid()) {
$extension = $file->getClientOriginalExtension(); // file extension
$fileName = uniqid(). '.' .$extension; // file name with extension
$file->move($destinationPath, $fileName); // move file to our uploads path
$data->image_location = $fileName;
// or you could say $destinationPath . '/' . $fileName
$data->save();
} else {
// handle error here
}
}
flash('success', 'Uploads Successful');
return Redirect::to('/upload');
Please note there is no use of the intervention library in your code to my knowledge and I've just wrote the code to perform the upload. I hope this helps you!
Edit
If you really want to use a foreach loop and you know you'll have a description for each image you can do it like this (but I personally think having a counter is a better approach)
$descriptions = $request->get('description'); // assign array of descriptions
$images = $request->file('image'); // assign array of images
// loop through the descriptions array
foreach($descriptions as $key => $val) {
// You can access the description like this
$val
// or this
$descriptions[$key]
// so naturally you can access the image like this:
$images[$key]
}
You could also instead check the count of the descriptions/images and use that as a counter to loop through:
$descriptions = $request->get('description');
$images = $request->file('image'); // assign array of images
$descCount = count($descriptions);
$imgCount = count($images);
If however you may have a different layout, i.e. you don't have 1 description for 1 image then please clarify as you'd need to take a different approach.

PHP Multiple file upload and store the names in Database

I am PHP beginner and building my own practice project (I have thought it something like used car sale online site)
My problem is very similar to multiple file upload sql/php and Multiple file upload in php
Here are list of my problems
I want to upload image in a directory and store it's name in database. So far below code is working fine (if I upload 1 file). I am trying to add 3 more file input option so that user can upload upto 4 images.
So far trying different codes available in stackoverflow and other online sites, I have been able to atleast upload the multiple files in my directory. But the real problem is that I don't know how I would store the name of the file in database .
(In most of the tutorials and suggestions, I found I should use 1 input file type with multiple attributes or name equals array like file[] and run foreach loop. But I couldn't figure out how would go ahead and get the file name of each input and store it in database.
Below are my code for the reference.
//this is my form.addVehicle.php file to process the form
<?php
define("UPLOAD_DIR", "../uploads/");
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$name = "default.jpg";
if (is_uploaded_file($_FILES["myFile"]['tmp_name'])) {
$myFile = $_FILES["myFile"];
if ($myFile["error"] !== UPLOAD_ERR_OK) {
echo "<p>An error occurred.</p>";
exit;
}
// ensure a safe filename
$name = preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]);
// don't overwrite an existing file
$i = 0;
$parts = pathinfo($name);
while (file_exists(UPLOAD_DIR . $name)) {
$i++;
$name = $parts["filename"] . "-" . $i . "." . $parts["extension"];
}
// preserve file from temporary directory
$success = move_uploaded_file($myFile["tmp_name"],
UPLOAD_DIR . $name);
if (!$success) {
echo "<p>Unable to save file.</p>";
exit;
}
// set proper permissions on the new file
chmod(UPLOAD_DIR . $name, 0644);
}
include_once ('../class/class.Vehicle.php');
$vehicle = new Vehicle(
$_POST['make_id'],
$_POST['yearMade'],
$_POST['mileage'],
$_POST['transmission'],
$_POST['price'],
$_POST['zone_name'],
$name,
$_POST['description']
);
}
?>
//To give a try, tested is_uploaded_file condition four different times with //different file name id like myFile1,myFile2...and path variable as $name1, //$name2...and it works as I want it to be...but I'm sure that' not the correct //way to do it..
//This is my class file with name class.Vehicle.php
include_once('class.pdoDbConnnection.php');
class Vehicle{
private $make_id;
private $yearMade;
private $mileage;
private $transmission;
private $price;
private $zone_name;
private $image_path;
private $description;
public function __construct($make_id, $yearMade, $mileage, $transmission, $price, $zone_name, $image_path, $description){
$this->make_id = $make_id;
$this->yearMade = $yearMade;
$this->mileage = $mileage;
$this->transmission= $transmission;
$this->price = $price;
$this->zone_name = $zone_name;
$this->image_path = $image_path;
$this->description = $description;
try{
$sql = "INSERT INTO cars (car_id, make_id, yearmade, mileage, transmission, price, zone_name,image_path, description) VALUES (?,?,?,?,?,?,?,?,?)";
$pdo = new DBConnection();
$stmt = $pdo->prepare($sql);
$stmt->execute(array(NULL,$this->make_id,$this->yearMade,$this->mileage,$this->transmission,$this->price,$this->zone_name,$this->image_path,$this->description));
}
catch (PDOException $e)
{
echo $e->getMessage();
}
}
}
Here are my mySql table columns (I want to insert file names in the column..while displaying it in the client side, I'm using it this way: <img alt="image" class="img-responsive" src="../uploads/<?php echo $row['image_path'] ?>">
car_id , make_id , zone_id, yearmade, mileage, transmission, price, image_path, image_path1, image_path2, image_path3, description
This is my client side form to add new cars....
..................
<form class="form-horizontal" role="form" method="post" action="../includes/form.addVehicle.php" enctype="multipart/form-data">
.....................
<div class="form-group">
<label for="description" class="col-sm-2 control-label">Upload Image</label>
<div class="col-sm-4">
<input type="file" class="form-control" id="myFile" name="myFile">
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">Upload Image</label>
<div class="col-sm-4">
<input type="file" class="form-control" id="myFile1" name="myFile2">
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">Upload Image</label>
<div class="col-sm-4">
<input type="file" class="form-control" id="myFile3" name="myFile3">
</div>
</div>
..............
Finally I ended up with the following code.
P.S. Thanks to #Andy-Brahman insight at Multiple file upload in php
<?php
if(isset($_POST['submit'])){
$uploads_dir = '../test_uploads';
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
$name = $_FILES["pictures"]["name"][$key];
// I don't want to overwrite the existing file
$i = 0;
$parts = pathinfo($name);
while (file_exists($uploads_dir . "/" . $name)) {
$i++;
$name = $parts["filename"] . "-" . $i . "." . $parts["extension"];
}
move_uploaded_file($tmp_name, "$uploads_dir/$name");
}
}
// Test to see if I get the uploaded file name which i want to insert into database table column.
echo "<pre>";
print_r($_FILES['pictures']['name'][0]);
echo"</br></br>";
print_r($_FILES['pictures']['name'][1]);
echo"</br></br>";
print_r($_FILES['pictures']['name'][2]);
echo"</br></br>";
print_r($_FILES['pictures']['name'][3]);
echo"</br></br>";
echo "</pre>";
// test succeeds . Now I guess I can do something like $picture0 = $_FILES['pictures']['name'][0]);
// and insert $picture0,$picture1...into database..
// Am I doing everything correctly?
}
I will make example, you just adapt it for yourself.
<form action="file_reciever.php" enctype="multipart/form-data" method="post">
<input type="file" name="files[]" multiple/>
<input type="submit" name="submission" value="Upload"/>
</form>
the PHP goes (file_reciever.php):
<?php
if (isset($_POST['submission'] && $_POST['submission'] != null) {
for ($i = 0; $i < count($_FILES['files']['name']); $i++) {
//Get the temp file path
$tmpFilePath = $_FILES['files']['tmp_name'][$i];
//Make sure we have a filepath
if ($tmpFilePath != "") {
//Setup our new file path
$newFilePath = "./uploadFiles/" . $_FILES['files']['name'][$i];
//Upload the file into the temp dir
if (move_uploaded_file($tmpFilePath, $newFilePath)) {
//Handle other code here
}
}
}
}
?>

Manipulate several files in PHP

I'm trying to import data from multiple .csv in a web app thanks to a single input, but I'm struggling manipulating $_FILES.
All I want to do is separating files into two arrays according to their names. I'm not able to upload these files on the server.
This is the input in the form page used to upload files :
<input type="file" name="file[]" id="inputrapports" accept=".csv" multiple="true"/>
In my action page, i'm doing this :
$files=$_FILES['file'];
$q=array();
$c=array();
foreach($files as $file){
if(strtoupper(substr(str_replace(' ','',$file['name']),7,1))=="Q"){
$q[]=$file;
}else{
$c[]=$file;
}
}
Unfortunately, it doesn't work. So I tried this :
foreach($files['name'] as $f){
echo $f; //I'm getting the name
}
foreach($files as $f){
echo $f['name']; //I'm not
}
I could use the first attempt shown above, but in this case I won't be able to put the entire array of the file in the appropriate array.
Can you explain me why this two attempts give different answers ?
Could you help me find a solution ?
Thanks in advance.
The dirty way to solve this is:
$files = $_FILES['file'];
for($i=0;$i<count($files['tmp_name']); $i++)
{
echo $files['name'][$i];
}
Another approach is from the php documentation:
function diverse_array($vector) {
$result = array();
foreach($vector as $key1 => $value1)
foreach($value1 as $key2 => $value2)
$result[$key2][$key1] = $value2;
return $result;
}
$files = diverse_array($_FILES["file"]);
And then proceed with your first foreach.
$q=array();
$c=array();
foreach($files as $file){
if(strtoupper(substr(str_replace(' ','',$file['name']),7,1))=="Q"){
$q[]=$file;
}else{
$c[]=$file;
}
}

How to upload multiple files with Zend framework?

Even if I select 2 or more images, only one gets uploaded.
I have a simple form:
<form action="/images/thumbs" method="post" enctype="multipart/form-data">
<input name="file[]" id="file" type="file" multiple="" />
<input type="submit" name="upload_images" value="Upload Images">
</form>
Then in my controller:
public function thumbsAction()
{
$request = $this->getRequest();
if ($request->isPost()) {
if (isset($_POST['upload_images'])) {
$names = $_FILES['file']['name'];
// the names will be an array of names
foreach($names as $name){
$path = APPLICATION_PATH.'/../public/img/'.$name;
echo $path; // will return all the paths of all the images that i selected
$uploaded = Application_Model_Functions::upload($path);
echo $uploaded; // will return true as many times as i select pictures, though only one file gets uploaded
}
}
}
}
and the upload method:
public static function upload($path)
{
$upload = new Zend_File_Transfer_Adapter_Http();
$upload->addFilter('Rename', array(
'target' => $path,
'overwrite' => true
));
try {
$upload->receive();
return true;
} catch (Zend_File_Transfer_Exception $e) {
echo $e->message();
}
}
Any ideas why I get only one file uploaded?
Zend_File_Transfer_Adapter_Http actually has the information about the file upload. You just have to iterate using that resource:
$upload = new Zend_File_Transfer_Adapter_Http();
$files = $upload->getFileInfo();
foreach($files as $file => $fileInfo) {
if ($upload->isUploaded($file)) {
if ($upload->isValid($file)) {
if ($upload->receive($file)) {
$info = $upload->getFileInfo($file);
$tmp = $info[$file]['tmp_name'];
// here $tmp is the location of the uploaded file on the server
// var_dump($info); to see all the fields you can use
}
}
}
}

Retrieve filename extension for multiple uploaded files (Class Upload, PHP)

Language: PHP / Using Class Upload by Colin Verot
About: Multiple Uploading
The code below already uploads the files fine, it works...
PROBLEM: I am having trouble figuring out how to get the filename extension.
(In a comment below, I have specified where my problem area is...)
// CONNECTION TO DATABASE HERE...
// INCLUDE UPLOAD CLASS LIBRARY
include (dirname(__FILE__).'/lib/class.upload.php');
$files = array();
foreach ($_FILES['fileupload'] as $k => $l)
{
foreach ($l as $i => $v)
{
if (!array_key_exists($i, $files))
$files[$i] = array();
$files[$i][$k] = $v;
$imagename = $_FILES['fileupload']['name'];
}
}
foreach ($files as $file) {
// THIS IS MY PROBLEM AREA, GETTING FILE EXTENSION
$ext=strchr($imagename,".");
$generate_name = rand(100,99999);
$generate_name_extra = rand(200,9999);
$filenamex = "PHOTO_".$generate_name.$generate_name_extra."_".time();
$filenamex_thumb = $filenamex."_thumb";
// COMPLETE FILENAME WITH EXTENSION
$filename = $filenamex.strtolower($ext);
$handle = new upload($file);
if ($handle->uploaded) {
///// 1 ////////////////////////////////////////////////////////////////////
$handle->file_new_name_body = $filenamex_thumb;
$handle->image_resize = true;
$handle->image_x = '300';
$handle->image_ratio_y = true;
$handle->jpeg_quality = '100';
// ABSOLUTE PATH BELOW
$handle->process($absoRoot.'covers/thumbs/');
if ($handle->processed) {
// SUCCESSFUL RESPONSE
}
else
{
// FAILED RESPONSE
}
}
}
And the webform is:
<form method="post" action="upload.php" enctype="multipart/form-data">
<input name="fileupload[]" id="fileupload" type="file" multiple>
I really pretty much need the file extensions to serve the files correctly online, but I can't spot where to find it. I have tried using: $files[$i][$k] instead of $imagename in my specified problem area above, as well as $file and other possible solutions, but I can't spot which one's going to give me the filename with extension.
Hopefully someone could point it out. Thank you for your time and assistance!
$ext=array_pop(explode('.', $imagename));
The function you're looking for is pathinfo().
$pathdata = pathinfo($filename);
$extension = $pathdata['extension'];

Categories