I am building a image upload in Laravel but I keep getting an error inside my foreach loop if one filed is empty.
My upload allows multible images[], so if one field is empty I get an error but I want to allow users to choose if they want to upload eg 2 or 5 images
$input = Input::all();
//Validation
File::exists($path) or File::makeDirectory($path);
foreach($input['images'] as $file) {
$image = Image::make($file->getRealPath()); //getRealPath gives me an error if not all images[] fields from post data containts an image
}
So how can I sort my input images[] from empty inputs?
Thanks in advance,
If I understood well you need something like this:
if(empty($file)) {
unset($file);
}
or something like this:
if(!empty($file)){
$image = Image::make($file->getRealPath());
}
Try checking whether $file has a non-null value before running getRealPath
File::exists($path) or File::makeDirectory($path);
foreach($input['images'] as $file) {
if($file) {
$image = Image::make($file->getRealPath());
}
}
By the way, $image is reset with every iteration. Is that really what you want? Do you care which $image you get?
You can use array_filter() with no callback to remove all elements that have a falsy value:
$input = array_filter($input);
foreach($input['images'] as $file) {
$image = Image::make($file->getRealPath());
}
What I did to solve it was to add if check within my foreach loop and it worked. But im not sure if this is the best solution?
$input = Input::all();
foreach($input['images'] as $file) {
if($file == ""){ //If one input is empty it jumps over it, instead of trying to use getRealPath() on an empty value
break;
}
$image = Image::make($file->getRealPath());
}
Related
Trying to upload file to my test api. For testing I tried to check if input has file and it returns true. The problem is when the code tries to move that file. Search google show almost the same code that I have;
if (Input::hasFile('attachments')) {
$path = base_path().'/assets';
$files = Input::file('attachments');
$data = [];
foreach ($files as $file) {
$data[] = $file->getClientOriginalExtension();
$uuid = Uuid::uuid1();
$extension = $file->getClientOriginalExtension();
$filename = $uuid.'.'.$extension;
$file->move($path, $filename);
}
return Response::json($data);
} else {
return 'no file';
}
Doing a post request using Paw multipart give this result on json
Still can't figure this out. Any help will be much appreciated. Thank you so much guys in advance.
Ok; so something as simple as this [] gave me a hard time figuring things out. All I did is add []; instead of just attachments I did attachments[] as post request name and in my controller I retain the Input::file('attachments')
Thank you guys for your guidance and help. Figured things out the hard and tired way.
I don't know why you are trying to iterate but there is no reason to and $files is a single uploaded file.
Just remove the loop since there is nothing to iterate.
if (Input::hasFile('attachments')) {
$path = base_path().'/assets';
$file = Input::file('attachments');
$uuid = Uuid::uuid1();
$extension = $file->getClientOriginalExtension();
$filename = $uuid.'.'.$extension;
$file->move($path, $filename);
return Response::json($extension);
} else {
return 'no file';
}
If you wanted to have multiple files you would need to have the input setup to be named as an array, attachments[]. You are sending attachments which is always a single value. If you sent an array then there would potentially be something for you to iterate through.
I adopted code from https://stackoverflow.com/a/44553006/8719001
but can't figure out why when uploading the same file "test.jpg" several times it only counts up once, creating "test-1.jpg" but not more ie. test-2.jpg, test-3.jpg.
Can anybody spot the issue and help please?
$keepFilesSeperator = "-";
$keepFilesNumberStart = 1;
if (isset($_FILES['upload'])) {
// Be careful about all the data that it's sent!!!
// Check that the user is authenticated, that the file isn't too big,
// that it matches the kind of allowed resources...
$name = $_FILES['upload']['name'];
//If overwriteFiles is true, files will be overwritten automatically.
if(!$overwriteFiles)
{
$ext = ".".pathinfo($name, PATHINFO_EXTENSION);
// Check if file exists, if it does loop through numbers until it doesn't.
// reassign name at the end, if it does exist.
if(file_exists($basePath.$name))
{
$operator = $keepFilesNumberStart;
//loop until file does not exist, every loop changes the operator to a different value.
while(file_exists($basePath.$name.$keepFilesSeperator.$operator))
{
$operator++;
}
$name = rtrim($name, $ext).$keepFilesSeperator.$operator.$ext;
}
}
move_uploaded_file($_FILES["upload"]["tmp_name"], $basePath . $name);
}
your while loop condition has a problem
while( file_exists( $basePath.$name.$keepFilesSeperator.$operator ) )
the $name variable still contains the full name of file, in this case test.jpg, you're testing a value like /home/test.jpg-1 so finally the while loop is never executed as the file test.jpg-1 never exists, that's why you always get the test-1.jpg on disk and not a ...-2.jpg or ...-3.jpg
I have a form which has 5 file inputs to create an array of images.
When processing, I wish to loop through the images and process them.
$images = Input::get('images');
// image proccessing
foreach ($images as $image) {
print_r($image);
}
That will output the file name, but If I call the move function on the $image variable I get "method move called on string".
How should I be doing this?
You should be doing something like this
$input = Input::file('files'); //get file as input
//check if input has file
if ($input){
foreach($input as $key){
//loop through file and perform action...
$array = Image::file_upload($key, 'file', 'Images');
// I assume you have your method for upload like the above
$key = $array['filename'];
print_r($key);
}
}
$this->image->save($input); //save to db file name.
So I've killed an entire day trying to do something that would take someone who actually knows how to write php less than 2mins. Frustrating, but I learn by doing and trying to figure things out.
I'll feel like a failure for not getting this, but 8hrs and counting (yeah I know lame) is enough.
Can somebody tell me what's wrong with this equation...
$dir = '../folder';
$images_array = glob($dir.'*.jpg');
$values['options'] = array( '<img src="$images_array"/>');
It's probably obvious, but all I need is for the images in mysite.com/folder to be loaded into the $values['options'] array.
If I simply state the path to a single image in then the image is displayed (obviously because it's not reliant on anything else.)
Thanks.
#hellcode
Sorry about the mess in the 'comment' below your response. Unfortunately I couldn't get this to work? Maybe I need to provide more context.
The images in the folder are going to be used as checkbox items in a form. This was my original code (not working):
add_filter('frm_setup_new_fields_vars', 'frm_set_checked', 20, 2);
function frm_set_checked($values, $field){
if($field->id == 187){
$dir = '../folder';
$images_array = glob($dir.'*.jpg');
$values['options'] = array( '<img src="$images_array"/>');
$values['use_key'] = true;
}
return $values;
}
I added your code like so:
add_filter('frm_setup_new_fields_vars', 'frm_set_checked', 20, 2);
function frm_set_checked($values, $field){
if($field->id == 187){
$dir = '../folder';
$images_array = glob($dir.'*.jpg');
$values['options'] = array();
foreach($images_array as $image) {
$values['options'][] = '<img src="'.$image.'"/>';
}
$values['use_key'] = true;
}
return $values;
}
But it didn't pull the files in unfortunately :(
Try:
$dir = '../folder';
$images_array = glob($dir.'*.jpg');
$values['options'] = array();
foreach($images_array as $image) {
$values['options'][] = '<img src="'.$image.'"/>';
}
Well, one problem may be that the glob() function uses the current directory, which can be anything, unless you use the chdir() function.
One thing that is definitely a problem is that you are using glob()'s return value, $images_array, as a string. Because it is an array that will not work.
Here is something that should work.
// Allowed image formats (also known as a "whitelist")
$allowedFormats = ['jpg', 'jpeg', 'gif', 'png'];
// Array for holding any found images
$foundImages = [];
// Get the real path from the relative path
$path = realpath('../folder');
if ($path === false) {
die('The path does not exist!');
}
// Open a folder handle
$folder = dir($path);
// Read what is in the folder
while (($item = $folder->read()) !== false) {
// .. is the parent folder, . is the current folder
if ($item === '..' or $item === '.') {
continue;
}
// Find the last dot in the filename
// If it was not found then not image file
$lastDot = strrpos($item, '.');
if ($lastDot === false) {
continue;
}
// Get the filetype and make sure it is
// an allowed format
$filetype = substr($item, $lastDot);
if ( ! in_array($filetype, $allowedFormats)) {
continue;
}
// Okay, looks like an image!
$foundImages[] = $item;
}
// Close the folder handle
$folder->close();
I have a folder of a lot of images for in iPad app. Trying to create an automated php script to check to see if all the images that are in the folder have a paired non-retina and retina image set. If the retina image is not present, display a message saying something like: "Missing: $filename" where $filename is the value... I am coming up short on how to do a compare of the array of images grabbed via glob():
First i get the images from the folder that are jpg or png:
$images = glob("ipad/{*.jpg,*.png}", GLOB_BRACE);
Now i want to check this array of images to show the missing #2x image sets... I was reading that you could use array_filter but don't quite get how to do this...
Any ideas how to achieve this and then echo them out with a foreach "Missing: $filename"
You can use the following:
$path = __DIR__;
$all = glob("$path/*.{jpg,png}", GLOB_BRACE);
$normal = $retina = array();
// Group Images
foreach($all as $v) {
strpos($v, '#2x') === false and $normal[basename($v)] = $v;
strpos($v, '#2x') !== false and $retina[basename($v)] = $v;
}
foreach($normal as $image) {
$v = pathinfo($image);
$name = $v['filename'] . '#2x.' . $v['extension'];
if (! isset($retina[$name])) {
echo "Missing: $name\n";
}
}
Something like this should do:
var_dump(array_filter(glob('ipad/{*.jpg,*.png}', GLOB_BRACE), function ($file) {
$info = pathinfo($file);
return !preg_match('/#2x$/', $info['filename'])
&& !file_exists("$info[dirname]/$info[filename]#2x.$info[extension]");
}));