php rename is copying instead of moving - php

I have the following code:
rename ('/original_dir/file','/new_dir/file');
When the code is run, I get the following message:
Warning: rename(/original_dir/file,/new_dir/file): Operation not permitted
The file is however copied to /newdir, but is not removed from /original_dir
I am using rename to have it moved, not copied.
Both /original_dir and /new_dir have permissions set to 0777
This should work. Any ideas?

Rename is actually moving file with another name. As you can see from error, that operation is not permitted because, even though you have permission to write to file, you cannot delete the file if you are not owner of it on many Linux distributions. That's why your web server process is copying file, and not able to delete the old one.

Have you tried a copy() and a unlink()?
It may give you a better look at what goes wrong.
if( copy('/original_dir/file', '/new_dir/file') ) {
unlink('/original_dir/file');
}
source
Edits: if the script is being called from the command line, does it work with sudo? If it is being called from a webpage, does it work if you change the owner of the file to apache? Did you get the exact error code and check it in man 2 rename per this comment?

Related

Issue with calling php script with cron

I have set up a cron to call a php script to run some download tasks at a regular interval.
The website is hosted at Bluehost. I have followed the instructions on how to set up a cron and that basically works fine, but the behaviour is different from when calling the script manually which i suspect has to do with directory settings. When using the cron i get errors:
Warning: copy(wp-content/uploads/feeds/full/1.csv): failed to open stream: No such file or directory in /home1/user1/public_html/import/custom-downloader.php on line 86
my php code is copy( $row["externalURL"] , 'wp-content/uploads/feeds/full/'. $localfilename );
I have also tried below with same result.
copy( $row["externalURL"] , $_SERVER['DOCUMENT_ROOT'].'wp-content/uploads/feeds/full/'. $localfilename );
I think think that i need to construct the path to /home1/user1/public_html/import/wp-content/uploads/feeds/full/ but i don't see how to do that.
First thing's first, make sure that 1.csv exists and that it can be read (there's read permissions on the file)
Second thing, double check if 'wp-content/uploads/feeds/full/1.csv' really is what you want to copy. Your error message indicates that the php script calling the copy method is /home1/user1/public_html/import/custom-downloader.php. However, the path you specified is relative. So your PHP script (barring any changes to the PATH to look for other directories) will look for /home1/user1/public_html/import/wp-content/uploads/feeds/full/1.csv -- which may not be what you intended!
This can be solved by using an absolute path to your wp-content folder, or by moving this script to the parent directory of wp-content.

PHP file_exists returns false but the file does exist

I have seen several similar questions, but no answer worked in my situation, except that it probably has something to do with permissions.
A PHP script served by Apache tells me unable to open database file.
When I print the path to that file, it returns a valid path, say DBPATH. The file does exist at that location; I gave it and its parent folder 777 rights; I gave them user:user access, where user is the sudoer that all script files belong to. I did the same to the whole htdocs/ folder, just in case.
When I print file_exists(DBPATH), it returns false. Is is most likely a matter of permissions, but I don't know what I should change for PHP to have access rights. I tried apache:apache, too. I cannot su apache (user not available).
My scripts are in htdocs/. DBFILE is somewhere out of it (I tried /tmp/test, all in 777, but no luck either).
No safe_mode, PHP 5.4 freshly installed, CentOS7.
Please someone give me a clue at least to help debug it.
Maybe such as: how can I check whether my file will be readable from apache/my php script, without running the script itself? How can I get the name of the user that is used to execute it?
Solved, more or less.
To debug I had the idea to move DBFILE to the same folder where the PHP script lives, and check it can find it - it did. Then I move DBFILE one folder after another in the tree to see where it stopped finding it.
It occurs that if only one of the folders in the whole path does not have execute rights for all users (xx5), the file cannot be found and file_exists returns false.
So the solution was to create another folder in a totally executable place (/var/www/data/ worked after chmod 755 data), and move the file there.
Do you use an absolute path or relative path?
Because file_exists() doesn't work with HTTP addresses (which is an absolute path). But you can enter the relative path.
I had the same problem and it fixed it. It was the same problem with unlink().
Exemple:
$file_relative_path = "./wp-content/uploads/fileDirectory/fileName.jpg";
if (file_exists($file_relative_path)) {
unlink($file_relative_path);
}
I had a similar problem and was able to solve it by the answer of JulienD:
If the execute flag of a directory in the file system (Linux) is not set, then PHP (still) scans this directory with glob or scandir. However, a subsequent check with file_exists() on this list of results, I wanted to find broken symbolic links, returned false!
So the solution was to set the Execute right for the directory, as mentioned by JulienD.

cannot includ a existing file - failed to open stream: Permission denied

