I´ve just moved my CI application to a real server, there, the user finds three optional file uploads, two for regular documents and images, and the third exclusively for a csv file, weird thing is that the first 2 uploads work Ok without warnings, the files upload with no problem, but the 3rd file, the csv file, keeps sending me a warning and avoids any file to be uploaded and the directory where it is supposed to upload is not created either, the code for the 1st file is this:
if (isset($_POST['save'])){
$this->load->library('upload');
$field = "file1";
$nombreCarpeta = preg_replace('/\s+/', '.', $this->session->userdata("username"));
$path = $this->config->item('server_root')."/codeigniter/uploads/".$nombreCarpeta."/";
if(!file_exists($path)){
mkdir($path, 0766);
}
$config["upload_path"] = $path;
$config["overwrite"] = "TRUE";
$config["remove_spaces"] = "TRUE";
$config["allowed_types"] = "txt|pdf|gif|jpg|png|tiff|doc|docx|rtf|jpeg";
$config["max_size"] = "1024*2048";
$config["max_width"] = "1024";
$config["max_height"] = "768";
$config["xss_clean"] = "FALSE";
$this->upload->initialize($config);
$this->upload->do_upload($field);
if($_FILES["file1"]['error'] == 0){
if ($this->upload->do_upload($field)){
$data = $this->upload->data();
array_push($arreglo, $data['file_name']);
}else{
$errors = $this->upload->display_errors();
}
}
.... same code, this time for file2
$field = "file3";
$pathDos = $this->config->item('server_root')."/codeigniter/listas/".$nombreCarpeta."/";
if(!file_exists($pathDos)){
mkdir($pathDos, 0777);
}
$config["upload_path"] = $pathDos;
$config["overwrite"] = "TRUE";
$config["remove_spaces"] = "TRUE";
$config["allowed_types"] = "csv";
$config["max_size"] = "1024*512";
$config["xss_clean"] = "FALSE";
$this->upload->initialize($config);
$this->upload->do_upload($field);
if($_FILES["file3"]['error'] == 0){
if ($this->upload->do_upload($field)){
$data = $this->upload->data();
array_push($arregloDos, $data['file_name']);
}else{
$errors = $this->upload->display_errors();
}
}
}
As you can see, the procedure is the same, except for some upload config, the files need to be uploaded in two previously created folders with 777 permissions, uploads and listas, inside of them, individual folders will be dynamically created and named as the user´s name, in order to distinguish between users files, as I said, no problem with the docs and images directory (uploads), the ls -l looks like this:
drwxrwxrwx. 2 root root 4096 Jan 14 05:59 listas
drwxrwxrwx. 3 root root 4096 Jan 13 11:18 uploads
ls -l inside uploads looks like this:
drwxr-xr-x. 2 apache apache 4096 Jan 13 13:29 administrator
the user administrator uploaded a couple of images, so, a folder named administrator was successfully created inside uploads before uploading his files, but no success when trying to upload a csv file, even when the folder listas has 777 permissions, no folder inside listas was created and no file uploaded, because a "mkdir(): Permission denied" warning!, as you can see the directories have proper permissions, I made a test creating the folder administrator inside of listas and giving it 777 permissions and chown-ing/chgrp-ing it to apache, and no results... any idea? am working on CentOS... thanx i.a.
It may be happening because of csv uploading problem which is a codeigniter bug.
Fix
Open application/config/mimes.php & update line 13 (probably)
'csv' => array('application/vnd.ms-excel', 'text/anytext', 'text/plain', 'text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),
Related
Using VPS server when I create directory using mkdir() it returns true but folder when I check using cpanel is blank, I dont know why I even used scandir() and I noticed that those folders which I created is showing in an array in scandir(), why is that happening, why those folders are not showing ?
This is my code:
/creating directory/
if (!file_exists('public_html/members/1213121')) {
mkdir('public_html/members/1213121', 0777, true);
echo "file getting created";
}
else{
echo "file not getting created.";
}
/**this is the code I put to scan the members folder and it retuns array and showing the folder named 1213121 but in actual cpanel that directory is not there **/
$dir = "public_html/members/";
// Sort in ascending order - this is default
$a = scandir($dir);
// Sort in descending order
$b = scandir($dir,1);
print_r($b);
since I did the testing with other folder names also so it returns in html as below::
file getting created
Array ( [0] => 1213121 [1] => 12131 [2] => 1213 [3] => .. [4] => . )
Also I did the testing with permissions as 0755, 0700 but none is working.
if your server folder permission is ok then this code is work for you.
this first script for deleting the '1213121' folder from your server.
script 1:
delete_files('/public_html/members/1213121/');
/*
* php delete function that deals with directories recursively
*/
function delete_files($target) {
if(is_dir($target)){
$files = glob( $target . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file ){
delete_files( $file );
}
rmdir( $target );
} elseif(is_file($target)) {
unlink( $target );
}
}
?>
replace your script with this script 2:
$dir = 'public_html/members/1213121';
if (!file_exists($dir) && !is_dir($dir)) { //check dir is not exist
if (mkdir($dir, 0777, true)) { //check folder is created
echo "Folder created"; //display success message
} else {
echo "folder not created."; //if the dir is not created then show error message
}
}
/**this is the code I put to scan the members folder and it retuns array and showing the folder named 1213121 but in actual cpanel that directory is not there **/
$dir = "public_html/members/";
// Sort in ascending order - this is default
$a = scandir($dir);
// Sort in descending order
$b = scandir($dir, 1);
print_r($b);
Note: before replacing 2nd script you must remove e first script.
The problem is solved actually the file which is creating the folder is in the subdomain and when I put the exact path , it was not pointing to it instead it created new public_html folder in subdomain and I was in main public_html.. it created a path like:-public_html/subdomainfolder/public_html/members/1213121 and instead i was thinking that path will be created as public_html/members/1213121 ... So my problem is solved now and Mahfuz answer is also right. thanks for the help.
I want to upload image in my codeigniter 3 , and I want to show the uploaded image to my users (this is in register level and users is inputing his profile data)
I should showe the uploaded image to him.
I have read this :
Moving it outside of the public_html is a good idea, also try to
rename the file and just add the extension to it.
and another :
Do not move uploaded file to directory which is accessible from URL
but I don't know how can I have show the picture which is not directory which is accessible from URL ! .
I don't have any idea it's really important for me the security I have used codeigniter upload class and I don't you know what kind of security other operations should I do
this is my controller :
public function do_resize($img_name ,$image_original_width , $image_original_height )
{
// $nesbat = $image_original_height / $image_original_width ;
$config_manip = array(
'image_library' => 'gd2',
'source_image' => '../uploads/'.$img_name,
'new_image' => '../uploads/'.$img_name,
'maintain_ratio' => TRUE,
'create_thumb' => TRUE,
'thumb_marker' => '_thumb',
'width' => 150,
'height' => 150
);
$this->load->library('image_lib', $config_manip);
if (!$this->image_lib->resize()) {
// echo $this->image_lib->display_errors();
return false ;
}
else
{
return true ;
}
// clear //
$this->image_lib->clear();
}
function do_upload()
{
$file_name = $this->input->post("file_name") ;
$config['upload_path'] = '../uploads/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = '10000';
$config['max_width'] = '1024';
$config['max_height'] = '768';
$config['file_name'] = $file_name;
// delete if .gif image exists before
if ( is_file('./uploads/'.$file_name.".gif") )
{
unlink("./uploads/".$file_name.".gif");
unlink("./uploads/".$file_name."_thumb.gif");
}
// delete if .gif image exists before
if ( is_file('./uploads/'.$file_name.".jpg") )
{
unlink("./uploads/".$file_name.".jpg");
unlink("./uploads/".$file_name."_thumb.jpg");
}
// delete if .gif image exists before
if ( is_file('./uploads/'.$file_name.".png") )
{
unlink("./uploads/".$file_name.".png");
unlink("./uploads/".$file_name."_thumb.png");
}
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload())
{
$error = array('error' => $this->upload->display_errors());
echo "<div id='upload_status'>fail</div>";
echo "<div id='error_mesage'>".$this->upload->display_errors()."</div>";
}
else
{
$data = array('upload_data' => $this->upload->data());
$upload_data = $this->upload->data();
$uploaded_file_name = $upload_data['file_name'];
$resize = $this->do_resize($uploaded_file_name , $upload_data['image_width'] , $upload_data['image_height'] ) ;
if ($resize == true )
{
echo "<div id='upload_status'>success</div>";
echo "<div id='uploaded_image_link' >".$upload_data['file_name']."</div> ";
$thumb_link = str_replace($file_name,$file_name."_thumb",$upload_data['file_name']);
echo "<div id='uploaded_image_thumb_link' >".$thumb_link."</div> ";
}
//if $resize == true , nabashe -> uploade koli fail eleam mishe ta dobare anjam beshe
else
{
echo "<div id='upload_status'>fail</div>";
}
}
}
Images are generally a public asset but you can protect them in a few ways.
Put an index.html or index.php file in your images directory.
Turn off directory listing in your .htaccess file
Rewrite the file name (will obfuscate orginal name)
To view the image after it's uploaded will require AJAX, or a page refresh. A page refresh is easier to code, simply upload the file and show that file on the preceeding page.
You can protect the folder to make sure a particular page has access to displaying an image. This makes things more complicated but working with some kind of resource access system might help you achieve this.
Once the page is loaded though - the image will be available to that user and once downloaded there.
I am not sure on what youre protecting exactly (profile pics, adult content..) but images, like CSS files are public assets.
Rich
Using this way, we can prevent Image call from other server.
Prevent image hotlinking (IMP)
- Image hotlinking is the process/technique of using someone else’s Image URL in our Website and using their bandwidth. In order to prevent this mystery, we can prevent access for external server by adding following line in htaccess.
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
Just create a blank index.html file and put the index.html file on all other public folders except application/system folders (they already have it).
This is a simple security technique to restrict viewers to view your files on public folders.
There is no solution, as i have searched a lot on moving my uploaded image into directory here is my php code :
<?php
//Profile Image upload script
if (isset($_FILES['profilepic'])) {
if (((#$_FILES["profilepic"]["type"]=="image/jpeg") || (#$_FILES["profilepic"]["type"]=="image/png") || (#$_FILES["profilepic"]["type"]=="image/gif"))&&(#$_FILES["profilepic"]["size"] < 1048576)) //1 Megabyte
{
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$rand_dir_name = substr(str_shuffle($chars), 0, 15);
$dir = "userdata/profile_pics/$rand_dir_name";
mkdir($dir);
move_uploaded_file($_FILES["profilepic"]["tmp_name"],"userdata/profile_pics/$rand_dir_name".$_FILES["profilepic"]["name"]);
$profile_pic_name = $_FILES["profilepic"]["tmp_name"];
echo $profile_pic_name;
$profile_pic_query = mysqli_query($conn,"UPDATE users2 SET profile_pic='$rand_dir_name/$profile_pic_name' WHERE username='$user'");
}
else
{
$msg5 = "Invailid File! Your image must be no larger than 1MB and it must be either a .jpg, .jpeg, .png or .gif";
}
}
?>
but when I try to upload image,it creates the random folder in userdata/profile_pics but it doesn't move the file into random folder directory i have also created a custom php.ini file with file_uploads = On, but i recieve the following warning when i submit the form :-
Warning: move_uploaded_file(): The second argument to copy() function cannot be a directory in /home/rahulkapoor90/public_html/note.php on line 26
Warning: move_uploaded_file(): Unable to move '/tmp/phpO592dd' to 'userdata/profile_pics/zAGC9wOhVyoe3R5' in /home/rahulkapoor90/public_html/note.php on line 26
/tmp/phpO592dd
For anyone else who comes across this error, in my case it was a permissions issue. I re-factored some legacy code and checked the wrong directory for permissions and instead kept getting this misleading error message.
Wasted few hours to get the correct cause. You can try 2 things
Verify your destination folder
`$destdir="YOUR-COMPLETE-DESTINATION-FOLDER/uploads/";
if(is_dir($destdir) && is_writable($destdir))
{echo "<strong>UPLOAD DIRECTORY EXIST & WRITABLE</strong>";}
else
{echo "<strong>ISSUE WITH UPLOAD DIRECTORY</strong>";}`
Confirm 2nd parameter of move_uploaded_file is a file name NOT A DIRECTORY NAME
In my case this turned to be the issue
if(move_uploaded_file($tempname,"$destdir/".$_FILES['profilepic']['name']"))
{echo 'FILE UPLOADED SUCCESSFULLY';}
else
{echo "FAILED TO UPLOAD";}
I save the path to my images in my database. To delete these images, I get the path from the database.
This worked fine, until I added two folders to the path.
So far the path in my database looked like this (working!):
/var/www/myproject/public/images/550d744bd91d16.7869
Now, it looks like this (not working!): /var/www/myproject/public/images/5/profile/550d744bd91d16.7869
My Code
$folder_name = /var/www/myproject/public/images/ . $_GET['user_id'] . '/';
$profile_folder = $folder_name . 'profile/';
chmod($folder_name, 0777);
chmod($profile_folder, 0777);
// Get the images file path
$database = DatabaseFactory::getFactory()->getConnection();
$query = $database->prepare("SELECT image_path FROM images WHERE image_id = :image_id AND user_id = :user_id LIMIT 1");
$query->execute(array(':image_id' => $image_id, ':user_id' => Session::get('user_id')));
$img_path = $query->fetch();
// Convert array to string
$path = $img_path->image_path;
$file = $path . '.jpg';
if (file_exists($file)) {
// Delete the image file on the server
unlink($file);
} else {
echo 'An error occured';
return false;
}
What I tried so far
The path is definitely correct. I triple checked in the database and outputted the variable multiple times.
Therefore, I thought it must be the directory permissions, however, I added the permissions to the code and nothing changed.
I am not getting any error message and I would be beyond thankful for any kind of help with this!
Summary
file_exists(unlink($file)) returns FALSE.
unlink($file) returns TRUE.
The file permissions:
images drwxrwxrwx
5 drwxrwxrwx
profile drwxrwxrwx
image.jpg -rwxrwxrwx
I use ziparchive to zip my files in linux, and can't open in windows
default zip uploader, I suspect it is caused by the file path during addfile
e.g.
$zip-addFile(‘/home/userName/public_html/gallery/license.txt’, ‘gallery/license.txt’);
Suggestion from links below mention that I coudl remove the local path(as this can't be understood by windows), which becomes becomes
$zip-addFile(‘/home/userName/public_html/gallery/license.txt’, ‘license.txt’);
http://www.jacobbates.com/blog/2012/04/24/corrupt-zip-files-in-windows-from-phps-ziparchive/
PHP ZipArchive Corrupt in Windows
But I need to maintain the directory structure, how should I address this problem?
maybe first add the target directory with addEmptyDir see the code below this create different files:
<?php
error_reporting(E_ALL);
ini_set('display_errors','on');
$zip = new ZipArchive;
if ($zip->open('tmp/test.zip',ZipArchive::CREATE) === TRUE) {
$zip->addFile('data.php', 'data/data.php');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
$zip = new ZipArchive;
if ($zip->open('tmp/testdata.zip',ZipArchive::CREATE) === TRUE) {
if($zip->addEmptyDir('data')) {
echo 'Created a new root directory';
} else {
echo 'Could not create the directory';
}
$zip->addFile('data.php', 'data/data.php');
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
The files got different file sizes:
-rw-r--r-- 1 www-data www-data 633 Apr 29 12:10 testdata.zip
-rw-r--r-- 1 www-data www-data 545 Apr 29 12:10 test.zip
unzip test.zip no empty dir added:
unzip test.zip
Archive: test.zip
inflating: data/data.php
unzip testdata.zip with an empty dir added:
Archive: testdata.zip
creating: data/
inflating: data/data.php
does creating: data/ first
Had the same problem with a structure similar to yours on a Drupal context. I solved this by setting the Content-disposition filename with my uri
file_transfer($archive_uri, array(
'Content-Disposition' => 'attachment; filename="' . $archive_uri . '"',
'Content-Length' => filesize($archive_uri))
);