I'm trying to upload 4 images, but I have a problem with their names. When I am saving images in my server, I save their names in an array, but it only returns the attribute of the first image and the rest is only the name (without attribute). Also, in the rest it only returns the letter of that index.
I'm really confused, why is that happening?
My file names are: pictts.jpeg / picture.jpeg / adadas.jpeg / b.jpeg
$img_counter = count($_FILES['upload_img']['name']);
$files = $_FILES;
for ($i = 0; $i < $img_counter; $i++) {
$this->load->library('upload');
$my_file_name = time() . $_FILES['upload_img']['name'][$i];
$my_new_file_name = str_replace(' ', '_', $my_file_name);
$my_new_file_names = str_replace('-', '_', $my_new_file_name);
$New_file_name = $my_new_file_names;
$_FILES['upload_img']['name'] = $files['upload_img']['name'][$i];
$_FILES['upload_img']['type'] = $files['upload_img']['type'][$i];
$_FILES['upload_img']['tmp_name'] = $files['upload_img']['tmp_name'][$i];
$_FILES['upload_img']['error'] = $files['upload_img']['error'][$i];
$_FILES['upload_img']['size'] = $files['upload_img']['size'][$i];
$this->upload->initialize($this->upload_options($New_file_name));
$upload_res [] = $this->upload->do_upload('upload_img');
$error[] = $this->upload->display_errors();
$upload_data[] = $New_file_name;
}
Wrong result:
Related
I have implemented dropzone js on my laravel project but af facing one issue on saving the images on the database
,/uploads/products/27/607f0fc0942b0_1618939840_fc3cde370d846c4d14b0200a29e9206f.png,/uploads/products/27/607f0fc0945e8_1618939840_copy-space-with-opened-quran_23-2148214357.jpg,/uploads/products/27/607f0fc09474d_1618939840_1 (1).jpg
the issue is the images start with a comma which is wrong and it must be after the image for example
image1.png,image2.png
Here is my Controller
$product_images = json_decode($request->product_images[0],true);
$images = [];
$path = "";
$productsPath = 'uploads/products/';
$productPath = 'uploads/products/'.$request->product_id;
if(!file_exists($productsPath)){
mkdir($productsPath);
}
if (!file_exists($productPath)) {
mkdir($productPath, 0777,true);
}
foreach($product_images as $img){
$file = $img['name'];
// $extension = $img->guessExtension();
$filename = uniqid() .'_'. time() .'_'. $file;
$img = explode(',',$img['file'])[1];
$img = str_replace('', '+', $img);
$data = base64_decode($img);
$file = $productPath .'/'. $filename;
$success = file_put_contents($file, $data);
// dd($file);
$images[] = '/'. $file;
}
// Update Product Information On "products" table
$product = Product::where('id', $request->product_id)->first();
$product->created_by = auth()->user()->id;
$product->name = request('name_en');
$product->name_ar = request('name_ar');
$product->description = request('description_en'); // Must be moved to "product_information"
$product->description_ar = request('description_ar'); // Must be moved to "product_information"
$product->youtube = request('youtube'); // Must be moved to "product_information"
$product->youtube_ar = request('youtube_ar'); // Must be moved to "product_information"
$product->slug = slugify($request->name_en, 'Product', '', '');
// $product->image = request('name_en');
$product->brand_id = request('brand');
$product->status = request('status');
$data = explode(',' ,$product->image);
$data = array_merge($data,$images);
$remove_images = json_decode($request->removed_images, true);
$temp = [];
$i = 0;
foreach($data as $key => $imag){
$i = $i + 1;
if(!empty($remove_images) && in_array($imag, $remove_images)){
if (file_exists($productPath .'/'. $imag)) {
unlink($productPath .'/'. $imag);
}
}else{
if($i < 8)
$temp[] = $imag;
}
}
$product->image = implode($temp, ',');
// dd (explode(',' ,$product->image));
$product->save();
thank you
use implode like this
implode(',', $temp);
I am trying to upload multiple images through a PHP API.
When uploading, the data sending returns success, but it only uploads the names of the images to the Database and the files are not saved on the server side.
I tried to specify separate paths to decode, and then I used the file_put_contents function, but nothing uploads correctly to the server.
if($_SERVER['REQUEST_METHOD']=='POST'){
$pic = $_POST['pic'];
$random = random_word(20);
$path = "grocery/item_img/".$random.".jpg";
$actualpath = "$random.jpg";
$actualpath1 = "$random1.jpg";
$actualpath2 = "$random2.jpg";
$sql = "INSERT INTO item (`pic`, `pic1`, `pic2`)
VALUES (NULL, '$actualpath', '$actualpath1', '$actualpath2')";
class emp{}
if(mysqli_query($koneksi,$sql)){
foreach ($_POST['pic'] as $name) {
file_put_contents($path, $name);
}
echo json_encode(array( 'success' => 1,'message'=>'Item Added Successfully'));
}
else{
echo json_encode(array( 'success' => 0,'message'=>'Failed to Add Item Image'));
}
}
function random_word($id = 20){
$pool = '1234567890abcdefghijkmnpqrstuvwxyz';
$word = '';
for ($i = 0; $i < $id; $i++){
$word .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
}
return $word;
SOLVED
foreach gives Invalid argument supplied
when edits it to
foreach ((array) $pic as $image) {
...
}
error gone but still no uploads
then tried
move_uploaded_file($_FILES["pic"]["tmp_name"], $path1);
give error of :
Undefined index: pic
then edits to :
if (isset($_FILES['foto'])) {
move_uploaded_file($_FILES["foto"]["tmp_name"], $path1); }
error gone but won't upload
tried to edit the file_put_contents
to the param of pic1
it uploaded the second pic ,,,
so below is the working code which uploads the three images while storing their paths to the DB
anyway to make it neat while working
if($_SERVER['REQUEST_METHOD']=='POST'){
$pic = $_POST['pic'];
$pic1 = $_POST['pic1'];
$pic2 = $_POST['pic2'];
$random = random_word(20);
$random1 = random_word(20);
$random2 = random_word(20);
$path = "../item_img/".$random.".jpg";
$actualpath = "$random.jpg";
$actualpath1 = "$random1.jpg";
$actualpath2 = "$random2.jpg";
//upload files
$path1 = '../item_img/'.$actualpath;
$path2 = '../item_img/'.$actualpath1;
$path3 = '../item_img/'.$actualpath2;
$sql = "INSERT INTO item (`pic`, `pic1`, `pic2`)
VALUES (NULL, '$actualpath', '$actualpath1', '$actualpath2')";
class emp{}
if(mysqli_query($koneksi,$sql)){
file_put_contents($path1,base64_decode($pic));
file_put_contents($path2,base64_decode($pic1));
file_put_contents($path3,base64_decode($pic2));
}
echo json_encode(array( 'success' => 1,'message'=>'Item Added Successfully'));
}
else{
echo json_encode(array( 'success' => 0,'message'=>'Failed to Add Item Image'));
}
}
function random_word($id = 20){
$pool = '1234567890abcdefghijkmnpqrstuvwxyz';
$word = '';
for ($i = 0; $i < $id; $i++){
$word .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
}
return $word;
I have this annoying problem:
Below you will see my messy upload script in which, whenever I upload a video file, I use a md5 function to name it so there are no video files with the same names in my database/folder.
The problem is that when I upload a given file multiple times to the database, it gets stored with the same md5 file name every time. I would really appreciate it if you could help me fix this little bug. I may be tired or something. I tried a hundred different solutions, and nothing fixed it.
Here is my mess:
<?php
class Upload_model extends CI_Model {
var $gallery_path;
var $videos_path;
var $thumbnail;
var $video_name;
var $upload_data;
var $file_name;
var $name;
var $videos_folder = "http://localhost/upload/videos/";
//////////////////////////////
function Upload_model() {
parent::__construct();
$this->videos_path = realpath(APPPATH . '..\videos');
// $this->returnFromDatabase();
}
function do_upload() {
$name = $_FILES['userfile']['name']; // get file name from form
$fileNameParts = explode(".", $name); // explode file name to two part
$fileExtension = end($fileNameParts); // give extension
$fileExtension = strtolower($fileExtension); // convert to lower case
$encripted_pic_name = md5($name) . "." . $fileExtension; // new file name
$config['file_name'] = $encripted_pic_name; //set file name
$config = array(
'allowed_types' => 'avi|mp4|flw|mov',
'upload_path' => $this->videos_path,
'file_name' => $encripted_pic_name
);
$this->load->library('upload', $config);
if ($this->upload->do_upload()) {
$this->upload_data = $this->upload->data(); //Returns array of containing all of the data related to the file you uploaded.
$this->file_name = $this->upload_data['file_name'];
$this->getThumbImage('C:\\xampp\\htdocs\\upload\\videos\\' . $encripted_pic_name);
$insert_data = array(
'name' => $encripted_pic_name,
'path' => 'C:\\xampp\\htdocs\\upload\\videos\\' . $encripted_pic_name,
'thumb_path' => 'C:\\xampp\\htdocs\\upload\\videos\\' . $encripted_pic_name . "_t.jpeg",
'uploaded_by' => 'admin'
);
$this->db->insert('videos', $insert_data); //load array to database
redirect('/welcome');
}
}
function getVideoInformation($videoPath) {
$movie = new ffmpeg_movie($videoPath, false);
$this->videoDuration = $movie->getDuration();
$this->frameCount = $movie->getFrameCount();
$this->frameRate = $movie->getFrameRate();
$this->videoTitle = $movie->getTitle();
$this->author = $movie->getAuthor();
$this->copyright = $movie->getCopyright();
$this->frameHeight = $movie->getFrameHeight();
$this->frameWidth = $movie->getFrameWidth();
$this->pixelFormat = $movie->getPixelFormat();
$this->bitRate = $movie->getVideoBitRate();
$this->videoCodec = $movie->getVideoCodec();
$this->audioCodec = $movie->getAudioCodec();
$this->hasAudio = $movie->hasAudio();
$this->audSampleRate = $movie->getAudioSampleRate();
$this->audBitRate = $movie->getAudioBitRate();
}
function getAudioInformation($videoPath) {
$movie = new ffmpeg_movie($videoPath, false);
$this->audioDuration = $movie->getDuration();
$this->frameCount = $movie->getFrameCount();
$this->frameRate = $movie->getFrameRate();
$this->audioTitle = $movie->getTitle();
$this->author = $movie->getAuthor();
$this->copyright = $movie->getCopyright();
$this->artist = $movie->getArtist();
$this->track = $movie->getTrackNumber();
$this->bitRate = $movie->getBitRate();
$this->audioChannels = $movie->getAudioChannels();
$this->audioCodec = $movie->getAudioCodec();
$this->audSampleRate = $movie->getAudioSampleRate();
$this->audBitRate = $movie->getAudioBitRate();
}
function getThumbImage($videoPath) {
$movie = new ffmpeg_movie($videoPath, false);
$this->videoDuration = $movie->getDuration();
$this->frameCount = $movie->getFrameCount();
$this->frameRate = $movie->getFrameRate();
$this->videoTitle = $movie->getTitle();
$this->author = $movie->getAuthor();
$this->copyright = $movie->getCopyright();
$this->frameHeight = $movie->getFrameHeight();
$this->frameWidth = $movie->getFrameWidth();
$capPos = ceil($this->frameCount / 4);
if ($this->frameWidth > 120) {
$cropWidth = ceil(($this->frameWidth - 120) / 2);
} else {
$cropWidth = 0;
}
if ($this->frameHeight > 90) {
$cropHeight = ceil(($this->frameHeight - 90) / 2);
} else {
$cropHeight = 0;
}
if ($cropWidth % 2 != 0) {
$cropWidth = $cropWidth - 1;
}
if ($cropHeight % 2 != 0) {
$cropHeight = $cropHeight - 1;
}
$frameObject = $movie->getFrame($capPos);
if ($frameObject) {
$imageName = $this->file_name . "_t.jpeg";
$tmbPath = "C:\\xampp\\htdocs\\upload\\videos\\" . $imageName;
$frameObject->resize(120, 90, 0, 0, 0, 0);
imagejpeg($frameObject->toGDImage(), $tmbPath);
} else {
$imageName = "";
}
return $imageName;
}
}
For what matters, CI's upload class has a property called encrypt_name. You can set it to true and have your filename encrypted by default without you doing something else. Take a look: http://ellislab.com/codeigniter/user-guide/libraries/file_uploading.html
Also, since you are using CI, please use the Upload Class, don't write your own when the one provided from CI is so easy to use.
md5 will always return the same value when used on the same string, so uploading the file with the same name will end up with the same hash, add a random string to the file name
$encripted_pic_name = md5(microtime() . $name) . '.' . $fileExtension
You also need to be aware that clashes can happen with md5() where two different strings will have the same output. I wouldn't worry about this too much though for your needs.
You'll need to attach some random characters to the name before you md5 it (though even then it'll still have the chance of a duplicate name).
E.g:
$encripted_pic_name = md5($name . $randomStringHere) . "." . $fileExtension; // new file name
md5 will always give the same output for the same input, so if you upload the same file twice, then yes, you have already used that hash.
If you just want random names, then you don't even need to use MD5 and could just dynamically create a random string everytime a file is uploaded (a, b, c, etc to z, then aa, ab, ac, etc).
If the file name is same then it will return the same md5 hash
For this you have to encrypt unique name or number
You can use
$encripted_pic_name = md5(strtotime()) . "." . $fileExtension; // new file name
or
$encripted_pic_name = md5(uniqid()) . "." . $fileExtension; // new file name
I am trying to create an option of uploading an avatar to my site. What I am trying to achieve is this :
first avatar : 1.jpg
second avatar : 2.jpg
third avatar : 3.png
and so on..
How can I create an upload counter in php? My current code is this :
if(!empty($_FILES['cover']['tmp_name']))
{
$uploadfolder = "avatar/";
$file1 = rands().'.'.end(explode('.',$_FILES['cover']['name']));
$cover = $uploadfolder.$file1;
move_uploaded_file($_FILES['cover']['tmp_name'],$cover);
}
else
{
$cover = ''
}
The function rands() does not do anything, so please use it to demonstrate how I can achieve my goal.
If you store your users in database and there is integer user ID, you better use this user ID for file naming rather than separate incrementing counter.
Also you can look at existing files to find maximum existing number like this:
function getNextFileName ()
{
$a = 0;
$b = 2147483647;
while ($a < $b)
{
$c = floor (($a + $b) / 2);
if (file_exists ("$c.jpg")) $a = $c + 1;
else $b = $c;
}
return "$a.jpg";
}
function saveAvatar ($avatar)
{
for ($i = 0; $i < 16; $i++)
{
$name = getNextFileName ();
$fd = fopen ($name, 'x');
if ($fd !== FALSE)
{
fwrite ($fd, $avatar);
fclose ($fd);
return $name;
}
}
return FALSE;
}
for ($i = 0; $i < 20; $i++)
saveAvatar ("BlahBlahBlah$i");
It seem you have problem in genetaing random numbers you can try this:
$prefix = substr(str_shuffle("0123456789"), 0,3);
$file1 = $prefix.'.'.end(explode('.',$_FILES['cover']['name']));
the above $prefix will be like : any random 3 digits
Hope will help it!
/*
* currentDir - path - eg. c:/xampp/htdocs/movies/uploads (no end slash)
* $dir - points current working directory.
* $filename - name of the file.
*/
public static function getFileName($dir, $filename) {
$filePath = $dir . "/uploads/" . $filename;
$fileInfo = pathinfo($filePath);
$i = 1;
while(file_exists($filePath)) {
$filePath = $dir . "/uploads/" . $fileInfo['filename'] . "_" . $i . "." . $fileInfo['extension'];
$i++;
}
return $filePath;
}
move_uploaded_file($_FILES['cover']['tmp_name'],$filePath);
if same filename existing in your uploads folder. it will auto generate the
avatar_1.jpg,
avatar_2.jpg,
avatar_3.jpg, ans so on ..
If (and this is a big IF) your server supports file locking, you can reasonably ensure you have a unique incrementing ID with:
function get_avatar_id()
{
$lockfile = fopen("avatar_id_lock_file","a");
if(flock($lockfile, LOCK_EX)) // Get an exclusive lock to avoid race conditions
{
$avatar_id = intval(file_get_contents("avatar_id"); // Assumes you made it and put a number in it
$avatar_id++;
file_put_contents("avatar_id", $avatar_id);
flock($lockfile, LOCK_UN);
fclose($lockfile);
return $avatar_id;
}
else
{
//What do you want to do if you can't lock the file?
}
}
create an XML file and store the count in there
<? xml version="1.0" ?>
<MyRootNode>
<count>123</count>
</MyRootNode>
UPDATE
Update added after you added more code to your question.
Function Rands(FileExtension as string) as long
'1 open xml file
'2 read counter in
'3 increment counter
'4 save value to back xml file
'5 return incremented counter with the file extension passed attached on the end
'This is in case a BMP GIF or PNG has been and not JPG
' SAMPLE filename 123.GIF
End Function
I have a folder that contains files named standard_xx.jpg (xx being a number)
I would like to find the highest number so that I can get the filename ready to rename the next file being uploaded.
Eg. if the highest number is standard_12.jpg
$newfilename = standard_13.jpg
I have created a method to do it by just exploding the file name but it isn't very elegant
$files = glob($uploaddir.'test-xrays-del/standard_*.JPG');
$maxfile = $files[count($files)-1];
$explode = explode('_',$maxfile);
$filename = $explode[1];
$explode2 = explode('.',$filename);
$number = $explode2[0];
$newnumber = $number + 1;
$standard = 'test-xrays-del/standard_'.$newnumber.'.JPG';
echo $newfile;
Is there a more efficient or elegant way of doing this?
I'd do it like this myself:
<?php
$files = glob($uploaddir.'test-xrays-del/standard_*.JPG');
natsort($files);
preg_match('!standard_(\d+)!', end($files), $matches);
$newfile = 'standard_' . ($matches[1] + 1) . '.JPG';
echo $newfile;
You can make use of sscanfDocs:
$success = sscanf($maxfile, 'standard_%d.JPG', $number);
It will allow you to not only pick out the number (and only the number) but also whether or not this worked ($success).
Additionally you could also take a look into natsortDocs to actually sort the array you get back for the highest natural number.
A complete code-example making use of these:
$mask = 'standard_%s.JPG';
$prefix = 'test-xrays-del';
$glob = sprintf("%s%s/%s", $uploaddir, $prefix, sprintf($mask, '*'));
$files = glob($glob);
if (!$files) {
throw new RuntimeException('No files found or error with ' . $glob);
}
natsort($files);
$maxfile = end($files);
$success = sscanf($maxfile, sprintf($mask, '%d'), $number);
if (!$success) {
throw new RuntimeException('Unable to obtain number from: ', $maxfile);
}
$newnumber = $number + 1;
$newfile = sprintf("%s/%s", $prefix, sprintf($mask, $newnumber));
Try with:
$files = glob($uploaddir.'test-xrays-del/standard_*.JPG');
natsort($files);
$highest = array_pop($files);
Then get it's number with regex and increase value.
Something like this:
function getMaxFileID($path) {
$files = new DirectoryIterator($path);
$filtered = new RegexIterator($files, '/^.+\.jpg$/i');
$maxFileID = 0;
foreach ($filtered as $fileInfo) {
$thisFileID = (int)preg_replace('/.*?_/',$fileInfo->getFilename());
if($thisFileID > $maxFileID) { $maxFileID = $thisFileID;}
}
return $maxFileID;
}