this is not a duplicate question, I read all related questions, and didn't find my answer.
I want to include a file that exists :
/var/www/html/monitor/protected/extensions/curl/curl.php
and my code is :
include('/monitor/protected/extensions/curl/curl.php');
and I'm getting this error :
include(/var/www/html/monitor/protected/extensions/curl/curl.php): failed to open stream: Permission denied
and the file has 777 permission.
My question is :
is it possible that a file exists and have a 777 permission and a proper chown AND still give this error?
Update : I had used all three possible ways :
include('/monitor/protected/extensions/curl/curl.php');
include('monitor/protected/extensions/curl/curl.php');
include('/var/www/html/monitor/protected/extensions/curl/curl.php');
Im using php 5.3
Note: when including another file in the same directory, it includes without any problem
I know this is late, but I just want to confirm Alireza Fallah's answer. This also worked for me. It looks like it has to be the original owner. So unzip/unrar the php files on the same machine you want to use it on. Hope this helps!
You're using the wrong path. If the file exists at
/var/www/html/monitor/protected/extensions/curl/curl.php
Then you should include that exact string.
include('/var/www/html/monitor/protected/extensions/curl/curl.php');
/ means the root of the file system. You get permission denied because you most certainly don't have permission to / and /monitor doesn't exist
Alternatively you can include it relatively. By dropping the first / you would do:
include('monitor/protected/extensions/curl/curl.php');
This will work if the running script is also in /var/www/html.
I think you're getting confused at the difference between the HTTP path and the system path. PHP files are included from the system path and should be referenced by the system path.
I deleted the file, and created again, and my problem solved.
the original file was downloaded from the internet and unzipped from a zipped file.
I think there was a problem with creating the file by original author.
This is very odd! but it worked

PHP deleting a file from a subdirectory?

I have a PHP script that deletes files. It can delete files from my root directory, but when I try to delete from a subdirectory, it says "Permission denied". I know the file exists and PHP can access it because I can read and write to the file, but I can't delete it.
Why?
EDIT: If this is relevant, I am using Zymic hosting. But I have another site on Zymic where the deleting works fine. I don't get it...
EDIT: I use ajax to access the PHP file with the code to delete, and the ajax sends the file name to delete. I know the file name it sends is correct, because the warning message prints it for me. The PHP code is simply:
$file=$_POST['file'];
echo unlink($file);
EDIT: I fixed it! I don't know why this worked, but I FTP-chmodded the directory from 755 to 775 Can anyone tell me why it worked?
To delete the file you need write permissions to the folder that contains it, check that first.
CHMOD xxx -> Owner Group Other
first case:
755 - Owner (read, write, execute), Group (read, execute), Other (read, execute)
second case:
775 - Owner (read, write, execute), Group (read, write, execute), Other (read, execute)
Try to add this at the beginning of the script you're running:
error_reporting(E_ALL | E_STRICT);
That should be able to point out accurately what is going on, chances are that you do not have permissions to write to the folder
Especially if you're working on a Linux environment. In Linux everything is a file, even folders. When it comes to deleting files, you need to be able to write to the file that represents a folder, that's why having permissions to write to the file you're trying to get rid of, does not have anything to do with deleting it.
You have to fclose($myfile) first before using unlink($myfile),,because if it is open on the server by anyone it will not delete it. Also place this script in the same directory as the files you wish to delete,, otherwise you may accidently delete the whole DIR.

Why would file_put_contents() succeed but touch() fail?

I'm running a script that makes some changes to the contents of a file then resets its modification time to what it was before. Intermittently, I'll find the following errors in my log:
touch() [function.touch]: Utime
failed: Operation not permitted
This on the line immediately after a file_put_contents() call appears to have changed the contents of the file I tried to touch(). There are no errors associated with the file_put_contents() line.
Has anyone had this happen? Can anyone figure out what set of permissions would allow me to write a file but not change its modification time? I'm doing this on Linux.
This is a bug with PHP's touch command. Even if you have write permission to the file, it fails if PHP isn't also the "owner".
If you're using Apache and Linux, use this command on your server's console to make PHP the file's owner:
sudo chown www-data:www-data /YourPATH/YourFILE
Better still, update the entire folder containing files you want PHP to control:
sudo chown -R www-data:www-data /YourPATH/YourFOLDER
Side Note: Because PHP can write to the file, that means it must have user or group write permission. Since that's the case, touch should not behave this way. It seems like a bug.
It could be possible that the file gets created with wrong permissions. Try to chmod 777 the file just after the file_put_contents and then touch the file.
As rossoft says, PHP is probably not the owner of the file. But setting the permissions to 777 might not be the best solution. I'd preferr:
function touch_file($file) {
fclose(fopen($file, 'a'));
}
touch_file('/path/to/file');
Only recently, I've had a similar problem and I think I know the answer.
The actual purpose of touch() is to update the modification and access times of a file. Creating the file is just a side-effect.
If you're using Linux, but writing to an NTFS partition as you might with a dual-boot configuration, depending on how the partition is mounted, touch() might have problems changing the access time on files. The file will be created, but touch() will still fail because the underlying system returns an error status. The same thing can be observed from the command line where you'll get a "permission denied" message.
There doesn't seem to be any documentation regarding this in the man pages for mount, ntfs-3g, or touch (Linux command), but the problem is mentioned in the comments on the touch() PHP function page.
Tweaking mount options might provide a solution, but you're better off using is_writable() to check permissions and fopen() to create files.

Categories